10#include <tracking/trackFindingCDC/utilities/FunctorTag.h>
22 namespace TrackFindingCDC {
33 return std::forward<T>(t);
66 template<class T, class SFINAE = std::enable_if_t<not isFunctor<T>()> >
67 constexpr Constant<T> toFunctor(
const T& t)
69 return Constant<T> {t};
73 template<class AFunctor, class SFINAE = std::enable_if_t<isFunctor<AFunctor>()> >
74 constexpr const AFunctor & toFunctor(
const AFunctor& get)
81 using ToFunctor =
typename std::decay<decltype(toFunctor(std::declval<T>()))>::type;
86 template <
class AFunctor1,
class AFunctor2>
126 template <
class ABinaryOp,
class AFunctor1,
class AFunctor2 = AFunctor1>
136 BinaryJoin(
const ABinaryOp& binaryOp,
const AFunctor1& functor1,
const AFunctor2& functor2)
145 BinaryJoin(
const AFunctor1& functor1,
const AFunctor2& functor2)
164 template <
class T1,
class T2>
179 template <
class AFunctor1,
class AFunctor2>
198 explicit Alternation(
const AFunctor1& functor1,
const AFunctor2& functor2 = AFunctor2())
206 template <
class... T>
207 auto impl(
int favouredTag __attribute__((unused)), T&& ... t)
const
208 ->
decltype(
m_functor1(std::forward<T>(t)...))
214 template <
class... T>
215 auto impl(
long disfavouredTag __attribute__((unused)), T&& ... t)
const
216 ->
decltype(
m_functor2(std::forward<T>(t)...))
223 template <
class... T>
224 auto operator()(T&& ... t)
const ->
decltype(this->
impl(0, std::forward<T>(t)...))
227 return impl(dispatchTag, std::forward<T>(t)...);
247 template <
class AFunctor = Id>
248 using VoidOf = Composition<Void, AFunctor>;
251 template <
class AFunctor>
252 using IfApplicable = Alternation<AFunctor, Void>;
255 template<
class AFunction,
class... T>
256 void invokeIfApplicable(AFunction&& function, T&& ... t)
258 IfApplicable<AFunction> invokeIfApplicableImpl(std::forward<AFunction>(function));
259 invokeIfApplicableImpl(std::forward<T>(t)...);
263 template<
class ADefault,
class AFunctor,
class T>
264 ADefault getIfApplicable(AFunctor&& function, T&& obj, ADefault value)
266 Alternation<AFunctor, Constant<ADefault> > getIfApplicableImpl{std::forward<AFunctor>(function), Constant(value) };
267 return getIfApplicableImpl(std::forward<T>(obj));
281 auto operator()(
const T& t)
const ->
decltype(std::get<I>(t))
289 template <
int I,
class AFunctor = Id>
290 using GetOf = Composition<Get<I>, AFunctor>;
297 using First = Get<0>;
300 template<
class AFunctor = Id>
301 using FirstOf = GetOf<0, AFunctor>;
308 using Second = Get<1>;
311 template<
class AFunctor = Id>
312 using SecondOf = GetOf<1, AFunctor>;
331 template <
class AFunctor = Id>
332 using SizeOf = Composition<Size, AFunctor>;
351 template <
class AFunctor = Id>
352 using ClearOf = Composition<Clear, AFunctor>;
355 using ClearIfApplicable = IfApplicable<Clear>;
358 static const ClearIfApplicable clearIfApplicable{};
376 template <
class AFunctor = Id>
377 using NotOf = Composition<Not, AFunctor>;
380 template <class AFunctor, class SFINAE = std::enable_if_t<isFunctor<AFunctor>()> >
381 NotOf<AFunctor> operator!(
const AFunctor& functor)
383 return NotOf<AFunctor> {functor};
405 assert(t !=
nullptr);
411 template <
class AFunctor = Id>
412 using DerefOf = Composition<Deref, AFunctor>;
415 template <
class AFunctor = Id>
416 using DerefTo = Composition<AFunctor, Deref>;
427 auto operator()(
const T& t)
const ->
decltype(*(t.operator->()))
429 assert(t.operator->() !=
nullptr);
430 return *(t.operator->());
437 assert(t !=
nullptr);
443 template <
class AFunctor = Id>
444 using IndirectOf = Composition<Indirect, AFunctor>;
447 template <
class AFunctor = Id>
448 using IndirectTo = Composition<AFunctor, Indirect>;
454 template <
class AFunctor>
455 using MayIndirectTo = Alternation<IndirectTo<AFunctor>, AFunctor>;
466 template<
class T1,
class T2>
467 auto operator()(
const T1& t1,
const T2& t2)
const ->
decltype(t1 < t2)
474 template <
class AFunctor1 = Id,
class AFunctor2 = AFunctor1>
475 using LessOf = BinaryJoin<Less, AFunctor1, AFunctor2>;
478 template <class ALHS, class ARHS, class SFINAE = std::enable_if_t<isFunctor<ALHS>() or isFunctor<ARHS>()>>
479 LessOf<ToFunctor<ALHS>, ToFunctor<ARHS> > operator<(const ALHS& lhs, const ARHS& rhs)
481 return {toFunctor(lhs), toFunctor(rhs)};
494 template<
class T1,
class T2>
495 auto operator()(
const T1& t1,
const T2& t2)
const ->
decltype(t1 > t2)
502 template <
class AFunctor1 = Id,
class AFunctor2 = AFunctor1>
503 using GreaterOf = BinaryJoin<Greater, AFunctor1, AFunctor2>;
506 template <class ALHS, class ARHS, class SFINAE = std::enable_if_t<isFunctor<ALHS>() or isFunctor<ARHS>()>>
507 GreaterOf<ToFunctor<ALHS>, ToFunctor<ARHS> > operator>(const ALHS& lhs, const ARHS& rhs)
509 return {toFunctor(lhs), toFunctor(rhs)};
520 template<
class T1,
class T2>
521 auto operator()(
const T1& t1,
const T2& t2)
const ->
decltype(t1 == t2)
528 template <
class AFunctor1 = Id,
class AFunctor2 = AFunctor1>
529 using EqualOf = BinaryJoin<Equal, AFunctor1, AFunctor2>;
532 template <class ALHS, class ARHS, class SFINAE = std::enable_if_t<isFunctor<ALHS>() or isFunctor<ARHS>()>>
533 EqualOf<ToFunctor<ALHS>, ToFunctor<ARHS> > operator==(const ALHS& lhs, const ARHS& rhs)
535 return {toFunctor(lhs), toFunctor(rhs)};
547 return std::isnan(t);
Abstract base class for different kinds of events.
Generic functor to try to functors and choose the first to be applicable.
auto operator()(T &&... t) const -> decltype(this->impl(0, std::forward< T >(t)...))
Operator to dispatch to the two functors and returns the first applicable option.
Alternation()=default
Allow default construction.
AFunctor2 m_functor2
Memory for the second nested functor.
Alternation(const AFunctor1 &functor1, const AFunctor2 &functor2=AFunctor2())
Constructor from the nested functors.
AFunctor1 m_functor1
Memory for the first nested functor.
auto impl(long disfavouredTag, T &&... t) const -> decltype(m_functor2(std::forward< T >(t)...))
Implementation applying the second functor. Disfavoured option.
auto impl(int favouredTag, T &&... t) const -> decltype(m_functor1(std::forward< T >(t)...))
Implementation applying the first functor. Favoured option.
Functor factory turning a binary functor and two functors into a new functor which executes the binar...
auto operator()(const T &t) const -> decltype(m_binaryOp(m_functor1(t), m_functor2(t)))
Operator getting the result of the binary operation from one object transformed by the two functors.
BinaryJoin(const ABinaryOp &binaryOp, const AFunctor1 &functor1, const AFunctor2 &functor2)
Constructor from the nested functors.
BinaryJoin(const AFunctor1 &functor1, const AFunctor2 &functor2)
Constructor from the nested functors.
AFunctor2 m_functor2
Memory for the second nested functor.
BinaryJoin()=default
Allow default construction.
ABinaryOp m_binaryOp
Memory for the binary operation.
AFunctor1 m_functor1
Memory for the first nested functor.
auto operator()(const T1 &t1, const T2 &t2) const -> decltype(m_binaryOp(m_functor1(t1), m_functor2(t2)))
Operator getting the result of the binary operation from two objects transformed by the two functors.
Functor to get the .clear() from an arbitrary objects.
auto operator()(T &t) const -> decltype(t.clear())
Operator getting the .clear() of an arbitrary object.
Functor factory from the functional composition of two functors.
auto operator()(const T &t) const -> decltype(m_functor1(m_functor2(t)))
Operator getting the result of the function composition.
Composition(const AFunctor2 &functor2)
Constructor from the nested functor.
Composition()=default
Allow default construction.
AFunctor2 m_functor2
Memory for the nested functor.
AFunctor1 m_functor1
Memory for the nested functor.
Composition(const AFunctor1 &functor1, const AFunctor2 &functor2)
Constructor from the first and the nested functor.
Generic functor to wrap a constant as a function.
T m_t
Memory for the constant to be returned.
Constant(const T &t)
Constructor from the constant value.
constexpr const T & operator()(const S &) const
Operator returning the constant.
Functor to get the referenced object from an arbitrary objects.
auto operator()(const T &t) const -> decltype(*t)
Operator getting the referenced object of an arbitrary object.
auto operator()(const T *t) const -> decltype(*t)
Specialisation for pointers to make an assertion that no nullptr is dereferenced.
Binary functor for equality comparison of arbitrary objects - equivalent to std::equal_to<> (c++14)
auto operator()(const T1 &t1, const T2 &t2) const -> decltype(t1==t2)
Operator for equality comparison of an arbitrary object.
Tag class to facilitate marking of class as a functor in the sense of this code.
Functor to get the I part (as of std::get<I>) from an arbitrary objects.
auto operator()(const T &t) const -> decltype(std::get< I >(t))
Operator getting the I part (as of std::get<I>) of an arbitrary object.
Binary functor for greater comparison of arbitrary objects - equivalent to std::greater<> (c++14)
auto operator()(const T1 &t1, const T2 &t2) const -> decltype(t1 > t2)
Operator for greater comparison of an arbitrary object.
Generic identity functor.
T && operator()(T &&t) const
Operator that just returns the object itself - gets me.
Functor to get the indirection from an arbitrary objects.
const T & operator()(const T *t) const
Specialisation for pointers that indirect to themselves.
auto operator()(const T &t) const -> decltype(*(t.operator->()))
Operator getting the indirection of an arbitrary object.
Unary functor for equality comparison to NAN.
bool operator()(const T &t) const
Operator for equality comparison to NaN.
Binary functor for less comparison of arbitrary objects - equivalent to std::less<> (c++14)
auto operator()(const T1 &t1, const T2 &t2) const -> decltype(t1< t2)
Operator for less comparison of an arbitrary object.
Functor to get the logical negation from an arbitrary objects.
auto operator()(const T &t) const -> decltype(not t)
Operator getting the logical negation of an arbitrary object.
Functor to get the .size() from an arbitrary objects.
auto operator()(const T &t) const -> decltype(t.size())
Operator getting the .size() of an arbitrary object.
Functor returning void from an arbitrary objects.
void operator()(T &&t) const
Operator always returning void.