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...>
172 template<
typename, std::
size_t>
class ArrayType,
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)) {
302 template<
typename, std::
size_t>
class ArrayType,
306 > constexpr std::enable_if_t<
310 const ArrayType<T, sizeA>& a,
311 const ArrayType<T, sizeB>& b
313 for(
unsigned i = 0; i < sizeA; ++i) {
314 if(!(a.at(i) < b.at(i))) {
328 template<
typename, std::
size_t>
class ArrayType,
332 > constexpr std::enable_if_t<
336 const ArrayType<T, sizeA>& ,
337 const ArrayType<T, sizeB>&
348 template<
typename, std::
size_t>
class ArrayType,
352 > constexpr std::enable_if_t<
356 const ArrayType<T, sizeA>& ,
357 const ArrayType<T, sizeB>&
400 class LessThanPredicate,
402 > constexpr Iter lowerBound(
406 LessThanPredicate predicate
408 using DiffType = decltype(last - bound);
410 std::is_signed<DiffType>::value,
411 "Difference between iterators must be a signed type!"
415 DiffType count = last - bound;
423 if(predicate(*it, item)) {
445 class LessThanPredicate = std::less<>
446 > constexpr
typename Container::const_iterator binarySearch(
449 LessThanPredicate predicate = LessThanPredicate()
451 auto bound = lowerBound<T, LessThanPredicate>(
467 if(predicate(item, *bound)) {
468 return container.end();
475 template<
class ContainerType>
476 struct getValueTypeImpl {
477 using type =
typename std::remove_const<
478 typename std::remove_reference<
480 *(std::declval<ContainerType>()).begin()
488 template<
class ContainerType>
489 using getValueType =
typename Detail::getValueTypeImpl<ContainerType>::type;
504 class LessThanComparator = std::less<
505 getValueType<ContainerType>
507 > constexpr
bool isPartiallyOrdered(
508 const ContainerType& container,
509 LessThanComparator comparator = LessThanComparator {}
511 auto leftIter = container.begin();
512 if(leftIter == container.end()) {
516 auto rightIter = leftIter + 1;
518 while(rightIter != container.end()) {
520 if(comparator(*rightIter, *leftIter)) {
544 class LessThanComparator = std::less<
545 getValueType<ContainerType>
547 > constexpr
bool isTotallyOrdered(
548 const ContainerType& container,
549 LessThanComparator comparator = LessThanComparator {}
551 auto leftIter = container.begin();
552 if(leftIter == container.end()) {
556 auto rightIter = leftIter + 1;
559 while(rightIter != container.end()) {
561 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...
Temple::Array< T, size > ArrayType
Definition: Properties.h:144
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
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
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
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:309
#define PURITY_STRONG
Definition: Preprocessor.h:65