10 #define group_helper_h
17 #include <type_traits>
18 #include <unordered_map>
21 #define let const auto
22 #define letref const auto&
32 namespace group_helper {
35 template <auto Start, auto End, auto Inc,
class F>
36 constexpr
void constexpr_for(F&& f)
38 if constexpr(Start < End) {
39 f(std::integral_constant<decltype(Start), Start>());
40 constexpr_for < Start + Inc, End, Inc > (f);
44 inline std::string root_type_name(
int)
49 inline std::string root_type_name(
double)
53 inline std::string root_type_name(
float)
57 inline std::string root_type_name(int64_t)
61 inline std::string root_type_name(uint64_t)
75 #define AXIS_NAME1(name_, type_, name_str) \
76 namespace name_##_impl_{\
79 type_ name_ = type_{}; \
80 constexpr explicit name_##_(type_ val) : name_ (val) {} \
81 template <typename... T1>\
82 constexpr explicit name_##_(const std::tuple <T1...> & val) : name_ ( std::get<name_##_>(val)) {} \
83 constexpr name_##_() = default; \
84 template <typename... T1> \
85 auto operator()(const std::tuple<T1...>& val) const{ \
86 return std::get<name_##_>(val); \
88 constexpr operator type_() const {\
91 constexpr type_ value() const {\
94 template <typename... T1>\
95 auto operator==(const std::tuple<T1...>& rhs ) const -> decltype( std::get<name_##_>(rhs) == name_ ){\
96 return std::get<name_##_>(rhs) == name_ ;\
98 friend inline std::string __get__name__(const name_##_&){ return name_str ;}\
99 friend inline std::string __get__name__and_type(const name_##_&){ return std::string(name_str) +"/"+ Belle2::group_helper::root_type_name(type_());}\
100 friend inline std::ostream& operator<<(std::ostream& out, const name_##_ & element ){ out << __get__name__(element) << ": "<< element.value() ; return out; }\
102 using name_ = name_##_impl_::name_##_
106 #define AXIS_NAME(name_, type_) AXIS_NAME1(name_, type_, #name_ )
109 namespace group_helper_imple__ {
112 template <
typename T >
113 static void print_name(std::ostream& out,
const T& tup)
115 if constexpr(N < std::tuple_size<T> ()) {
116 out <<
"| " << __get__name__(std::get<N>(tup)) <<
" ";
122 template <
typename T,
typename FUNC_T>
123 static void print(std::ostream& out,
const T& tup,
const FUNC_T& fun)
125 if constexpr(N < std::tuple_size<T> ()) {
126 out <<
"| " << fun(std::get<N>(tup)) <<
" ";
138 template <
typename... ARGS>
139 std::ostream&
operator<<(std::ostream& out,
const std::tuple<ARGS...>& tup)
145 template <
typename... ARGS>
146 std::ostream&
operator<<(std::ostream& out,
const std::vector<std::tuple<ARGS...>>& vec)
148 decltype(vec[0]) header{};
149 group_helper_imple__::print_s<0>::print_name(out, header);
151 for (
const auto& ele : vec) {
152 group_helper_imple__::print_s<0>::print(out, ele, [](
const auto & e) {
return e.value() ;});
162 template<
typename T,
typename... Ts>
163 constexpr
bool contains()
165 return std::disjunction_v<std::is_same<T, Ts>...>;
168 template <
typename T,
typename Tuple>
171 template <
typename T,
typename... Us>
172 struct has_type<T, std::tuple<Us...>> : std::disjunction<std::is_same<T, Us>...> {};
174 template <
typename>
struct is_tuple: std::false_type {};
176 template <
typename ...T>
struct is_tuple<std::tuple<T...>>: std::true_type {};
180 using _Remove_cvref_t = std::remove_cv_t<std::remove_reference_t<_Ty>>;
183 template <
typename FUNC_T>
184 auto fill_vector(
size_t entries, FUNC_T&& func)
186 std::vector< decltype(func(
size_t(0))) > ret ;
187 ret.reserve(entries);
188 for (
size_t i = 0; i < entries; ++i) {
189 ret.emplace_back(func(i));
196 constexpr T&& operator()(T&& t)
const noexcept
202 template <
typename T1,
typename T2,
typename Prj_T =
identity>
212 return m_end.m_prj(*(m_end.get_base() - 1));
222 auto operator[](
size_t i)
const
224 return m_begin.m_prj(*(m_begin.get_base() + i));
229 return m_end - m_begin;
232 begin_t(T1&& t1, Prj_T& pro) : T1(std::move(t1)), m_prj(pro) {}
233 begin_t(
const T1& t1, Prj_T& pro) : T1(t1), m_prj(pro) {}
235 auto operator*()
const
237 return m_prj(**((
const T1*)
this));
241 return *((
const T1*)
this);
248 template <
typename T1,
typename T2>
249 auto __range__(T1&& b, T2&& e)
253 template <
typename T1,
typename T2,
typename PRJ>
254 auto __range__(T1&& b, T2&& e, PRJ&& prj)
256 return __range__impl_prj< _Remove_cvref_t<T1>, _Remove_cvref_t<T2>, _Remove_cvref_t<PRJ> >(std::forward<T1>(b), std::forward<T2>(e),
257 std::forward<PRJ>(prj));
260 template <
typename PRJ,
typename VEC_T>
261 auto project(VEC_T&& vec)
263 return __range__(vec.begin(), vec.end(), [](
const auto & e) { return std::get<PRJ>(e); });
265 template <
typename VEC_T,
typename PRJ>
266 auto project(VEC_T&& vec, PRJ&& prj)
268 return __range__(vec.begin(), vec.end(), std::forward<PRJ>(prj));
272 template <
typename T1,
typename T2,
typename PRJ,
typename OP>
273 auto operator|(__range__impl_prj<T1, T2, PRJ> r, OP op)
275 return __range__(r.begin(), r.end(), std::move(op));
281 template <
typename T>
282 friend auto operator|(T&& t,
const to_range_&)
284 return __range__(t.begin(), t.end());
287 template <
typename T>
288 friend auto operator|(
const T& t,
const to_range_&)
290 return __range__(t.begin(), t.end());
301 template <
typename... T>
304 template <
typename VEC_T,
typename T1,
typename... T_rest>
305 static auto __isEequal(
const VEC_T& vecA,
const VEC_T& vecB)
307 if constexpr(
sizeof...(T_rest) > 0) {
308 if (std::get<T1>(vecA) != std::get<T1>(vecB)) {
311 return __isEequal< VEC_T, T_rest...>(vecA, vecB);
313 return std::get<T1>(vecA) == std::get<T1>(vecB);
317 template <
typename VEC_T,
typename T1,
typename... T_rest>
318 static auto __isLessthen(
const VEC_T& vecA,
const VEC_T& vecB)
320 if constexpr(
sizeof...(T_rest) > 0) {
321 if (std::get<T1>(vecA) < std::get<T1>(vecB)) {
323 }
else if (std::get<T1>(vecA) > std::get<T1>(vecB)) {
326 return __isLessthen< VEC_T, T_rest...>(vecA, vecB);
328 return std::get<T1>(vecA) < std::get<T1>(vecB);
334 template <
typename VEC_T,
typename... FUNC_T>
335 static auto __apply__list__(
const std::vector<VEC_T>& vec, FUNC_T&& ... fun)
338 auto is_sorted_ = std::is_sorted(std::begin(vec), std::end(vec), [](
const auto & lhs,
const auto & rhs) {
339 return group<T...>::__isLessthen<VEC_T, T...>(lhs, rhs);
343 throw std::runtime_error(
"group::apply expects the input vector to be sorted according to the group parameters\nthe input vector was not sorted with respect to the group axis");
347 std::vector< std::tuple<T..., decltype(fun(__range__(std::begin(vec), std::end(vec))))... >> ret;
351 auto tail = std::begin(vec);
353 for (
auto head = std::begin(vec); head != std::end(vec); ++head) {
356 ret.emplace_back(std::get<T>(*tail)..., fun(__range__(tail, head))...);
362 ret.emplace_back(std::get<T>(*tail)..., fun(__range__(tail, std::end(vec)))...);
366 template <
typename VEC_T,
typename FUNC_T>
367 static auto __apply__tuple__(
const std::vector<VEC_T>& vec, FUNC_T&& fun)
370 auto is_sorted_ = std::is_sorted(std::begin(vec), std::end(vec), [](
const auto & lhs,
const auto & rhs) {
371 return group<T...>::__isLessthen<VEC_T, T...>(lhs, rhs);
375 throw std::runtime_error(
"group::apply1 expects the input vector to be sorted according to the group parameters\nthe input vector was not sorted with respect to the group axis");
381 std::make_tuple(std::get<T>(*vec.begin())...),
382 fun(__range__(std::begin(vec), std::end(vec)))
389 auto tail = std::begin(vec);
391 for (
auto head = std::begin(vec); head != std::end(vec); ++head) {
396 std::make_tuple(std::get<T>(*tail)...),
397 fun(__range__(tail, head))
404 ret.push_back(tuple_cat(std::make_tuple(std::get<T>(*tail)...), fun(__range__(tail, std::end(vec)))));
408 template <
typename VEC_T,
typename FUNC_T>
409 static auto __apply__one_argument__(
const std::vector<VEC_T>& vec, FUNC_T&& fun)
411 if constexpr(
is_tuple< decltype(fun(__range__(std::begin(vec), std::end(vec))))>::value) {
412 return __apply__tuple__(vec, std::forward<FUNC_T>(fun));
414 return __apply__list__(vec, std::forward<FUNC_T>(fun));
419 template <
typename VEC_T,
typename... FUNC_T>
420 static auto apply(
const std::vector<VEC_T>& vec, FUNC_T&& ... fun)
422 if constexpr(
sizeof...(FUNC_T) > 1) {
423 return __apply__list__(vec, std::forward<FUNC_T>(fun)...);
426 return __apply__one_argument__(vec, std::forward<FUNC_T>(fun)...);
432 template <
typename CONTAINER_T,
typename FUNC_T>
433 void erase_remove_if(CONTAINER_T& container, FUNC_T&& fun)
436 std::remove_if(container.begin(), container.end(),
437 std::forward<FUNC_T>(fun)),
442 template <
typename CONTAINER_T>
443 void sort(CONTAINER_T& container)
445 std::sort(container.begin(), container.end());
448 template <
typename CONTAINER_T>
449 void drop_duplicates(CONTAINER_T& container)
451 container.erase(std::unique(container.begin(), container.end()), container.end());
456 template <
typename CONTAINER_T,
typename T1>
457 bool contains(
const CONTAINER_T& container, T1&& value)
459 return std::find(container.begin(), container.end(), value) != container.end();
463 template<
typename T1 =
int>
465 explicit greater(T1&& data) : m_data(data) {}
466 explicit greater(
const T1& data) : m_data(data) {}
470 constexpr
auto operator()(
const T1& u)
const
482 template <
typename CONTAINER_T,
typename OP_T = group_helper::greater<
int>>
486 for (
const auto& e : container)
493 template <
typename CONTAINER_T,
typename CONDITION_T>
494 auto get_first(
const CONTAINER_T& container,
const CONDITION_T& con)
497 for (
const auto& e : container) {
502 static decltype(container[0]) ret{};
511 namespace comparators {
520 template <
typename T1,
typename T2>
521 constexpr
static bool __comp__(T1&& t1, T2&& t2)
524 constexpr_for<0, std::tuple_size<_Remove_cvref_t<T1> >::value, 1>(
526 using N_th_T = _Remove_cvref_t < decltype(std::get<i>(t1))>;
527 if constexpr(
has_type<N_th_T, _Remove_cvref_t<T2>>::value) {
528 ret &= (std::get<N_th_T>(t1) == std::get<N_th_T>(t2));
537 template <
typename T1,
typename T2>
538 constexpr
bool operator()(T1&& t1, T2&& t2)
const
540 return __comp__(std::forward<T1>(t1), std::forward<T2>(t2));
547 template <
typename T0,
typename T1,
typename T2,
typename Comparision_T,
typename projecttion_t >
548 void vec_join_r(T0& ret,
const T1& t1,
const T2& t2, Comparision_T comp, projecttion_t project)
551 for (
const auto& e1 : t1) {
552 for (
const auto& e2 : t2) {
554 ret.push_back(project(e1, e2));
561 template <
typename T1,
typename T2,
typename Comparision_T,
typename projecttion_t >
562 auto vec_join(
const T1& t1,
const T2& t2, Comparision_T comp, projecttion_t project)
564 std::vector< decltype(project(t1[0], t2[0])) > ret;
565 vec_join_r(ret, t1, t2, comp, project);
std::ostream & operator<<(std::ostream &output, const IntervalOfValidity &iov)
Abstract base class for different kinds of events.