10 #include <tracking/trackFindingCDC/utilities/EvalVariadic.h>
12 #include <type_traits>
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...> {
68 using This =
Box<AFirstType, ASubordinaryTypes...>;
75 decltype(ASubordinaryTypes() - ASubordinaryTypes())... >;
78 template<std::
size_t I>
79 using Type =
typename std::tuple_element<I, Point>::type;
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)
103 std::min(firstBound[0], firstBound[1]),
104 std::max(firstBound[1], firstBound[0])}}
105 , m_subordinaryBox(subordinaryBounds...)
120 std::array<ASubordinaryTypes, 2>... subordinaryBounds)
122 m_firstBounds[0] = std::min(firstBounds[0], firstBounds[1]);
123 m_firstBounds[1] = std::max(firstBounds[0], firstBounds[1]);
124 m_subordinaryBox.setBounds(subordinaryBounds...);
130 return m_subordinaryBox;
134 template<std::
size_t I>
137 return m_firstBounds[0];
141 template<std::
size_t I>
144 static_assert(I < c_nTypes,
145 "Accessed index exceeds number of coordinates");
146 return m_subordinaryBox.template getLowerBound < I - 1 > ();
153 return getLowerBound<TypeIndex<T>::value>();
157 template <std::
size_t I>
160 return m_firstBounds[1];
164 template<std::
size_t I>
167 static_assert(I < c_nTypes,
168 "Accessed index exceeds number of coordinates");
169 return m_subordinaryBox.template getUpperBound < I - 1 > ();
176 return getUpperBound<TypeIndex<T>::value>();
180 template <std::
size_t I>
181 const std::enable_if_t<I == 0, std::array<Type<I>, 2>>&
getBounds()
const
183 return m_firstBounds;
187 template <std::
size_t I>
188 const std::enable_if_t < I != 0, std::array<Type<I>, 2 >>&
getBounds()
const
190 static_assert(I < c_nTypes,
"Accessed index exceeds number of coordinates");
191 return m_subordinaryBox.template getBounds < I - 1 > ();
196 const std::enable_if_t<HasType<T>::value, std::array<T, 2>>&
getBounds()
const
198 return getBounds<TypeIndex<T>::value>();
202 template <std::
size_t I>
205 return getUpperBound<I>() - getLowerBound<I>();
210 template<std::
size_t I>
213 assert(nDivisions >= iDivision);
214 return Type<I>(getLowerBound<I>() + getWidth<I>() * iDivision / nDivisions);
218 template<std::
size_t I>
219 std::array<Type<I>, 2 >
222 assert(nDivisions > iDivision);
223 return {{getDivision<I>(nDivisions, iDivision), getDivision<I>(nDivisions, iDivision + 1)}};
227 template <std::
size_t I>
230 return (getWidth<I>() + (nDivisions - 1) * overlap) / nDivisions;
246 template<std::
size_t I>
250 size_t iDivision)
const
252 assert(nDivisions >= iDivision);
253 return Type<I>(getLowerBound<I>() + (getWidth<I>() - overlap) * iDivision / nDivisions);
269 template<std::
size_t I>
273 size_t iDivision)
const
275 assert(nDivisions >= iDivision);
276 return Type<I>(getUpperBound<I>() - (getWidth<I>() - overlap) * (nDivisions - iDivision - 1) / nDivisions);
293 template<std::
size_t I>
294 std::array<Type<I>, 2 >
297 size_t iDivision)
const
299 assert(nDivisions > iDivision);
301 getLowerDivisionBoundWithOverlap<I>(overlap, nDivisions, iDivision),
302 getUpperDivisionBoundWithOverlap<I>(overlap, nDivisions, iDivision)
307 template <std::
size_t I>
310 return getDivision<I>(2, 1);
314 template <std::
size_t I>
317 return getDivisionBounds(2, 0);
321 template <std::
size_t I>
324 return getDivisionBounds(2, 1);
328 template <std::
size_t I,
class ASubordinaryValue>
329 bool isIn(
const ASubordinaryValue& value)
const
331 return getLowerBound<I>() < value and not(getUpperBound<I>() < value);
336 static bool any(
const std::initializer_list<bool>& booleans)
338 return std::accumulate(std::begin(booleans), std::end(booleans),
339 false, [](
const bool & lhs,
const bool & rhs) {
return lhs or rhs;});
344 static bool all(
const std::initializer_list<bool>& booleans)
346 return std::accumulate(std::begin(booleans), std::end(booleans),
347 true, [](
const bool & lhs,
const bool & rhs) {
return lhs and rhs;});
359 template <
size_t... Is>
361 std::index_sequence<Is...> is __attribute__((unused)))
const
363 return not(any({box.
getUpperBound<Is>() < this->getLowerBound<Is>()... }) or
364 any({this->getUpperBound<Is>() < box.
getLowerBound<Is>()... }));
371 template <
size_t... Is>
373 std::index_sequence<Is...> is __attribute__((unused)))
const
375 return not all({isIn<Is>(std::get<Is>(point))...});
382 return intersectsImpl(box,
Indices());
388 return isInImpl(point,
Indices());
392 bool isIn(
const FirstType& value,
const ASubordinaryTypes& ... values)
const
Box Base class specification without a first and subordinary types which can be used to "stack" vario...
const std::enable_if_t< I !=0, std::array< Type< I >, 2 > > & getBounds() const
Get the bounds of the box in the coordinate I - subordinary coordinate case.
AFirstType FirstType
Type of the first coordinate.
std::array< Type< I >, 2 > getDivisionBoundsWithOverlap(const Width< I > &overlap, size_t nDivisions, size_t iDivision) const
Getter for the both bounds of a subbox along the Ith axes in an equal spaced division with overlap.
const Box< ASubordinaryTypes... > & getSubordinaryBox() const
Getter for the box in excluding the first coordinate.
Type< I > getLowerDivisionBoundWithOverlap(const Width< I > &overlap, size_t nDivisions, size_t iDivision) const
Getter for the lower bound of a subbox along the Ith axes in an equal spaced division with overlap.
bool intersectsImpl(const This &box, std::index_sequence< Is... > is) const
Indicates if this box intersects with the other box.
const std::enable_if_t< HasType< T >::value, std::array< T, 2 > > & getBounds() const
Get the bounds of the box by the type of the coordinate.
TypeInTuple< T, Point > HasType
Check if the type is a coordinate of the box which amounts to a std::integral_constant.
const std::enable_if_t< I !=0, Type< I > > & getLowerBound() const
Get the lower bound of the box in the coordinate I - subordinary coordinate case.
bool isIn(const ASubordinaryValue &value) const
Indicate if the given value is in the range of the coordinate I.
Type< I > getDivision(size_t nDivisions, size_t iDivision) const
Get for break point in the range of coordinate I out of nDivsions equal spaced points.
const std::enable_if_t< I==0, std::array< Type< I >, 2 > > & getBounds() const
Get the bounds of the box in the coordinate I - first coordinate case.
const std::enable_if_t< I==0, Type< I > > & getUpperBound() const
Get the upper bound of the box in the coordinate I.
typename std::tuple_element< I, Delta >::type Width
Accessor for the individual coordinate difference types.
static bool all(const std::initializer_list< bool > &booleans)
Indicates if all of the boolean values are true.
std::tuple< decltype(FirstType() - FirstType()), decltype(ASubordinaryTypes() - ASubordinaryTypes())... > Delta
Tuple of differencs in each coordinate.
std::array< FirstType, 2 > m_firstBounds
Bound in the first coordindate.
std::array< Type< I >, 2 > getUpperHalfBounds() const
Get the upper partition in the coordinate I.
Type< I > getUpperDivisionBoundWithOverlap(const Width< I > &overlap, size_t nDivisions, size_t iDivision) const
Getter for the upper bound of a subbox along the Ith axes in an equal spaced division with overlap.
bool isIn(const Point &point) const
Indicate if all given values are in the range of their coordinates.
static bool any(const std::initializer_list< bool > &booleans)
Indicates if any of the boolean values is true.
std::make_index_sequence< c_nTypes > Indices
Helper class to iterate over the individual coordinates.
Width< I > getWidth() const
Get the difference of upper and lower bound.
bool isInImpl(const Point &point, std::index_sequence< Is... > is) const
Indicate if all given values are in the range of their coordinates.
std::tuple< FirstType, ASubordinaryTypes... > Point
Tuple of the types of each coordinates.
Box(const std::array< FirstType, 2 > &firstBound, const std::array< ASubordinaryTypes, 2 > &... subordinaryBounds)
Initialise the box with bound in each dimension.
bool isIn(const FirstType &value, const ASubordinaryTypes &... values) const
Indicate if all given values are in the range of their coordinates.
const std::enable_if_t< I !=0, Type< I > > & getUpperBound() const
Get the lower bound of the box in the coordinate I - subordinary coordinate case.
Box< ASubordinaryTypes... > m_subordinaryBox
Box in the other coordinate.
const std::enable_if_t< HasType< T >::value, T > & getLowerBound() const
Get the lower bound of the box by the type of the coordinate.
const std::enable_if_t< I==0, Type< I > > & getLowerBound() const
Get the lower bound of the box in the coordinate I - first coordinate case.
void setBounds(std::array< FirstType, 2 > firstBounds, std::array< ASubordinaryTypes, 2 >... subordinaryBounds)
Set bounds of the box to new values.
friend std::ostream & operator<<(std::ostream &output, const This &box)
Output operator for debugging.
typename std::tuple_element< I, Point >::type Type
Accessor for the individual coordinate types.
Width< I > getDivisionWidthWithOverlap(const Width< I > &overlap, size_t nDivisions) const
Get for the distance between two division bounds with overlap.
std::array< Type< I >, 2 > getDivisionBounds(size_t nDivisions, size_t iDivision) const
Get the lower partition in the coordinate I.
bool intersects(const This &box) const
Indicates if this box intersects with the other box.
std::array< Type< I >, 2 > getLowerHalfBounds() const
Get the lower partition in the coordinate I.
Type< I > getCenter() const
Get the center of the box in the coordinate I.
const std::enable_if_t< HasType< T >::value, T > & getUpperBound() const
Get the upper bound of the box by the type of the coordinate.
Box Base class specification without any template arguments.
void setBounds()
Nothing to do on set bounds.
friend std::ostream & operator<<(std::ostream &output, const Box<> &voidBox)
Nothing to do on printing.
The base class for all boxes.
Abstract base class for different kinds of events.
Looks up, at which index the given Type can be found in a tuple.