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);
36 using element_type = T;
37 using value_type = std::remove_cv_t<T>;
38 using size_type = std::size_t;
39 using difference_type = std::ptrdiff_t;
45 using iterator_category = std::forward_iterator_tag;
47 using difference_type = std::ptrdiff_t;
51 iterator(std::byte* ptr, size_type stride)
52 : m_ptr(ptr), m_stride(stride) {}
54 reference operator*()
const {
return *
reinterpret_cast<pointer
>(m_ptr); }
55 pointer operator->()
const {
return reinterpret_cast<pointer
>(m_ptr); }
72 return a.m_ptr == b.m_ptr;
77 return a.m_ptr != b.m_ptr;
85 span(std::byte* ptr, size_type count, size_type stride =
sizeof(T))
86 : m_ptr(ptr), m_count(count), m_stride(stride) {}
88 reference operator[](size_type idx)
const
90 return *
reinterpret_cast<pointer
>(m_ptr + idx * m_stride);
93 pointer data() const noexcept
95 return reinterpret_cast<pointer
>(m_ptr);
98 size_type size() const noexcept
103 size_type stride() const noexcept
108 iterator begin() const noexcept
110 return iterator(m_ptr, m_stride);
113 iterator end() const noexcept
115 return iterator(m_ptr + m_count * m_stride, m_stride);
126#define nt_span(container, member) nt::span<decltype(container[0].member.v)>( \
127 container.size() ? (std::byte *)&decltype(container[0].member)::get(container[0]) : nullptr, \
128 container.size(), sizeof(decltype(container[0])))
130#define nt_span_t(container, member) nt::span<decltype(container[0].member)>( \
131 container.size() ? (std::byte *)&decltype(container[0].member)::get(container[0]) : nullptr, \
132 container.size(), sizeof(decltype(container[0])))
137 using _Remove_cvref_t = std::remove_cv_t<std::remove_reference_t<_Ty>>;
139 template <
int N,
typename... Ts>
141 typename std::tuple_element<N, std::tuple<Ts...>>::type;
145 template <
typename T1>
150 template <
typename T1,
typename T2>
154 constexpr ax_type(T1 t1) : v(std::move(t1)) {}
155 constexpr ax_type operator=(T1&& t1)
const {
return ax_type(std::move(t1)); }
156 constexpr ax_type operator=(
const T1& t1)
const {
return ax_type(t1); }
158 template <
typename T_IN>
159 constexpr ax_type operator()(T_IN&& t1)
const {
return ax_type(std::move(
static_cast<T1
>(t1))); }
161 template <
typename T_IN>
162 constexpr ax_type operator()(
const T_IN& t1)
const {
return ax_type(
static_cast<T1
>(t1)); }
163 constexpr ax_type operator=(T1&& t1)
168 constexpr ax_type& operator=(
const T1& t1)
174 template <
typename T>
181 using struct_maker = T2;
189 operator const T1()
const
194 template <
typename T_RHS>
197 return lhs.v < rhs.v;
200 template <
typename T_RHS>
203 return lhs.v <= rhs.v;
206 template <
typename T_RHS>
209 return lhs.v == rhs.v;
212 template <
typename T_RHS>
215 return lhs.v != rhs.v;
218 template <
typename T_RHS>
221 return lhs.v >= rhs.v;
224 template <
typename T_RHS>
227 return lhs.v > rhs.v;
233 friend constexpr bool operator<(
const ax_type& lhs,
const T1& rhs)
237 friend constexpr bool operator<(
const T1 lhs,
const ax_type& rhs)
243 friend constexpr bool operator<=(
const ax_type& lhs,
const T1& rhs)
248 friend constexpr bool operator<=(
const T1& lhs,
const ax_type& rhs)
254 friend constexpr bool operator==(
const ax_type& lhs,
const T1& rhs)
259 friend constexpr bool operator==(
const T1& lhs,
const ax_type& rhs)
265 friend constexpr bool operator!=(
const ax_type& lhs,
const T1& rhs)
270 friend constexpr bool operator!=(
const T1& lhs,
const ax_type& rhs)
276 friend constexpr bool operator>=(
const ax_type& lhs,
const T1& rhs)
281 friend constexpr bool operator>=(
const T1& lhs,
const ax_type& rhs)
287 friend constexpr bool operator>(
const ax_type& lhs,
const T1& rhs)
292 friend constexpr bool operator>(
const T1& lhs,
const ax_type& rhs)
298 friend std::ostream& operator<<(std::ostream& out,
const ax_type& self)
300 out << self.get_name() <<
" : " << self.v;
308 namespace comparators {
309 template <
typename T1,
typename... T_rest>
312 template <
typename VECA_T,
typename VECB_T>
313 static auto __isLessthen(
const VECA_T& vecA,
const VECB_T& vecB)
315 if constexpr(
sizeof...(T_rest) > 0) {
316 if (T1::get(vecA) < T1::get(vecB)) {
318 }
else if (T1::get(vecA) > T1::get(vecB)) {
321 return _nt_compare<T_rest...>::template __isLessthen(vecA, vecB);
323 return T1::get(vecA) < T1::get(vecB);
327 template <
typename VECA_T,
typename VECB_T>
328 static auto __isEequal(
const VECA_T& vecA,
const VECB_T& vecB)
330 if constexpr(
sizeof...(T_rest) > 0) {
331 if (nt::_Remove_cvref_t<T1>::get(vecA) != nt::_Remove_cvref_t<T1>::get(vecB)) {
334 return _nt_compare<T_rest...>::template __isEequal(vecA, vecB);
336 return nt::_Remove_cvref_t<T1>::get(vecA) == nt::_Remove_cvref_t<T1>::get(vecB);
341 template <
typename... T_rest>
342 auto nt_compare(T_rest&& ...)
347 template <
typename... T_rest>
348 constexpr auto lessThan(T_rest&& ...)
350 return [less = _nt_compare<nt::_Remove_cvref_t<T_rest>...> {}](
const auto & lhs,
const auto & rhs) {
351 return less.__isLessthen(lhs, rhs);
355 template <
typename... T_rest>
356 constexpr auto lessThan()
358 return [less = _nt_compare<nt::_Remove_cvref_t<T_rest>...> {}](
const auto & lhs,
const auto & rhs) {
359 return less.__isLessthen(lhs, rhs);
363 template <
typename... T_rest>
364 constexpr auto equal(T_rest&& ...)
366 return [less = _nt_compare<nt::_Remove_cvref_t<T_rest>...> {}](
const auto & lhs,
const auto & rhs) {
367 return less.__isEequal(lhs, rhs);
371 template <
typename... T_rest>
372 constexpr auto equal()
374 return [less = _nt_compare<nt::_Remove_cvref_t<T_rest>...> {}](
const auto & lhs,
const auto & rhs) {
375 return less.__isEequal(lhs, rhs);
380 template <
typename T1,
typename T2>
385 using struct_maker = T2;
390 static constexpr int c_struct_maker = 0;
391 static constexpr int c_getter1 = 1;
392 static constexpr int c_get_name = 2;
395 template <
typename T2>
401 template <
typename T,
int N>
403 static constexpr int N_value = N;
408 template <
typename T>
409 static constexpr auto struct_maker()
411 return decltype(std::declval<type>()(std::declval<type_wrap<T, c_struct_maker>>())) {};
414 template <
typename Data_T>
415 using base_t =
typename decltype(struct_maker<Data_T>())::type;
417 template <
typename T>
418 static constexpr decltype(
auto) get(T& t)
420 using getter1 =
decltype(std::declval<type>()(std::declval<type_wrap<T&, c_getter1>>()));
421 return getter1::get(t);
424 template <
typename T>
425 static constexpr decltype(
auto) get(
const T& t)
427 using getter1 =
decltype(std::declval<type>()(std::declval<type_wrap<const T&, c_getter1>>()));
428 return getter1::get(t);
430 template <
typename T>
431 static constexpr decltype(
auto) get_value(
const T& t)
433 return ax_name_container_base::get(t).v;
436 template <
typename T>
437 static constexpr decltype(
auto) get_value(T& t)
439 return ax_name_container_base::get(t).v;
442 static constexpr auto get_name()
444 using name_getter =
decltype(std::declval<type>()(std::declval<type_wrap<int, c_get_name>>()));
445 return name_getter::get_name();
449 template <
typename TBase>
453 template <
typename T>
454 constexpr decltype(
auto)
operator()(T&& t)
const
456 return TBase::get(t);
459 template <
typename T>
460 static constexpr decltype(
auto) get_value(T& t)
462 return TBase::get(t).v;
465 template <
typename T>
466 static constexpr decltype(
auto) get_value(
const T& t)
468 return TBase::get(t).v;
471 template <
typename T>
472 constexpr auto operator=(T t)
const
479 template <
typename... Ts>
482 template <
typename T2>
488 template <
typename T,
typename data_T>
490 using type =
typename T::template base_t<data_T>;
492 template <
typename T,
typename data_T>
493 using base_maker_t =
typename base_maker<T, data_T>::type;
497 template <
typename T>
498 using ntuple_base_t = base_maker_t<_Remove_cvref_t<T>, T>;
500 template <
typename... T>
503 constexpr ntuple& operator=(
const ntuple& rhs) =
default;
505 constexpr ntuple(
const T& ...t1) : ntuple_base_t<T>(t1)... {}
508 constexpr ntuple() : ntuple_base_t<T>(_Remove_cvref_t<T> {})... {}
510 template <
typename... Ts,
typename = std::enable_if_t < (
sizeof...(Ts) != 1) > >
511 constexpr ntuple(Ts && ...t1) : ntuple_base_t<T>(std::forward<Ts>(t1))... {}
513 template <
typename T2>
519 friend std::ostream& operator<<(std::ostream& out,
const ntuple& self)
523 constexpr_for<0,
sizeof...(T), 1>([&](
auto i) {
524 using current_t =
decltype(NthTypeOf<i, _Remove_cvref_t<T>...> {});
526 out << current_t::get(self);
533 template <
typename... ARGS>
536 return ntuple<T..., ARGS...>(
542 friend constexpr bool operator<(
const ntuple& lhs,
const ntuple& rhs)
544 constexpr auto lt = comparators::lessThan<T...>();
547 inline static constexpr std::size_t __size__ =
sizeof...(T);
550 template <
typename... Ts>
553 template <
int N,
typename... ARGS>
556 return nt::_Remove_cvref_t<nt::NthTypeOf<N, nt::_Remove_cvref_t<ARGS>...>>::get(nt);
559 template <
int N,
typename... ARGS>
562 return nt::_Remove_cvref_t<nt::NthTypeOf<N, nt::_Remove_cvref_t<ARGS>...>>::get(nt);
566 template <
typename T,
typename Ntuple>
571 template <
typename T,
typename... ARGS>
576 template <
typename T,
typename Ntuple>
584namespace nt::comparators {
588 template <
typename T1,
typename T2>
589 constexpr static bool __comp__(T1&& t1, T2&& t2)
592 constexpr_for<0, _Remove_cvref_t<T1>::__size__, 1>(
594 using N_th_T = _Remove_cvref_t<decltype(nt::get_nth<i>(t1))>;
595 if constexpr(contains_type_v<N_th_T, _Remove_cvref_t<T2>>) {
596 ret &= (N_th_T::get(t1) == N_th_T::get(t2));
602 template <
typename T1,
typename T2>
603 constexpr bool operator()(T1&& t1, T2&& t2)
const
605 return __comp__(std::forward<T1>(t1), std::forward<T2>(t2));
616 template <
typename... Ts>
617 struct dataframe : nt::base_maker_t<nt::_Remove_cvref_t<Ts>, nt::ax_type2<std::vector<Ts>, typename Ts::struct_maker>>... {
619 template <
typename T2>
625 auto operator[](
size_t i)
632 auto operator[](
size_t i)
const
639 template <
typename T>
640 void push_back(
const T& t)
643 [](
auto...) {}(Ts::get(*this).emplace_back(Ts::get(t))...);
646 template <
typename... T>
647 void emplace_back(T&& ...t)
649 static_assert(
sizeof...(t) ==
sizeof...(Ts),
"\n==============missmatched amount of arguments=================\n");
650 [](
auto...) {}(T::get(*this).emplace_back(std::forward<T>(t))...);
653 template <
typename T1>
654 decltype(
auto) get()
const
656 return T1::get(*
this);
659 template <
typename T1>
662 return T1::get(*
this);
667 auto size = _Remove_cvref_t<NthTypeOf<0, Ts...>>::get(*this).size();
672 static constexpr auto get_nth_type()
675 return get_ax_name_container(NthTypeOf<N, _Remove_cvref_t<Ts>...> {});
677 friend std::ostream& operator<<(std::ostream& out,
const dataframe& self)
681 constexpr_for<0,
sizeof...(Ts), 1>([&](
auto ntuple_index) {
682 static const auto x = self.template get_nth_type<ntuple_index>();
684 out << std::setw(5) << x.get_name();
690 constexpr_for<0,
sizeof...(Ts), 1>([&](
auto i) {
691 out << std::setw(5) <<
"-------|";
694 auto size = self.size();
695 for (
int i = 0; i < size; ++i) {
696 auto current_element = self[i];
698 constexpr_for<0,
sizeof...(Ts), 1>([&](
auto ntuple_index) {
699 static const auto x = self.template get_nth_type<ntuple_index>();
701 out << std::setw(5) << x.get(current_element).v;
711 template <
typename... Ts>
714 template <
typename T>
718 template <
typename... T>
723 template <
typename F>
724 auto fill_dataframe(
int index, F&& f)
727 for (
int i = 0; i < index; ++i) {
733 template <
typename NT_T,
typename FUNT>
734 void ntuple_for_each(
const NT_T& ntuple, FUNT&& fun)
738 nt::_Remove_cvref_t<
decltype(ntuple)>::__size__,
742 nt::get_nth<j>(ntuple)
750namespace nt::algorithms {
755 template <
typename T>
756 constexpr T&& operator()(T&& t)
const
761 template <
typename VEC,
typename FUNC_T =
identity_t>
762 auto sum(
const VEC& vec, FUNC_T && proj =
identity_t {})
764 decltype(proj(vec[0])) ret{};
765 for (
auto&& e : vec) {
772 template <
typename VEC,
typename FUNC_T>
773 auto add_column(
const VEC& vec, FUNC_T&& func)
775 std::vector <
decltype(vec[0] | func(vec[0])) > ret;
776 ret.reserve(vec.size());
777 for (
const auto& e : vec) {
778 ret.push_back(e | func(e));
783 template <
typename FUNC_T>
784 auto fill_vector(
size_t entries, FUNC_T&& func)
786 std::vector<
decltype(func(
size_t(0)))> ret;
787 ret.reserve(entries);
788 for (
size_t i = 0; i < entries; ++i) {
789 ret.push_back(func(i));
794 template <
typename T0,
typename T1,
typename T2,
typename Comparision_T,
typename projecttion_t>
795 void join_vectors_r(T0& ret,
const T1& t1,
const T2& t2, Comparision_T comp, projecttion_t project)
798 for (
const auto& e1 : t1) {
799 for (
const auto& e2 : t2) {
801 ret.push_back(project(e1, e2));
807 template <
typename T1,
typename T2,
typename Comparision_T,
typename projecttion_t>
808 auto join_vectors(
const T1& t1,
const T2& t2, Comparision_T comp, projecttion_t project)
810 std::vector<
decltype(project(t1[0], t2[0]))> ret;
811 join_vectors_r(ret, t1, t2, comp, project);
815 template <
typename CONTAINER_T>
816 void sort(CONTAINER_T& container)
818 std::sort(container.begin(), container.end());
821 template <
typename CONTAINER_T,
typename COMP_T>
822 void sort(CONTAINER_T& container, COMP_T&& comp)
824 std::sort(container.begin(), container.end(), comp);
827 template <
typename CONTAINER_T,
typename OP_T>
828 auto count_if(
const CONTAINER_T& container, OP_T op)
831 for (
const auto& e : container)
837 template <
typename VEC_T,
typename FILTER_T>
838 void filter(VEC_T& vec, FILTER_T&& f)
840 auto removeIt = std::remove_if(vec.begin(), vec.end(), [&](
auto&& e) {return !f(e); });
841 vec.erase(removeIt, vec.end());
845 template <
typename VEC_T,
typename FILTER_T>
846 auto filter_copy(
const VEC_T& vec, FILTER_T&& f)
849 ret.reserve(vec.size());
850 for (
const auto& e : vec) {
861namespace nt::algorithms {
865 template <
typename... T>
867 template <
typename VEC_T,
typename FUNC_T>
868 static auto apply_append(
const std::vector<VEC_T>& vec, FUNC_T&& fun)
870 auto fun_c = [&](
const auto & rng) {
871 auto tail = rng.begin();
872 return nt::ntuple<T...>(T::get(*tail)...) | fun(rng);
874 return __apply__internal__(vec, fun_c);
877 template <
typename VEC_T,
typename FUNC_T>
878 static auto apply(
const std::vector<VEC_T>& vec, FUNC_T&& fun)
880 auto fun_c = [&](
const auto & rng) {
883 return __apply__internal__(vec, fun_c);
888 template <
typename VEC_T,
typename FUNC_T>
889 static auto create_empty_vector()
891 return std::vector< decltype(std::declval<FUNC_T>()(std::declval<const std::vector<VEC_T>& >())) > {};
894 template <
typename VEC_T,
typename FUNC_T>
895 static auto __apply__internal__(
const std::vector<VEC_T>& vec, FUNC_T&& fun_c)
897 static constexpr auto lt = nt::comparators::lessThan<T...>();
898 static constexpr auto eq = nt::comparators::equal<T...>();
899 auto ret = create_empty_vector<VEC_T, FUNC_T>();
906 auto min_element = vec[0];
907 auto max_element = vec[0];
909 for (
const auto& e : vec) {
910 if (lt(e, min_element)) {
914 if (lt(max_element, e)) {
919 if (eq(min_element, max_element)) {
926 std::vector<VEC_T> buff{};
927 buff.reserve(vec.size());
931 auto process = [&]() {
933 VEC_T next_min_element{};
934 next_min_element = max_element;
936 for (
const auto& e : vec) {
937 if (eq(min_element, e)) {
939 }
else if (lt(min_element, e) && lt(e, next_min_element)) {
940 next_min_element = e;
945 min_element = next_min_element;
948 ret.push_back(fun_c(buff));
951 while (lt(min_element, max_element)) {
963 template <
typename... ARGS>
970 template <
typename T>
971 constexpr auto get_default_element(T&& t)
973 return nt::_Remove_cvref_t<
decltype(t[0])> {};
981#define ax_maker(name_) []() constexpr { \
982 auto struct_maker_template_lambda = [](auto e) constexpr { \
983 using ARG_T = decltype(e); \
984 if constexpr (e.N_value == nt::ax_name_container_base_const::c_struct_maker) \
986 if constexpr (!std::is_reference_v<typename ARG_T::type>) \
990 constexpr Zt##name_() {} \
991 constexpr Zt##name_(const decltype(e.val) &e_) : name_(e_) {} \
992 constexpr Zt##name_(decltype(e.val) &e_) : name_(e_) {} \
993 constexpr Zt##name_(decltype(e.val) &&e_) : name_(std::move(e_)) {} \
994 decltype(e.val) name_; \
995 decltype(e.val) value() const \
1000 return nt::type_container<Zt##name_>{}; \
1006 Zt##name_(decltype(e.val) e_) : name_(e_) {} \
1007 decltype(e.val) name_; \
1008 decltype(e.val) value() const \
1013 return nt::type_container<Zt##name_>{}; \
1016 else if constexpr (e.N_value == nt::ax_name_container_base_const::c_getter1) \
1020 static auto &get(decltype(e.val) x) \
1025 return getter_t{}; \
1027 else if constexpr (e.N_value == nt::ax_name_container_base_const::c_get_name) \
1029 struct name_getter_t \
1031 static std::string get_name() \
1036 return name_getter_t{}; \
1039 return nt::ax_name_container< \
1040 nt::ax_name_container_base<decltype(struct_maker_template_lambda)>>{}; \
1043#define ax_new_axis(name_, value) static constexpr inline auto name_ = (ax_maker(name_) = value)
1045#define ax_new_axis_t(name_, value) \
1046 auto __internal__##name_ = [] { return ax_maker(name_) = value; }; \
1047 using name_ = decltype(__internal__##name_())
1050#define nt_lessthan(...) [](){ using T = decltype( \
1051 nt::comparators::nt_compare( __VA_ARGS__ ) ); \
1052 static constexpr T t{}; \
1053 return [&](const auto& x,const auto &y) {return t.__isLessthen(x,y);}; }()
1055#define nt_equal(...) [](){ using T = decltype( \
1056 nt::comparators::nt_compare( __VA_ARGS__ ) ); \
1057 static constexpr T t{}; \
1058 return [&](const auto& x,const auto &y) {return t.__isEequal(x,y);}; }()
1062#define nt_group(...) [](){ using T = decltype( \
1063 nt::algorithms::group( __VA_ARGS__ ) ); \
1064 static constexpr T t{}; \
1071#define __nt_new_axis_core(name_) \
1074 template <typename T> \
1077 constexpr type_wrap() {} \
1078 template <typename T1> \
1079 constexpr type_wrap(T1 &&e_) : name_(std::forward<T1>(e_)) {} \
1082 template <typename Data_T> \
1083 using base_t = type_wrap<Data_T>; \
1084 static auto get_name() \
1088 template <typename T> \
1089 static constexpr auto &get(T &t) \
1093 template <typename T> \
1094 static constexpr const auto &get(const T &t) \
1100#define __nt_new_axis(qualifier, name_, value) \
1103 __nt_new_axis_core(name_); \
1105 qualifier name_ = (nt::ax_name_container<__nt::zt##name_>{} = value)
1107#define nt_new_axis(name_, value) __nt_new_axis(static constexpr inline auto, name_, value)
1108#define nt_new_axis_c(name_, value) __nt_new_axis(static const inline auto, name_, value)
1110#define nt_new_axis_t(name_, value) \
1113 __nt_new_axis_core(name_); \
1115 using name_ = decltype(nt::ax_name_container<__nt::zt##name_>{} = value)
1117#define nt_new_name(name_) \
1120 __nt_new_axis_core(name_); \
1122 static constexpr inline auto name_ = nt::ax_name_container<__nt::zt##name_> {}
1124#define nt_new_name_t(name_) \
1127 __nt_new_axis_core(name_); \
1129 using name_ = nt::ax_name_container<__nt::zt##name_>