36 #include <type_traits>
44 #include "transforms.h"
50 #define __EXPR1__(type, var, expr) [](type var) { return expr; }
51 #define __EXPR2__(type, var1, var2, expr) \
52 [](type var1, type var2) { return expr; }
53 #define __GET_MACRO__(_1, _2, _3, NAME, ...) NAME
68 __GET_MACRO__(__VA_ARGS__, __EXPR2__, __EXPR1__)(auto, __VA_ARGS__)
82 #define CR_EXPR(...) \
83 __GET_MACRO__(__VA_ARGS__, __EXPR2__, __EXPR1__)(const auto &, __VA_ARGS__)
104 template <
typename WhenTrueQueried,
typename T>
114 template <
typename TrueT,
typename FalseT>
124 template <
typename T>
161 template <
typename T>
169 explicit Queryable(std::vector<T> items);
201 operator const std::vector<T> &&()
const {
return std::move(items_); }
216 return std::equal(lhs.items_.begin(), lhs.items_.end(), rhs.begin());
227 return std::equal(lhs.items_.begin(), lhs.items_.end(), rhs.items_.begin());
244 template <
typename U,
typename AccumulateFn>
245 U
accumulate(U initial, AccumulateFn accumulate_func)
const;
253 template <
typename ActionFn>
263 template <
typename Predicate>
264 bool all(Predicate predicate)
const;
273 template <
typename Predicate>
274 bool any(Predicate predicate)
const;
282 template <
typename Predicate>
316 template <
typename Predicate>
334 template <
typename KeySelector>
358 template <
typename U,
typename LhsKeySelector,
typename RhsKeySelector>
360 std::vector<U> rhs_items, LhsKeySelector lhs_key_selector,
361 RhsKeySelector rhs_key_selector);
371 template <
typename KeySelector>
388 template <
typename ValueSelector>
389 T
max(ValueSelector value_selector);
405 template <
typename ValueSelector>
406 T
min(ValueSelector value_selector);
417 template <
typename ValueSelector>
434 template <
typename Selector>
435 auto select(Selector selector);
518 template <
typename KeySelector>
529 template <
typename KeySelector >
561 template <
typename Predicate>
575 template <
typename U>
577 zip(std::vector<U> rhs_items,
bool truncate =
false);
590 template <
typename U>
592 zip(std::initializer_list<U> rhs_items,
bool truncate);
598 std::vector<T> items_;
612 template <
typename T>
613 Queryable<T> query(std::vector<T> items) {
614 return Queryable<T>(std::move(items));
617 template <
typename T>
620 template <
typename T>
621 bool operator==(
const Queryable<T> &lhs,
const std::vector<T> &rhs) {
622 return std::equal(lhs.items_.begin(), lhs.items_.end(), rhs.begin());
625 template <
typename T>
627 return std::equal(lhs.items_.begin(), lhs.items_.end(), rhs.items_.begin());
630 template <
typename T>
631 template <
typename U,
typename AccumulateFn>
636 return std::accumulate(
637 std::make_move_iterator(items_.begin()),
638 std::make_move_iterator(items_.end()), initial, accumulate_func);
641 template <
typename T>
642 template <
typename ActionFn>
645 std::for_each(items_.begin(), items_.end(), [&action_func](
auto item) {
651 template <
typename T>
652 template <
typename Predicate>
654 return std::all_of(items_.begin(), items_.end(), predicate);
657 template <
typename T>
658 template <
typename Predicate>
660 return std::any_of(items_.begin(), items_.end(), predicate);
663 template <
typename T>
667 "T must be equality comparable.");
669 std::vector<T> difference;
671 std::make_move_iterator(items_.begin()),
672 std::make_move_iterator(items_.end()),
673 std::make_move_iterator(rhs_items.begin()),
674 std::make_move_iterator(rhs_items.end()), std::back_inserter(difference));
678 template <
typename T>
682 "T must be equality comparable.");
684 std::set<T> distinguished(
685 std::make_move_iterator(items_.begin()),
686 std::make_move_iterator(items_.end()));
687 return Queryable<T>(transforms::to_vector(std::move(distinguished)));
690 template <
typename T>
692 return items_.
empty();
695 template <
typename T>
696 template <
typename Predicate>
699 auto end = std::make_move_iterator(items_.end());
701 std::find_if(std::make_move_iterator(items_.begin()), end, predicate);
702 return it != end ? std::make_optional(*it) : std::nullopt;
705 template <
typename T>
708 using U = T::value_type;
709 std::vector<U> flattened;
710 for (T &item : items_) {
711 for (U &sub_item : item) {
712 flattened.push_back(std::move(sub_item));
715 return Queryable<U>(std::move(flattened));
718 template <
typename T>
719 template <
typename KeySelector>
720 Queryable<std::vector<T>> Queryable<T>::group_by(KeySelector key_selector) {
721 using K = decltype(key_selector(*items_.begin()));
723 traits::is_less_than_comparable<K>::value,
724 "Key selector must produce a value that is less-than comparable.");
726 std::map<K, std::vector<T>> keyed_groups;
728 std::make_move_iterator(items_.begin()),
729 std::make_move_iterator(items_.end()), [&](
auto item) {
730 keyed_groups[key_selector(item)].push_back(std::move(item));
733 std::vector<std::vector<T>> groups;
734 groups.resize(keyed_groups.size());
736 std::make_move_iterator(keyed_groups.begin()),
737 std::make_move_iterator(keyed_groups.end()), groups.begin(),
738 [
this](std::pair<K, std::vector<T>> pair) {
739 return std::move(pair.second);
745 template <
typename T>
749 std::vector<T> intersection;
750 std::set_intersection(
751 std::make_move_iterator(items_.begin()),
752 std::make_move_iterator(items_.end()), rhs_items.begin(), rhs_items.end(),
753 std::back_inserter(intersection));
757 template <
typename T>
758 template <
typename U,
typename LhsKeySelector,
typename RhsKeySelector>
760 std::vector<U> rhs_items, LhsKeySelector lhs_key_selector,
761 RhsKeySelector rhs_key_selector) {
762 using KU = decltype(rhs_key_selector(*rhs_items.begin()));
763 using KT = decltype(rhs_key_selector(*items_.begin()));
765 std::is_same<KU, KT>::value,
766 "Left and right hand key selectors must produce the same type.");
771 "Key selectors must produce a type that is less-than compareable.");
773 std::map<K, std::vector<U>> rhs_mapped;
775 std::make_move_iterator(rhs_items.begin()),
776 std::make_move_iterator(rhs_items.end()), [&,
this](U rhs_item) {
777 rhs_mapped[rhs_key_selector(rhs_item)].push_back(std::move(rhs_item));
780 std::vector<std::tuple<T, U>> joined;
782 std::make_move_iterator(items_.begin()),
783 std::make_move_iterator(items_.end()), [&,
this](
auto lhs_item) {
784 auto lhs_key = lhs_key_selector(lhs_item);
785 auto rhs_it = rhs_mapped.find(lhs_key);
786 if (rhs_it != rhs_mapped.end()) {
787 for (U &rhs_item : rhs_it->second) {
788 joined.push_back({std::move(lhs_item), std::move(rhs_item)});
796 template <
typename T>
797 template <
typename KeySelector>
798 auto Queryable<T>::keyed_group_by(KeySelector key_selector) {
799 using K = decltype(key_selector(*items_.begin()));
801 std::map<K, std::vector<T>> mapped;
802 for (
int i = 0; i < items_.size(); i++) {
804 mapped[key_selector(items_[i])].push_back(std::move(items_[i]));
807 {std::make_move_iterator(mapped.begin()),
808 std::make_move_iterator(mapped.end())});
811 template <
typename T>
812 T Queryable<T>::max() {
814 traits::is_less_than_comparable<T>::value,
815 "T must be less-than compareable.");
816 asserts::invariant::eval(!items_.empty()) <<
"Sequence cannot be empty.";
819 return *std::max_element(
820 std::make_move_iterator(items_.begin()),
821 std::make_move_iterator(items_.end()));
824 template <
typename T>
825 template <
typename ValueSelector>
829 *items_.begin()))>::value,
830 "ValueSelector return type must be less-than compareable.");
831 asserts::invariant::eval(!items_.empty()) <<
"Sequence cannot be empty.";
834 return *std::max_element(
835 std::make_move_iterator(items_.begin()),
836 std::make_move_iterator(items_.end()),
837 [&value_selector](
const auto &lhs,
const auto &rhs) {
838 return value_selector(lhs) < value_selector(rhs);
842 template <
typename T>
846 "T must be less-than compareable.");
847 asserts::invariant::eval(!items_.empty()) <<
"Sequence cannot be empty.";
850 return *std::min_element(
851 std::make_move_iterator(items_.begin()),
852 std::make_move_iterator(items_.end()));
855 template <
typename T>
856 template <
typename ValueSelector >
860 *items_.begin()))>::value,
861 "ValueSelector return type must be less-than compareable.");
862 asserts::invariant::eval(!items_.empty()) <<
"Sequence cannot be empty.";
865 return *std::min_element(
866 std::make_move_iterator(items_.begin()),
867 std::make_move_iterator(items_.end()),
868 [&value_selector](
const auto &lhs,
const auto &rhs) {
869 return value_selector(lhs) < value_selector(rhs);
873 template <
typename T>
874 template <
typename ValueSelector>
878 std::is_copy_assignable_v<T> ||
879 (std::is_move_assignable_v<T> && std::is_move_constructible_v<T>),
880 "T must either be copy assignable, or move assignable and "
884 *items_.begin()))>::value,
885 "ValueSelector return type must be less-than compareable.");
887 using K = decltype(value_selector(*items_.begin()));
889 items_.begin(), items_.end(),
890 [&value_selector, descending](
const auto &lhs,
const auto &rhs) ->
bool {
891 const K &lhs_value = value_selector(lhs);
892 const K &rhs_value = value_selector(rhs);
893 return descending ? lhs_value > rhs_value : lhs_value < rhs_value;
899 template <
typename T>
901 std::reverse(items_.begin(), items_.end());
905 template <
typename T>
906 template <
typename Selector >
908 using U = decltype(selector(*items_.begin()));
909 std::vector<U> selected;
910 selected.reserve(items_.size());
912 std::make_move_iterator(items_.begin()),
913 std::make_move_iterator(items_.end()), std::back_inserter(selected),
919 template <
typename T>
922 items_.begin(), items_.end(), std::mt19937(std::random_device()()));
926 template <
typename T>
928 return items_.
size();
931 template <
typename T>
933 asserts::invariant::eval(value <= size())
934 <<
"Skip value " << value
935 <<
" must be less than or equal to sequence size of " << size() <<
".";
938 {std::make_move_iterator(items_.begin() + value),
939 std::make_move_iterator(items_.end())});
942 template <
typename T>
944 Queryable<T>::slice(
size_t start_index,
size_t size,
size_t stride) {
945 asserts::invariant::eval(start_index < this->size())
946 <<
"Slice start index " << start_index
947 <<
" must be less than sequence size of " << this->size() <<
".";
949 size_t slice_length = (start_index - 1) + (size * stride);
950 asserts::invariant::eval(stride == 0 || slice_length <= this->size())
951 <<
"Slice length " << slice_length
952 <<
" must be less than or equal to the sequence size of " << this->size()
955 std::vector<T> sliced;
956 sliced.reserve(size);
959 for (
size_t current_size = 0; current_size < size; current_size++) {
960 sliced.push_back(std::move(items_[i]));
967 template <
typename T>
968 Queryable<T> Queryable<T>::sort() {
969 std::sort(items_.begin(), items_.end());
973 template <
typename T>
975 asserts::invariant::eval(value <= size())
976 <<
"Take value " << value
977 <<
" must be less than or equal to sequence size of " << size() <<
".";
980 {std::make_move_iterator(items_.begin()),
981 std::make_move_iterator(items_.begin() + value)});
984 template <
typename T>
985 Queryable<T> Queryable<T>::take_random(
size_t value) {
986 asserts::invariant::eval(value <= size())
987 <<
"Take random value " << value
988 <<
" must be less than or equal to sequence size of " << size() <<
".";
990 std::vector<int> indices;
991 indices.reserve(items_.size());
992 for (
int i = 0; i < items_.size(); i++) {
993 indices.push_back(i);
996 indices.begin(), indices.end(), std::mt19937(std::random_device()()));
997 indices.resize(value);
999 std::vector<T> random_items;
1000 random_items.reserve(std::min(items_.size(), value));
1002 indices.begin(), indices.end(), std::back_inserter(random_items),
1003 [
this](
int i) { return std::move(items_[i]); });
1008 template <
typename T>
1009 template <
typename KeySelector >
1010 auto Queryable<T>::to_multi_value_map(KeySelector key_selector) {
1011 using K = decltype(key_selector(*items_.begin()));
1012 std::map<K, std::vector<T>> mapped;
1013 std::for_each(items_.begin(), items_.end(), [&,
this](
auto &item) {
1014 mapped[key_selector(item)].push_back(std::move(item));
1019 template <
typename T>
1020 template <
typename KeySelector >
1022 using K = decltype(key_selector(*items_.begin()));
1025 "KeySelector return type must be less-than compareable.");
1027 std::map<K, T> mapped;
1029 std::make_move_iterator(items_.begin()),
1030 std::make_move_iterator(items_.end()), [&,
this](
auto item) {
1031 K key = key_selector(item);
1032 auto it = mapped.find(key);
1033 if (it == mapped.end()) {
1034 mapped.insert({std::move(key), std::move(item)});
1040 template <
typename T>
1041 std::set<T> Queryable<T>::to_set() {
1043 traits::is_less_than_comparable<T>::value,
1044 "T must be less-than compareable.");
1046 std::make_move_iterator(items_.begin()),
1047 std::make_move_iterator(items_.end()));
1050 template <
typename T>
1052 return std::move(items_);
1055 template <
typename T>
1058 <<
"Size " << size <<
" must be less than or equal to sequence size of "
1059 << this->size() <<
".";
1061 items_.resize(items_.size() - size);
1065 template <
typename T>
1069 "T must be less-than compareable.");
1071 std::set<T> unionized(
1072 std::make_move_iterator(items_.begin()),
1073 std::make_move_iterator(items_.end()));
1075 rhs_items.begin(), rhs_items.end(),
1076 std::inserter(unionized, unionized.end()));
1078 return Queryable<T>(transforms::to_vector(std::move(unionized)));
1081 template <
typename T>
1082 template <
typename Predicate>
1084 std::vector<T> filtered;
1086 std::make_move_iterator(items_.begin()),
1087 std::make_move_iterator(items_.end()), std::back_inserter(filtered),
1092 template <
typename T>
1093 template <
typename U>
1098 std::is_default_constructible_v<T>,
1099 "T must have a default constructor so default values can "
1100 "populate the tuple.");
1102 std::is_default_constructible_v<U>,
1103 "U must have a default constructor so default values can "
1104 "populate the tuple.");
1107 std::vector<std::tuple<T, U>> zipped;
1109 truncate ? std::min({items_.size(), rhs_items.size()})
1110 : std::max({items_.size(), rhs_items.size()}));
1113 for (; i < std::min({items_.size(), rhs_items.size()}); i++) {
1114 zipped.push_back({std::move(items_[i]), std::move(rhs_items[i])});
1118 return Queryable<std::tuple<T, U>>(std::move(zipped));
1121 if (items_.size() > rhs_items.size()) {
1122 for (; i < items_.size(); i++) {
1123 zipped.push_back({std::move(items_[i]), U()});
1126 for (; i < rhs_items.size(); i++) {
1127 zipped.push_back({T(), std::move(rhs_items[i])});
1130 return Queryable<std::tuple<T, U>>(std::move(zipped));
1133 template <
typename T>
1134 template <
typename U>
1135 Queryable<std::tuple<T, U>>
1136 Queryable<T>::zip(std::initializer_list<U> rhs_items,
bool truncate) {
1137 return zip(std::vector<U>(std::move(rhs_items)), truncate);
1140 template <
typename TrueT,
typename FalseT>
1144 : true_queried_(std::move(true_queried)),
1145 false_queried_(std::move(false_queried)) {}
1147 virtual ~
Merge() =
default;
1153 return true_queried_.
zip(std::move(false_queried_.to_vector()), truncate);
1161 template <
typename WhenTrueQueriedT,
typename T>
1166 std::vector<T> when_false_items)
1167 : when_true_queried_(std::move(when_true_queried)),
1168 when_false_items_(std::move(when_false_items)) {}
1169 WhenFalse() =
delete;
1170 virtual ~WhenFalse() =
default;
1171 WhenFalse(
const WhenFalse &) =
delete;
1172 WhenFalse &operator=(
const WhenFalse &) =
delete;
1176 typename WhenFalseQuery
1180 typename WhenFalseQueriedT =
1181 std::invoke_result_t<WhenFalseQuery, Queryable<T>>::item_type>
1182 Merge<WhenTrueQueriedT, WhenFalseQueriedT>
1183 when_false(WhenFalseQuery when_false_query) {
1184 return Merge<WhenTrueQueriedT, WhenFalseQueriedT>(
1185 Queryable<WhenTrueQueriedT>(when_true_queried_.to_vector()),
1186 when_false_query(Queryable<T>(std::move(when_false_items_))));
1190 Queryable<WhenTrueQueriedT> when_true_queried_;
1191 std::vector<T> when_false_items_;
1195 template <
typename T>
1199 std::vector<T> when_true_items, std::vector<T> when_false_items)
1200 : when_true_items_(std::move(when_true_items)),
1201 when_false_items_(std::move(when_false_items)) {}
1202 WhenTrue() =
delete;
1203 virtual ~WhenTrue() =
default;
1204 WhenTrue(
const WhenTrue &) =
delete;
1205 WhenTrue &operator=(
const WhenTrue &) =
delete;
1209 typename WhenTrueQuery
1213 typename WhenTrueQueriedT =
1214 std::invoke_result_t<WhenTrueQuery, Queryable<T>>::item_type>
1215 WhenFalse<WhenTrueQueriedT, T> when_true(WhenTrueQuery when_true_query) {
1216 return WhenFalse<WhenTrueQueriedT, T>(
1217 std::move(when_true_query(Queryable<T>(std::move(when_true_items_)))),
1218 std::move(when_false_items_));
1222 std::vector<T> when_true_items_;
1223 std::vector<T> when_false_items_;
1226 template <
typename T>
1227 template <
typename Predicate>
1228 WhenTrue<T> Queryable<T>::branch(Predicate predicate) {
1229 std::vector<T> when_true_items;
1230 std::vector<T> when_false_items;
1232 std::make_move_iterator(items_.begin()),
1233 std::make_move_iterator(items_.end()), [&](
auto item) {
1234 if (predicate(item)) {
1235 when_true_items.push_back(std::move(item));
1237 when_false_items.push_back(std::move(item));
1241 return WhenTrue<T>(std::move(when_true_items), std::move(when_false_items));
1246 #endif // FCPP_QUERY_H