10#include <tracking/trackFindingCDC/utilities/EvalVariadic.h>
24 namespace TrackFindingCDC {
32 template<
class... ATypes>
48 friend std::ostream&
operator<<(std::ostream& output,
const Box<>& voidBox __attribute__((unused)))
61 template<
class AFirstType,
class... ASubordinaryTypes>
62 class Box<AFirstType, ASubordinaryTypes...> {
65 using FirstType = AFirstType;
68 using This = Box<AFirstType, ASubordinaryTypes...>;
71 using Point = std::tuple<FirstType, ASubordinaryTypes...>;
74 using Delta = std::tuple <
decltype(FirstType() - FirstType()),
75 decltype(ASubordinaryTypes() - ASubordinaryTypes())... >;
78 template<std::
size_t I>
79 using Type =
typename std::tuple_element<I, Point>::type;
83 using TypeIndex = GetIndexInTuple<T, Point>;
87 using HasType = TypeInTuple<T, Point>;
90 template<std::
size_t I>
91 using Width =
typename std::tuple_element<I, Delta>::type;
94 static const size_t c_nTypes = std::tuple_size<Point>::value;
97 using Indices = std::make_index_sequence<c_nTypes>;
100 Box(
const std::array<FirstType, 2>& firstBound,
101 const std::array<ASubordinaryTypes, 2>& ... subordinaryBounds)
102 : m_firstBounds{
std::min(firstBound[0], firstBound[1]),
103 std::max(firstBound[1], firstBound[0])}
104 , m_subordinaryBox(subordinaryBounds...)
109 friend std::ostream& operator<<(std::ostream& output,
const This& box)
112 "Range from " << box.m_firstBounds[0] <<
113 " to " << box.m_firstBounds[1] << std::endl <<
114 box.getSubordinaryBox();
118 void setBounds(std::array<FirstType, 2> firstBounds,
119 std::array<ASubordinaryTypes, 2>... subordinaryBounds)
121 m_firstBounds[0] = std::min(firstBounds[0], firstBounds[1]);
122 m_firstBounds[1] = std::max(firstBounds[0], firstBounds[1]);
123 m_subordinaryBox.setBounds(subordinaryBounds...);
127 const Box<ASubordinaryTypes...>& getSubordinaryBox()
const
129 return m_subordinaryBox;
133 template<std::
size_t I>
134 const std::enable_if_t<I == 0, Type<I> >& getLowerBound()
const
136 return m_firstBounds[0];
140 template<std::
size_t I>
141 const std::enable_if_t < I != 0, Type<I> > & getLowerBound()
const
143 static_assert(I < c_nTypes,
144 "Accessed index exceeds number of coordinates");
145 return m_subordinaryBox.template getLowerBound < I - 1 > ();
150 const std::enable_if_t<HasType<T>::value, T>& getLowerBound()
const
152 return getLowerBound<TypeIndex<T>::value>();
156 template <std::
size_t I>
157 const std::enable_if_t<I == 0, Type<I>>& getUpperBound()
const
159 return m_firstBounds[1];
163 template<std::
size_t I>
164 const std::enable_if_t < I != 0, Type<I> > & getUpperBound()
const
166 static_assert(I < c_nTypes,
167 "Accessed index exceeds number of coordinates");
168 return m_subordinaryBox.template getUpperBound < I - 1 > ();
173 const std::enable_if_t<HasType<T>::value, T>& getUpperBound()
const
175 return getUpperBound<TypeIndex<T>::value>();
179 template <std::
size_t I>
180 const std::enable_if_t<I == 0, std::array<Type<I>, 2>>& getBounds()
const
182 return m_firstBounds;
186 template <std::
size_t I>
187 const std::enable_if_t < I != 0, std::array<Type<I>, 2 >>& getBounds()
const
189 static_assert(I < c_nTypes,
"Accessed index exceeds number of coordinates");
190 return m_subordinaryBox.template getBounds < I - 1 > ();
195 const std::enable_if_t<HasType<T>::value, std::array<T, 2>>& getBounds()
const
197 return getBounds<TypeIndex<T>::value>();
201 template <std::
size_t I>
202 Width<I> getWidth()
const
204 return getUpperBound<I>() - getLowerBound<I>();
209 template<std::
size_t I>
210 Type<I> getDivision(
size_t nDivisions,
size_t iDivision)
const
212 assert(nDivisions >= iDivision);
213 return Type<I>(getLowerBound<I>() + getWidth<I>() * iDivision / nDivisions);
217 template<std::
size_t I>
218 std::array<Type<I>, 2 >
219 getDivisionBounds(
size_t nDivisions,
size_t iDivision)
const
221 assert(nDivisions > iDivision);
222 return {{getDivision<I>(nDivisions, iDivision), getDivision<I>(nDivisions, iDivision + 1)}};
226 template <std::
size_t I>
227 Width<I> getDivisionWidthWithOverlap(
const Width<I>& overlap,
size_t nDivisions)
const
229 return (getWidth<I>() + (nDivisions - 1) * overlap) / nDivisions;
245 template<std::
size_t I>
247 getLowerDivisionBoundWithOverlap(
const Width<I>& overlap,
249 size_t iDivision)
const
251 assert(nDivisions >= iDivision);
252 return Type<I>(getLowerBound<I>() + (getWidth<I>() - overlap) * iDivision / nDivisions);
268 template<std::
size_t I>
270 getUpperDivisionBoundWithOverlap(
const Width<I>& overlap,
272 size_t iDivision)
const
274 assert(nDivisions >= iDivision);
275 return Type<I>(getUpperBound<I>() - (getWidth<I>() - overlap) * (nDivisions - iDivision - 1) / nDivisions);
292 template<std::
size_t I>
293 std::array<Type<I>, 2 >
294 getDivisionBoundsWithOverlap(
const Width<I>& overlap,
296 size_t iDivision)
const
298 assert(nDivisions > iDivision);
300 getLowerDivisionBoundWithOverlap<I>(overlap, nDivisions, iDivision),
301 getUpperDivisionBoundWithOverlap<I>(overlap, nDivisions, iDivision)
306 template <std::
size_t I>
307 Type<I> getCenter()
const
309 return getDivision<I>(2, 1);
313 template <std::
size_t I>
314 std::array<Type<I>, 2> getLowerHalfBounds()
const
316 return getDivisionBounds(2, 0);
320 template <std::
size_t I>
321 std::array<Type<I>, 2> getUpperHalfBounds()
const
323 return getDivisionBounds(2, 1);
327 template <std::
size_t I,
class ASubordinaryValue>
328 bool isIn(
const ASubordinaryValue& value)
const
330 return getLowerBound<I>() < value and not(getUpperBound<I>() < value);
335 static bool any(
const std::initializer_list<bool>& booleans)
337 return std::accumulate(std::begin(booleans), std::end(booleans),
338 false, [](
const bool & lhs,
const bool & rhs) {
return lhs or rhs;});
343 static bool all(
const std::initializer_list<bool>& booleans)
345 return std::accumulate(std::begin(booleans), std::end(booleans),
346 true, [](
const bool & lhs,
const bool & rhs) {
return lhs and rhs;});
358 template <
size_t... Is>
359 bool intersectsImpl(
const This& box,
360 std::index_sequence<Is...> is __attribute__((unused)))
const
362 return not(any({box.getUpperBound<Is>() < this->getLowerBound<Is>()... }) or
363 any({this->getUpperBound<Is>() < box.getLowerBound<Is>()... }));
370 template <
size_t... Is>
371 bool isInImpl(
const Point& point,
372 std::index_sequence<Is...> is __attribute__((unused)))
const
374 return not all({isIn<Is>(std::get<Is>(point))...});
379 bool intersects(
const This& box)
const
381 return intersectsImpl(box, Indices());
385 bool isIn(
const Point& point)
const
387 return isInImpl(point, Indices());
391 bool isIn(
const FirstType& value,
const ASubordinaryTypes& ... values)
const
393 return isInImpl(Point(value, values...), Indices());
398 std::array<FirstType, 2> m_firstBounds;
401 Box<ASubordinaryTypes... > m_subordinaryBox;
Box Base class specification without any template arguments.
friend std::ostream & operator<<(std::ostream &output, const Box<> &voidBox)
Nothing to do on printing.
void setBounds()
Nothing to do on set bounds.
The base class for all boxes.
Abstract base class for different kinds of events.