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...> {
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)
102 : m_firstBounds{
std::min(firstBound[0], firstBound[1]),
103 std::max(firstBound[1], firstBound[0])}
104 , m_subordinaryBox(subordinaryBounds...)
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...);
129 return m_subordinaryBox;
133 template<std::
size_t I>
136 return m_firstBounds[0];
140 template<std::
size_t I>
143 static_assert(I < c_nTypes,
144 "Accessed index exceeds number of coordinates");
145 return m_subordinaryBox.template getLowerBound < I - 1 > ();
152 return getLowerBound<TypeIndex<T>::value>();
156 template <std::
size_t I>
159 return m_firstBounds[1];
163 template<std::
size_t I>
166 static_assert(I < c_nTypes,
167 "Accessed index exceeds number of coordinates");
168 return m_subordinaryBox.template getUpperBound < I - 1 > ();
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>
204 return getUpperBound<I>() - getLowerBound<I>();
209 template<std::
size_t I>
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 >
221 assert(nDivisions > iDivision);
222 return {{getDivision<I>(nDivisions, iDivision), getDivision<I>(nDivisions, iDivision + 1)}};
226 template <std::
size_t I>
229 return (getWidth<I>() + (nDivisions - 1) * overlap) / nDivisions;
245 template<std::
size_t I>
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>
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 >
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>
309 return getDivision<I>(2, 1);
313 template <std::
size_t I>
316 return getDivisionBounds(2, 0);
320 template <std::
size_t I>
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>
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>
372 std::index_sequence<Is...> is __attribute__((unused)))
const
374 return not all({isIn<Is>(std::get<Is>(point))...});
381 return intersectsImpl(box,
Indices());
387 return isInImpl(point,
Indices());
391 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...
AFirstType FirstType
Type of the first coordinate.
std::array< Type< I >, 2 > getDivisionBounds(size_t nDivisions, size_t iDivision) const
Get the lower partition in the coordinate I.
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.
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.
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.
bool intersectsImpl(const This &box, std::index_sequence< Is... > is) const
Indicates if this box intersects with the other box.
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< HasType< T >::value, T > & getUpperBound() const
Get the upper bound of the box by the type of the coordinate.
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.
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.
Type< I > getCenter() const
Get the center of the box in the coordinate I.
bool isIn(const ASubordinaryValue &value) const
Indicate if the given value is in the range of 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.
const std::enable_if_t< I==0, Type< I > > & getUpperBound() const
Get the upper bound of the box in the coordinate I.
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 coordinate.
const Box< ASubordinaryTypes... > & getSubordinaryBox() const
Getter for the box in excluding the first coordinate.
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.
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.
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.
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.
Width< I > getDivisionWidthWithOverlap(const Width< I > &overlap, size_t nDivisions) const
Get for the distance between two division bounds with overlap.
Box(const std::array< FirstType, 2 > &firstBound, const std::array< ASubordinaryTypes, 2 > &... subordinaryBounds)
Initialise the box with bound in each dimension.
std::array< Type< I >, 2 > getLowerHalfBounds() const
Get the lower partition in the coordinate I.
bool isIn(const FirstType &value, const ASubordinaryTypes &... values) const
Indicate if all given values are in the range of their coordinates.
Box< ASubordinaryTypes... > m_subordinaryBox
Box in the other coordinate.
void setBounds(std::array< FirstType, 2 > firstBounds, std::array< ASubordinaryTypes, 2 >... subordinaryBounds)
Set bounds of the box to new values.
typename std::tuple_element< I, Point >::type Type
Accessor for the individual coordinate types.
std::array< Type< I >, 2 > getUpperHalfBounds() const
Get the upper partition in the coordinate I.
Width< I > getWidth() const
Get the difference of upper and lower bound.
const std::enable_if_t< HasType< T >::value, T > & getLowerBound() const
Get the lower bound of the box by the type of the 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 intersects(const This &box) const
Indicates if this box intersects with the other box.
friend std::ostream & operator<<(std::ostream &output, const This &box)
Output operator for debugging.
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 std::enable_if_t< I==0, Type< I > > & getLowerBound() const
Get the lower bound of the box in the coordinate I - first coordinate case.
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.
Looks up, at which index the given Type can be found in a tuple.