10 #ifndef INCLUDE_MOLASSEMBLER_TEMPLE_CONSTEXPR_CONTAINERS_H
11 #define INCLUDE_MOLASSEMBLER_TEMPLE_CONSTEXPR_CONTAINERS_H
20 namespace Molassembler {
25 template<
class Function,
typename ...Args>
34 template<
typename, std::
size_t>
class ArrayType,
39 > constexpr
auto mapImpl(
40 const ArrayType<T, size>& array,
41 UnaryFunction&&
function,
42 std::index_sequence<Inds...>
48 function(array.at(Inds))...
59 template<
typename, std::
size_t>
class ArrayType,
64 const ArrayType<T, size>& array,
65 UnaryFunction&&
function
67 return Detail::mapImpl(
69 std::forward<UnaryFunction>(
function),
70 std::make_index_sequence<size>{}
85 template<
typename, std::
size_t>
class ArrayType,
90 const ArrayType<T, size>& array,
92 BinaryFunction&& reduction
94 for(
const auto&
element : array) {
95 init = reduction(init,
element);
109 template<
typename, std::
size_t>
class ArrayType,
112 > constexpr T
sum(
const ArrayType<T, size>& array) {
115 for(
unsigned i = 0; i < size; ++i) {
126 template<
typename, std::
size_t>
class ArrayType,
130 > constexpr ArrayType<T, size> iotaHelper(
131 std::index_sequence<Inds...>
133 return ArrayType<T, size> {
static_cast<T
>(Inds)... };
140 template<
typename, std::
size_t>
class ArrayType,
144 std::is_arithmetic<T>::value,
147 return Detail::iotaHelper<ArrayType, T, size>(
148 std::make_index_sequence<size>()
155 template<
typename, std::
size_t>
class ArrayType,
160 > constexpr ArrayType<T, (end - begin)> rangeHelper(
161 std::index_sequence<Inds...>
163 return ArrayType<T, (end - begin)> {
172 template<
typename, std::
size_t>
class ArrayType,
176 > constexpr ArrayType<T, (end - begin)>
range() {
177 return Detail::rangeHelper<ArrayType, T, begin, end>(
178 std::make_index_sequence<(end - begin)>()
186 template<
typename, std::
size_t>
class ArrayType,
189 std::size_t... AIndices,
191 std::size_t... BIndices
193 constexpr ArrayType<T, N1+N2> arrayConcatenateImpl(
194 const ArrayType<T, N1>& a,
195 const ArrayType<T, N2>& b,
196 std::index_sequence<AIndices...> ,
197 std::index_sequence<BIndices...>
209 template<
typename, std::
size_t>
class ArrayType,
215 const ArrayType<T, N1>& a,
216 const ArrayType<T, N2>& b
218 return Detail::arrayConcatenateImpl(
221 std::make_index_sequence<N1>{},
222 std::make_index_sequence<N2>{}
229 template<
typename, std::
size_t>
class ArrayType,
231 std::size_t concatenatedSize
232 > constexpr ArrayType<T, concatenatedSize> concatenateHelper(
233 const ArrayType<T, concatenatedSize>& concatenated
239 template<
typename, std::
size_t>
class ArrayType,
241 std::size_t concatenatedSize,
244 > constexpr
auto concatenateHelper(
245 const ArrayType<T, concatenatedSize>& concatenated,
246 const ArrayType<T, curSize>& array,
247 const ArrayType<T, Ns>& ... arrays
249 return concatenateHelper(
262 template<
typename, std::
size_t>
class ArrayType,
267 const ArrayType<T, N>& startingArray,
268 const ArrayType<T, Ns>& ... remainingArrays
270 return Detail::concatenateHelper(startingArray, remainingArrays...);
278 template<
typename, std::
size_t>
class ArrayType,
282 const ArrayType<T, size>& a,
283 const ArrayType<T, size>& b
285 for(
unsigned i = 0; i < size; ++i) {
286 if(a.at(i) != b.at(i)) {
299 template<
typename, std::
size_t>
class ArrayType,
303 > constexpr std::enable_if_t<
307 const ArrayType<T, sizeA>& a,
308 const ArrayType<T, sizeB>& b
310 if constexpr(sizeA < sizeB) {
312 }
else if constexpr(sizeA > sizeB) {
315 for(
unsigned i = 0; i < sizeA; ++i) {
316 if(!(a.at(i) < b.at(i))) {
335 class LessThanPredicate,
341 LessThanPredicate predicate
343 using DiffType = decltype(last - bound);
345 std::is_signed<DiffType>::value,
346 "Difference between iterators must be a signed type!"
350 DiffType count = last - bound;
356 std::advance(it, step);
358 if(predicate(*it, item)) {
380 class LessThanPredicate = std::less<>
384 LessThanPredicate predicate = LessThanPredicate()
386 auto bound = lowerBound<T, LessThanPredicate>(
402 if(predicate(item, *bound)) {
403 return container.end();
410 template<
class ContainerType>
411 struct getValueTypeImpl {
412 using type =
typename std::remove_const<
413 typename std::remove_reference<
415 *(std::declval<ContainerType>()).begin()
423 template<
class ContainerType>
424 using getValueType =
typename Detail::getValueTypeImpl<ContainerType>::type;
439 class LessThanComparator = std::less<
443 const ContainerType& container,
444 LessThanComparator comparator = LessThanComparator {}
446 auto leftIter = container.begin();
447 if(leftIter == container.end()) {
451 auto rightIter = leftIter + 1;
453 while(rightIter != container.end()) {
455 if(comparator(*rightIter, *leftIter)) {
479 class LessThanComparator = std::less<
480 getValueType<ContainerType>
483 const ContainerType& container,
484 LessThanComparator comparator = LessThanComparator {}
486 auto leftIter = container.begin();
487 if(leftIter == container.end()) {
491 auto rightIter = leftIter + 1;
494 while(rightIter != container.end()) {
496 if(!comparator(*leftIter, *rightIter)) {
PURITY_STRONG constexpr std::enable_if_t< std::is_arithmetic< T >::value, ArrayType< T, size >> iota()
Iota for any array type.
Definition: Containers.h:146
double element(const PositionCollection &normalizedPositions, const Elements::Rotation &rotation)
Returns the CSM for a Rotation symmetry element along the rotation axis without optimizing the coordi...
constexpr Container::const_iterator binarySearch(const Container &container, const T &item, LessThanPredicate predicate=LessThanPredicate())
Binary search an order container.
Definition: Containers.h:381
constexpr std::enable_if_t< (sizeA > sizeB), bool > arraysLess(const ArrayType< T, sizeA > &a, const ArrayType< T, sizeB > &b)
Lexicographical comparison for two instances of an array-like class.
Definition: Containers.h:306
constexpr bool isTotallyOrdered(const ContainerType &container, LessThanComparator comparator=LessThanComparator{})
Checks if the container hold strictly increasing values.
Definition: Containers.h:482
constexpr Iter lowerBound(Iter bound, Iter last, const T &item, LessThanPredicate predicate)
Constexpr lower bound algorithm from STL.
Definition: Containers.h:337
Defines a set of useful preprocessor macros.
constexpr T reduce(const ArrayType< T, size > &array, T init, BinaryFunction &&reduction)
Reduce an array-like container with a binary function.
Definition: Containers.h:89
constexpr bool isPartiallyOrdered(const ContainerType &container, LessThanComparator comparator=LessThanComparator{})
Checks if a container is partially ordered.
Definition: Containers.h:442
std::result_of_t< Function(Args...)> functionReturnType
Figure out the return type of calling a function.
Definition: Containers.h:26
constexpr bool arraysEqual(const ArrayType< T, size > &a, const ArrayType< T, size > &b)
Array-like container lexicographic equality comparaotr.
Definition: Containers.h:281
constexpr auto map(const ArrayType< T, size > &array, UnaryFunction &&function)
Maps all elements of any array-like container with a unary function.
Definition: Containers.h:63
constexpr T sum(const ArrayType< T, size > &array)
Sum up all elements of an array-like class.
Definition: Containers.h:112
constexpr ArrayType< T,(end-begin)> range()
Range for any array type.
Definition: Containers.h:176
typename Detail::getValueTypeImpl< ContainerType >::type getValueType
Figures out the value type of a container via its iterators.
Definition: Containers.h:424
constexpr ArrayType< T, N1+N2 > arrayConcatenate(const ArrayType< T, N1 > &a, const ArrayType< T, N2 > &b)
Concatenation of two instances of an array-like class.
Definition: Containers.h:214
#define PURITY_STRONG
Definition: Preprocessor.h:65