18 template <auto Start, auto End, auto Inc,
class F>
19 constexpr void constexpr_for(F&& f)
21 if constexpr(Start < End) {
22 f(std::integral_constant<
decltype(Start), Start>());
23 constexpr_for < Start + Inc, End, Inc > (f);
37 using _Remove_cvref_t = std::remove_cv_t<std::remove_reference_t<_Ty>>;
39 template <
int N,
typename... Ts>
41 typename std::tuple_element<N, std::tuple<Ts...>>::type;
45 template <
typename T1>
50 template <
typename T1,
typename T2>
54 constexpr ax_type(T1 t1) : v(std::move(t1)) {}
55 constexpr ax_type operator=(T1&& t1)
const {
return ax_type(std::move(t1)); }
56 constexpr ax_type operator=(
const T1& t1)
const {
return ax_type(t1); }
58 template <
typename T_IN>
59 constexpr ax_type operator()(T_IN&& t1)
const {
return ax_type(std::move(
static_cast<T1
>(t1))); }
61 template <
typename T_IN>
62 constexpr ax_type operator()(
const T_IN& t1)
const {
return ax_type(
static_cast<T1
>(t1)); }
63 constexpr ax_type operator=(T1&& t1)
68 constexpr ax_type& operator=(
const T1& t1)
81 using struct_maker = T2;
89 operator const T1()
const
94 template <
typename T_RHS>
100 template <
typename T_RHS>
103 return lhs.v <= rhs.v;
106 template <
typename T_RHS>
109 return lhs.v == rhs.v;
112 template <
typename T_RHS>
115 return lhs.v != rhs.v;
118 template <
typename T_RHS>
121 return lhs.v >= rhs.v;
124 template <
typename T_RHS>
127 return lhs.v > rhs.v;
133 friend constexpr bool operator<(
const ax_type& lhs,
const T1& rhs)
137 friend constexpr bool operator<(
const T1 lhs,
const ax_type& rhs)
143 friend constexpr bool operator<=(
const ax_type& lhs,
const T1& rhs)
148 friend constexpr bool operator<=(
const T1& lhs,
const ax_type& rhs)
154 friend constexpr bool operator==(
const ax_type& lhs,
const T1& rhs)
159 friend constexpr bool operator==(
const T1& lhs,
const ax_type& rhs)
165 friend constexpr bool operator!=(
const ax_type& lhs,
const T1& rhs)
170 friend constexpr bool operator!=(
const T1& lhs,
const ax_type& rhs)
176 friend constexpr bool operator>=(
const ax_type& lhs,
const T1& rhs)
181 friend constexpr bool operator>=(
const T1& lhs,
const ax_type& rhs)
187 friend constexpr bool operator>(
const ax_type& lhs,
const T1& rhs)
192 friend constexpr bool operator>(
const T1& lhs,
const ax_type& rhs)
198 friend std::ostream& operator<<(std::ostream& out,
const ax_type& self)
200 out << self.get_name() <<
" : " << self.v;
208 namespace comparators {
209 template <
typename T1,
typename... T_rest>
212 template <
typename VECA_T,
typename VECB_T>
213 static auto __isLessthen(
const VECA_T& vecA,
const VECB_T& vecB)
215 if constexpr(
sizeof...(T_rest) > 0) {
216 if (T1::get(vecA) < T1::get(vecB)) {
218 }
else if (T1::get(vecA) > T1::get(vecB)) {
221 return _nt_compare<T_rest...>::template __isLessthen(vecA, vecB);
223 return T1::get(vecA) < T1::get(vecB);
227 template <
typename VECA_T,
typename VECB_T>
228 static auto __isEequal(
const VECA_T& vecA,
const VECB_T& vecB)
230 if constexpr(
sizeof...(T_rest) > 0) {
231 if (nt::_Remove_cvref_t<T1>::get(vecA) != nt::_Remove_cvref_t<T1>::get(vecB)) {
234 return _nt_compare<T_rest...>::template __isEequal(vecA, vecB);
236 return nt::_Remove_cvref_t<T1>::get(vecA) == nt::_Remove_cvref_t<T1>::get(vecB);
241 template <
typename... T_rest>
242 auto nt_compare(T_rest&& ...)
247 template <
typename... T_rest>
248 constexpr auto lessThan(T_rest&& ...)
250 return [less = _nt_compare<nt::_Remove_cvref_t<T_rest>...> {}](
const auto & lhs,
const auto & rhs) {
251 return less.__isLessthen(lhs, rhs);
255 template <
typename... T_rest>
256 constexpr auto lessThan()
258 return [less = _nt_compare<nt::_Remove_cvref_t<T_rest>...> {}](
const auto & lhs,
const auto & rhs) {
259 return less.__isLessthen(lhs, rhs);
263 template <
typename... T_rest>
264 constexpr auto equal(T_rest&& ...)
266 return [less = _nt_compare<nt::_Remove_cvref_t<T_rest>...> {}](
const auto & lhs,
const auto & rhs) {
267 return less.__isEequal(lhs, rhs);
271 template <
typename... T_rest>
272 constexpr auto equal()
274 return [less = _nt_compare<nt::_Remove_cvref_t<T_rest>...> {}](
const auto & lhs,
const auto & rhs) {
275 return less.__isEequal(lhs, rhs);
280 template <
typename T1,
typename T2>
285 using struct_maker = T2;
290 static constexpr int c_struct_maker = 0;
291 static constexpr int c_getter1 = 1;
292 static constexpr int c_get_name = 2;
295 template <
typename T2>
301 template <
typename T,
int N>
303 static constexpr int N_value = N;
308 template <
typename T>
309 static constexpr auto struct_maker()
311 return decltype(std::declval<type>()(std::declval<type_wrap<T, c_struct_maker>>())) {};
314 template <
typename Data_T>
315 using base_t =
typename decltype(struct_maker<Data_T>())::type;
317 template <
typename T>
318 static constexpr decltype(
auto) get(T& t)
320 using getter1 =
decltype(std::declval<type>()(std::declval<type_wrap<T&, c_getter1>>()));
321 return getter1::get(t);
324 template <
typename T>
325 static constexpr decltype(
auto) get(
const T& t)
327 using getter1 =
decltype(std::declval<type>()(std::declval<type_wrap<const T&, c_getter1>>()));
328 return getter1::get(t);
330 template <
typename T>
331 static constexpr decltype(
auto) get_value(
const T& t)
333 return ax_name_container_base::get(t).v;
336 template <
typename T>
337 static constexpr decltype(
auto) get_value(T& t)
339 return ax_name_container_base::get(t).v;
342 static constexpr auto get_name()
344 using name_getter =
decltype(std::declval<type>()(std::declval<type_wrap<int, c_get_name>>()));
345 return name_getter::get_name();
349 template <
typename TBase>
353 template <
typename T>
354 constexpr decltype(
auto)
operator()(T&& t)
const
356 return TBase::get(t);
359 template <
typename T>
360 static constexpr decltype(
auto) get_value(T& t)
362 return TBase::get(t).v;
365 template <
typename T>
366 static constexpr decltype(
auto) get_value(
const T& t)
368 return TBase::get(t).v;
371 template <
typename T>
372 constexpr auto operator=(T t)
const
379 template <
typename... Ts>
382 template <
typename T2>
388 template <
typename T,
typename data_T>
390 using type =
typename T::template base_t<data_T>;
392 template <
typename T,
typename data_T>
393 using base_maker_t =
typename base_maker<T, data_T>::type;
397 template <
typename T>
398 using ntuple_base_t = base_maker_t<_Remove_cvref_t<T>, T>;
400 template <
typename... T>
403 constexpr ntuple& operator=(
const ntuple& rhs) =
default;
405 constexpr ntuple(
const T& ...t1) : ntuple_base_t<T>(t1)... {}
408 constexpr ntuple() : ntuple_base_t<T>(_Remove_cvref_t<T> {})... {}
410 template <
typename... Ts,
typename = std::enable_if_t < (
sizeof...(Ts) != 1) > >
411 constexpr ntuple(Ts && ...t1) : ntuple_base_t<T>(std::forward<Ts>(t1))... {}
413 template <
typename T2>
419 friend std::ostream& operator<<(std::ostream& out,
const ntuple& self)
423 constexpr_for<0,
sizeof...(T), 1>([&](
auto i) {
424 using current_t =
decltype(NthTypeOf<i, _Remove_cvref_t<T>...> {});
426 out << current_t::get(self);
433 template <
typename... ARGS>
436 return ntuple<T..., ARGS...>(
442 friend constexpr bool operator<(
const ntuple& lhs,
const ntuple& rhs)
444 constexpr auto lt = comparators::lessThan<T...>();
447 inline static constexpr std::size_t __size__ =
sizeof...(T);
450 template <
typename... Ts>
453 template <
int N,
typename... ARGS>
456 return nt::_Remove_cvref_t<nt::NthTypeOf<N, nt::_Remove_cvref_t<ARGS>...>>::get(nt);
459 template <
int N,
typename... ARGS>
462 return nt::_Remove_cvref_t<nt::NthTypeOf<N, nt::_Remove_cvref_t<ARGS>...>>::get(nt);
466 template <
typename T,
typename Ntuple>
471 template <
typename T,
typename... ARGS>
476 template <
typename T,
typename Ntuple>
484namespace nt::comparators {
488 template <
typename T1,
typename T2>
489 constexpr static bool __comp__(T1&& t1, T2&& t2)
492 constexpr_for<0, _Remove_cvref_t<T1>::__size__, 1>(
494 using N_th_T = _Remove_cvref_t<decltype(nt::get_nth<i>(t1))>;
495 if constexpr(contains_type_v<N_th_T, _Remove_cvref_t<T2>>) {
496 ret &= (N_th_T::get(t1) == N_th_T::get(t2));
502 template <
typename T1,
typename T2>
503 constexpr bool operator()(T1&& t1, T2&& t2)
const
505 return __comp__(std::forward<T1>(t1), std::forward<T2>(t2));
516 template <
typename... Ts>
517 struct dataframe : nt::base_maker_t<nt::_Remove_cvref_t<Ts>, nt::ax_type2<std::vector<Ts>, typename Ts::struct_maker>>... {
519 template <
typename T2>
525 auto operator[](
size_t i)
532 auto operator[](
size_t i)
const
539 template <
typename T>
540 void push_back(
const T& t)
543 [](
auto...) {}(Ts::get(*this).emplace_back(Ts::get(t))...);
546 template <
typename... T>
547 void emplace_back(T&& ...t)
549 static_assert(
sizeof...(t) ==
sizeof...(Ts),
"\n==============missmatched amount of arguments=================\n");
550 [](
auto...) {}(T::get(*this).emplace_back(std::forward<T>(t))...);
553 template <
typename T1>
554 decltype(
auto) get()
const
556 return T1::get(*
this);
559 template <
typename T1>
562 return T1::get(*
this);
567 auto size = _Remove_cvref_t<NthTypeOf<0, Ts...>>::get(*this).size();
572 static constexpr auto get_nth_type()
575 return get_ax_name_container(NthTypeOf<N, _Remove_cvref_t<Ts>...> {});
577 friend std::ostream& operator<<(std::ostream& out,
const dataframe& self)
581 constexpr_for<0,
sizeof...(Ts), 1>([&](
auto ntuple_index) {
582 static const auto x = self.template get_nth_type<ntuple_index>();
584 out << std::setw(5) << x.get_name();
590 constexpr_for<0,
sizeof...(Ts), 1>([&](
auto i) {
591 out << std::setw(5) <<
"-------|";
594 auto size = self.size();
595 for (
int i = 0; i < size; ++i) {
596 auto current_element = self[i];
598 constexpr_for<0,
sizeof...(Ts), 1>([&](
auto ntuple_index) {
599 static const auto x = self.template get_nth_type<ntuple_index>();
601 out << std::setw(5) << x.get(current_element).v;
611 template <
typename... Ts>
614 template <
typename T>
618 template <
typename... T>
623 template <
typename F>
624 auto fill_dataframe(
int index, F&& f)
627 for (
int i = 0; i < index; ++i) {
633 template <
typename NT_T,
typename FUNT>
634 void ntuple_for_each(
const NT_T& ntuple, FUNT&& fun)
638 nt::_Remove_cvref_t<
decltype(ntuple)>::__size__,
642 nt::get_nth<j>(ntuple)
650namespace nt::algorithms {
655 template <
typename T>
656 constexpr T&& operator()(T&& t)
const
661 template <
typename VEC,
typename FUNC_T =
identity_t>
662 auto sum(
const VEC& vec, FUNC_T && proj =
identity_t {})
664 decltype(proj(vec[0])) ret {};
665 for (
auto&& e : vec) {
672 template <
typename VEC,
typename FUNC_T>
673 auto add_column(
const VEC& vec, FUNC_T&& func)
675 std::vector <
decltype(vec[0] | func(vec[0])) > ret;
676 ret.reserve(vec.size());
677 for (
const auto& e : vec) {
678 ret.push_back(e | func(e));
683 template <
typename FUNC_T>
684 auto fill_vector(
size_t entries, FUNC_T&& func)
686 std::vector<
decltype(func(
size_t(0)))> ret;
687 ret.reserve(entries);
688 for (
size_t i = 0; i < entries; ++i) {
689 ret.push_back(func(i));
694 template <
typename T0,
typename T1,
typename T2,
typename Comparision_T,
typename projecttion_t>
695 void join_vectors_r(T0& ret,
const T1& t1,
const T2& t2, Comparision_T comp, projecttion_t project)
698 for (
const auto& e1 : t1) {
699 for (
const auto& e2 : t2) {
701 ret.push_back(project(e1, e2));
707 template <
typename T1,
typename T2,
typename Comparision_T,
typename projecttion_t>
708 auto join_vectors(
const T1& t1,
const T2& t2, Comparision_T comp, projecttion_t project)
710 std::vector<
decltype(project(t1[0], t2[0]))> ret;
711 join_vectors_r(ret, t1, t2, comp, project);
715 template <
typename CONTAINER_T>
716 void sort(CONTAINER_T& container)
718 std::sort(container.begin(), container.end());
721 template <
typename CONTAINER_T,
typename COMP_T>
722 void sort(CONTAINER_T& container, COMP_T&& comp)
724 std::sort(container.begin(), container.end(), comp);
727 template <
typename CONTAINER_T,
typename OP_T>
728 auto count_if(
const CONTAINER_T& container, OP_T op)
731 for (
const auto& e : container)
737 template <
typename VEC_T,
typename FILTER_T>
738 void filter(VEC_T& vec, FILTER_T&& f)
740 auto removeIt = std::remove_if(vec.begin(), vec.end(), [&](
auto&& e) {return !f(e); });
741 vec.erase(removeIt, vec.end());
745 template <
typename VEC_T,
typename FILTER_T>
746 auto filter_copy(
const VEC_T& vec, FILTER_T&& f)
749 ret.reserve(vec.size());
750 for (
const auto& e : vec) {
761namespace nt::algorithms {
765 template <
typename... T>
767 template <
typename VEC_T,
typename FUNC_T>
768 static auto apply_append(
const std::vector<VEC_T>& vec, FUNC_T&& fun)
770 auto fun_c = [&](
const auto & rng) {
771 auto tail = rng.begin();
772 return nt::ntuple<T...>(T::get(*tail)...) | fun(rng);
774 return __apply__internal__(vec, fun_c);
777 template <
typename VEC_T,
typename FUNC_T>
778 static auto apply(
const std::vector<VEC_T>& vec, FUNC_T&& fun)
780 auto fun_c = [&](
const auto & rng) {
783 return __apply__internal__(vec, fun_c);
788 template <
typename VEC_T,
typename FUNC_T>
789 static auto create_empty_vector()
791 return std::vector< decltype(std::declval<FUNC_T>()(std::declval<const std::vector<VEC_T>& >())) > {};
794 template <
typename VEC_T,
typename FUNC_T>
795 static auto __apply__internal__(
const std::vector<VEC_T>& vec, FUNC_T&& fun_c)
797 static constexpr auto lt = nt::comparators::lessThan<T...>();
798 static constexpr auto eq = nt::comparators::equal<T...>();
799 auto ret = create_empty_vector<VEC_T, FUNC_T>();
806 auto min_element = vec[0];
807 auto max_element = vec[0];
809 for (
const auto& e : vec) {
810 if (lt(e, min_element)) {
814 if (lt(max_element, e)) {
819 if (eq(min_element, max_element)) {
826 std::vector<VEC_T> buff{};
827 buff.reserve(vec.size());
831 auto process = [&]() {
833 VEC_T next_min_element{};
834 next_min_element = max_element;
836 for (
const auto& e : vec) {
837 if (eq(min_element, e)) {
839 }
else if (lt(min_element, e) && lt(e, next_min_element)) {
840 next_min_element = e;
845 min_element = next_min_element;
848 ret.push_back(fun_c(buff));
851 while (lt(min_element, max_element)) {
863 template <
typename... ARGS>
870 template <
typename T>
871 constexpr auto get_default_element(T&& t)
873 return nt::_Remove_cvref_t<
decltype(t[0])> {};
881#define ax_maker(name_) []() constexpr { \
882 auto struct_maker_template_lambda = [](auto e) constexpr { \
883 using ARG_T = decltype(e); \
884 if constexpr (e.N_value == nt::ax_name_container_base_const::c_struct_maker) \
886 if constexpr (!std::is_reference_v<typename ARG_T::type>) \
890 constexpr Zt##name_() {} \
891 constexpr Zt##name_(const decltype(e.val) &e_) : name_(e_) {} \
892 constexpr Zt##name_(decltype(e.val) &e_) : name_(e_) {} \
893 constexpr Zt##name_(decltype(e.val) &&e_) : name_(std::move(e_)) {} \
894 decltype(e.val) name_; \
895 decltype(e.val) value() const \
900 return nt::type_container<Zt##name_>{}; \
906 Zt##name_(decltype(e.val) e_) : name_(e_) {} \
907 decltype(e.val) name_; \
908 decltype(e.val) value() const \
913 return nt::type_container<Zt##name_>{}; \
916 else if constexpr (e.N_value == nt::ax_name_container_base_const::c_getter1) \
920 static auto &get(decltype(e.val) x) \
927 else if constexpr (e.N_value == nt::ax_name_container_base_const::c_get_name) \
929 struct name_getter_t \
931 static std::string get_name() \
936 return name_getter_t{}; \
939 return nt::ax_name_container< \
940 nt::ax_name_container_base<decltype(struct_maker_template_lambda)>>{}; \
943#define ax_new_axis(name_, value) static constexpr inline auto name_ = (ax_maker(name_) = value)
945#define ax_new_axis_t(name_, value) \
946 auto __internal__##name_ = [] { return ax_maker(name_) = value; }; \
947 using name_ = decltype(__internal__##name_())
950#define nt_lessthan(...) [](){ using T = decltype( \
951 nt::comparators::nt_compare( __VA_ARGS__ ) ); \
952 static constexpr T t{}; \
953 return [&](const auto& x,const auto &y) {return t.__isLessthen(x,y);}; }()
955#define nt_equal(...) [](){ using T = decltype( \
956 nt::comparators::nt_compare( __VA_ARGS__ ) ); \
957 static constexpr T t{}; \
958 return [&](const auto& x,const auto &y) {return t.__isEequal(x,y);}; }()
962#define nt_group(...) [](){ using T = decltype( \
963 nt::algorithms::group( __VA_ARGS__ ) ); \
964 static constexpr T t{}; \
971#define __nt_new_axis_core(name_) \
974 template <typename T> \
977 constexpr type_wrap() {} \
978 template <typename T1> \
979 constexpr type_wrap(T1 &&e_) : name_(std::forward<T1>(e_)) {} \
982 template <typename Data_T> \
983 using base_t = type_wrap<Data_T>; \
984 static auto get_name() \
988 template <typename T> \
989 static constexpr auto &get(T &t) \
993 template <typename T> \
994 static constexpr const auto &get(const T &t) \
1000#define __nt_new_axis(qualifier, name_, value) \
1003 __nt_new_axis_core(name_); \
1005 qualifier name_ = (nt::ax_name_container<__nt::zt##name_>{} = value)
1007#define nt_new_axis(name_, value) __nt_new_axis(static constexpr inline auto, name_, value)
1008#define nt_new_axis_c(name_, value) __nt_new_axis(static const inline auto, name_, value)
1010#define nt_new_axis_t(name_, value) \
1013 __nt_new_axis_core(name_); \
1015 using name_ = decltype(nt::ax_name_container<__nt::zt##name_>{} = value)
1017#define nt_new_name(name_) \
1020 __nt_new_axis_core(name_); \
1022 static constexpr inline auto name_ = nt::ax_name_container<__nt::zt##name_> {}
1024#define nt_new_name_t(name_) \
1027 __nt_new_axis_core(name_); \
1029 using name_ = nt::ax_name_container<__nt::zt##name_>