SpECTRE  v2024.09.29
Utilities

A collection of useful classes, functions and metafunctions. More...

Namespaces

namespace  alg
 Utility functions wrapping STL algorithms and additional algorithms.
 
namespace  formaline
 Functions for retrieving system and source tree information.
 
namespace  funcl
 Higher order function objects similar to std::plus, etc.
 
namespace  gsl
 Implementations from the Guideline Support Library.
 
namespace  Registration
 Helpers for derived class registration.
 
namespace  tmpl2
 Metaprogramming things that are not planned to be submitted to Brigand.
 

Classes

struct  GetContainerSize
 Callable struct which retrieves the t.size() for operand t. This will cause a compiler error if no such function exists. More...
 
struct  GetContainerElement
 Callable struct for the subscript operator. Returns t[i] More...
 
class  ContinuedFraction< T >
 Compute the continued fraction representation of a number. More...
 
class  ContinuedFractionSummer< Fraction >
 Sum a continued fraction. More...
 
class  gsl::not_null< T >
 Require a pointer to not be a nullptr More...
 
class  gsl::span< ElementType, Extent >
 Create a span/view on a range, which is cheap to copy (one pointer). More...
 
class  MakeString
 Make a string by streaming into object. More...
 
struct  NoSuchType
 Used to mark "no type" or "bad state" for metaprogramming. More...
 
struct  Overloader< Fs >
 Used for overloading lambdas, useful for lambda-SFINAE. More...
 
class  Rational
 A rational number. More...
 
struct  CacheRange< Start, End >
 Range of integral values for StaticCache indices. The Start is inclusive and the End is exclusive. The range must not be empty. More...
 
struct  CacheEnumeration< EnumerationType, Enums >
 Possible enumeration values for the StaticCache. Only values specified here are retrievable. More...
 
class  StaticCache< Generator, T, Ranges >
 A cache of objects intended to be stored in a static variable. More...
 
class  tuples::TaggedTuple< Tags >
 An associative container that is indexed by structs. More...
 
struct  tmpl2::value_list< T,... >
 A compile-time list of values of the same type. More...
 
struct  TypeDisplayer<... >
 Get compiler error with type of template parameter. More...
 
struct  make_list< Ts >
 Metafunction to turn a parameter pack into a typelist. More...
 

Macros

#define SPECTRE_ALWAYS_INLINE   inline
 Always inline a function. Only use this if you benchmarked the code.
 
#define GENERATE_INSTANTIATIONS(INSTANTIATION_MACRO, ...)
 Macro useful for generating many explicit instantiations of function or class templates. More...
 
#define LIKELY(x)   (x)
 
#define UNLIKELY(x)   (x)
 
#define DEFINE_STD_ARRAY_BINOP(RESULT_TYPE, LTYPE, RTYPE, OP_FUNCTION_NAME, BINARY_OP)
 Declares a binary function on an array, intended for binary operators such as + More...
 
#define DEFINE_STD_ARRAY_INPLACE_BINOP(LTYPE, RTYPE, OP_FUNCTION_NAME, BINARY_OP)
 Declares an in-place binary function on an array, intended for operations such as += More...
 
#define EXPAND_PACK_LEFT_TO_RIGHT(...)    (void)std::initializer_list<char> { ((void)(__VA_ARGS__), '0')... }
 Expand a parameter pack evaluating the terms from left to right. More...
 

Typedefs

template<class T , Requires< std::is_pointer< T >::value > = nullptr>
using gsl::owner = typename detail::owner_impl< T >::type
 Mark a raw pointer as owning its data. More...
 
template<bool B>
using Requires = typename Requires_detail::requires_impl< B >::template_error_type_failed_to_meet_requirements_on_template_parameters
 Express requirements on the template parameters of a function or class, replaces std::enable_if_t More...
 
template<typename T >
using tuples::tagged_tuple_from_typelist = typename TaggedTuple_detail::tagged_tuple_typelist_impl< T >::type
 
template<bool... Bs>
using tmpl2::flat_all = std::is_same< value_list< bool, Bs... >, value_list< bool,(static_cast< void >(Bs), true)... > >
 A non-short-circuiting logical AND between bools 'B"". More...
 
template<bool... Bs>
using tmpl2::flat_any = std::integral_constant< bool, not std::is_same< value_list< bool, Bs... >, value_list< bool,(static_cast< void >(Bs), false)... > >::value >
 A non-short-circuiting logical OR between bools 'B"". More...
 
template<typename Sequence >
using brigand::make_std_variant_over = typename detail::make_std_variant_over_impl< tmpl::remove_duplicates< Sequence > >::type
 Create a std::variant with all all the types inside the typelist Sequence. More...
 
template<class Graph , class S , class D >
using brigand::has_edge = typename ::brigand::lazy::has_edge< Graph, S, D >::type
 Check if a digraph has an edge with source S and destination D
 

Functions

template<class T >
constexpr void cpp20::swap (T &a, T &b)
 
template<class ForwardIt1 , class ForwardIt2 >
constexpr void cpp20::iter_swap (ForwardIt1 a, ForwardIt2 b)
 
template<class BidirectionalIterator >
constexpr void cpp20::reverse (BidirectionalIterator first, BidirectionalIterator last)
 
template<class Compare , class BidirectionalIterator >
constexpr bool cpp20::next_permutation (BidirectionalIterator first, BidirectionalIterator last, Compare comp)
 
template<class BidirectionalIterator >
constexpr bool cpp20::next_permutation (BidirectionalIterator first, BidirectionalIterator last)
 
template<class InputIt , class T >
constexpr InputIt cpp20::find (InputIt first, InputIt last, const T &value)
 
template<class InputIt , class UnaryPredicate >
constexpr InputIt cpp20::find_if (InputIt first, InputIt last, UnaryPredicate p)
 
template<class InputIt , class UnaryPredicate >
constexpr InputIt cpp20::find_if_not (InputIt first, InputIt last, UnaryPredicate q)
 
template<typename Result , typename Classes , typename Base , typename Callable , typename... Args>
Result call_with_dynamic_type (Base *const obj, Callable &&f, Args &&... args)
 Call a functor with the derived type of a base class pointer. More...
 
template<class OutputIterator , class... InputIterator>
void cartesian_product (OutputIterator result, std::pair< InputIterator, InputIterator >... dimensions)
 Fill the result iterator with the Cartesian product of a sequence of iterators. More...
 
template<typename... Ts, size_t... Lens>
std::array< std::tuple< Ts... >,(... *Lens)> cartesian_product (const std::array< Ts, Lens > &... dimensions)
 The Cartesian product of a sequence of arrays. More...
 
template<typename... Containers>
std::vector< std::tuple< typename Containers::value_type... > > cartesian_product (const Containers &... containers)
 The Cartesian product of several containers. More...
 
template<typename KeyType , typename T >
std::unordered_map< KeyType, std::unique_ptr< T > > clone_unique_ptrs (const std::unordered_map< KeyType, std::unique_ptr< T > > &map)
 Given a map of std::unique_ptr returns a copy of the map by invoking get_clone() on each element of the input map.
 
template<typename T >
std::vector< std::unique_ptr< T > > clone_unique_ptrs (const std::vector< std::unique_ptr< T > > &vector)
 Given a vector of std::unique_ptr returns a copy of the vector by invoking get_clone() on each element of the input vector.
 
template<typename T , typename SubscriptFunction = GetContainerElement>
decltype(auto) get_element (T &t, const size_t i, SubscriptFunction at=GetContainerElement{})
 Returns the ith element if T has a subscript operator, otherwise if T is fundamental or a std::complex of a fundamental type, returns t. More...
 
template<typename T , typename SizeFunction = GetContainerSize>
decltype(auto) get_size (const T &t, SizeFunction size=GetContainerSize{})
 Retrieve the size of t if t.size() is a valid expression, otherwise if T is fundamental or a std::complex of a fundamental type, returns 1. More...
 
template<typename T >
decltype(auto) dereference_wrapper (T &&t)
 Returns the reference object held by a reference wrapper, if a non-reference_wrapper type is passed in then the object is returned.
 
template<typename Lhs , typename Rhs >
constexpr bool equal_within_roundoff (const Lhs &lhs, const Rhs &rhs, const double eps=std::numeric_limits< double >::epsilon() *100.0, const double scale=1.0)
 Checks if two values lhs and rhs are equal within roundoff, by comparing abs(lhs - rhs) < (max(abs(lhs), abs(rhs)) + scale) * eps. More...
 
template<typename Fraction , typename T1 , typename T2 >
Fraction simplest_fraction_in_interval (const T1 &end1, const T2 &end2)
 Find the fraction in the supplied interval with the smallest denominator. More...
 
template<typename T >
std::string get_output (const T &t)
 Get the streamed output of t as a std::string
 
template<class T , class U >
constexpr T gsl::narrow_cast (U &&u)
 Cast u to a type T where the cast may result in narrowing.
 
template<class T , class U >
gsl::narrow (U u)
 A checked version of narrow_cast() that ERRORs if the cast changed the value.
 
constexpr size_t operator""_st (const unsigned long long n)
 Defines the _st size_t suffix.
 
template<size_t Size, typename T , typename... Args>
constexpr std::array< T, Size > make_array (Args &&... args)
 Create a std::array<T, Size>{{T(args...), T(args...), ...}} More...
 
template<size_t Size, typename T >
constexpr auto make_array (T &&t) -> std::array< std::decay_t< T >, Size >
 Create a std::array<std::decay_t<T>, Size>{{t, t, ...}} More...
 
template<typename T , typename... V, Requires<(sizeof...(V) > 0)> = nullptr>
constexpr auto make_array (T &&t, V &&... values) -> std::array< typename std::decay_t< T >, sizeof...(V)+1 >
 Helper function to initialize a std::array with varying number of arguments.
 
template<typename T , size_t size, typename Seq >
constexpr std::array< T, size > make_array (Seq &&seq)
 Create an std::array<T, size> from the first size values of seq More...
 
template<typename T >
number_of_digits (const T number)
 Returns the number of digits in an integer number.
 
template<typename CoeffsIterable , typename DataType >
DataType evaluate_polynomial (const CoeffsIterable &coeffs, const DataType &x)
 Evaluate a polynomial \(\sum_{p=0}^N c_p x^p\) with Horner's rule. More...
 
template<typename T , Requires< std::is_arithmetic< T >::value > = nullptr>
constexpr T step_function (const T &arg)
 Defines the Heaviside step function \(\Theta\) for arithmetic types. \(\Theta(0) = 1\).
 
template<size_t N, typename DataType >
DataType smoothstep (const double lower_edge, const double upper_edge, const DataType &arg)
 Smoothly interpolates from 0 to 1 between lower_edge and upper_edge with a Hermite polynomial of degree 2 * N + 1. More...
 
template<typename T , Requires< std::is_arithmetic< T >::value or tt::is_a_v< std::complex, T > > = nullptr>
auto invsqrt (const T &arg)
 Defines the inverse square-root ( \(1/\sqrt{x}\)) for arithmetic and complex types.
 
template<typename T , Requires< std::is_arithmetic< T >::value > = nullptr>
auto invcbrt (const T &arg)
 Defines the inverse cube-root ( \(1/\sqrt[3]{x}\)) for arithmetic types.
 
template<typename T >
constexpr T sgn (const T &val)
 Compute the sign function of val defined as 1 if val > 0, 0 if val == 0, and -1 if val < 0.
 
double integer_pow (const double x, const int e)
 Raises a double to the integer power n.
 
template<class ForwardIterator , class T >
constexpr void cpp2b::iota (ForwardIterator first, ForwardIterator last, T value)
 
template<class InputIt , class T >
constexpr T cpp2b::accumulate (InputIt first, InputIt last, T init)
 
template<typename StreamType , typename T >
StreamType & print_value (StreamType &os, const T &value)
 Either streams value or the string "UNSTREAMABLE".
 
template<typename ForwardIt , typename Func >
void sequence_print_helper (std::ostream &out, ForwardIt begin, const ForwardIt &end, Func f)
 Applies the function f(out, it) to each item from begin to end, separated by commas and surrounded by parens.
 
template<typename ForwardIt >
void sequence_print_helper (std::ostream &out, ForwardIt begin, const ForwardIt &end)
 Prints all the items as a comma separated list surrounded by parens.
 
template<typename... Ranges, typename Generator >
auto make_static_cache (Generator &&generator)
 Create a StaticCache, inferring the cached type from the generator.
 
template<typename T , size_t Dim>
std::array< T, Dim - 1 > all_but_specified_element_of (const std::array< T, Dim > &a, const size_t element_to_remove)
 Construct an array from an existing array omitting one element.
 
template<typename T , size_t Dim>
std::array< T, Dim+1 > insert_element (std::array< T, Dim > a, const size_t element_to_add, T value)
 Construct an array from an existing array adding one element.
 
template<typename T , size_t Dim>
constexpr std::array< T, Dim+1 > prepend (const std::array< T, Dim > &a, T value)
 Construct an array from an existing array prepending a value.
 
template<typename T , size_t Dim1, size_t Dim2>
constexpr std::array< T, Dim1+Dim2 > concatenate (std::array< T, Dim1 > a, std::array< T, Dim2 > b)
 Construct an array from the contents of two other arrays.
 
template<typename T , size_t Dim, typename F >
auto map_array (const std::array< T, Dim > &array, const F &f)
 Applies a function to each element of an array, producing a new array of the results. The elements of the new array are constructed in place, so they need not be default constructible.
 
template<typename T >
std::ostreamoperator<< (std::ostream &os, const std::list< T > &v)
 Output the items of a std::list.
 
template<typename T >
std::ostreamoperator<< (std::ostream &os, const std::vector< T > &v)
 Output the items of a std::vector.
 
template<typename T >
std::ostreamoperator<< (std::ostream &os, const std::deque< T > &v)
 Output the items of a std::deque.
 
template<typename T , size_t N>
std::ostreamoperator<< (std::ostream &os, const std::array< T, N > &a)
 Output the items of a std::array.
 
template<typename... Args>
std::ostreamoperator<< (std::ostream &os, const std::tuple< Args... > &t)
 Stream operator for tuples.
 
template<typename K , typename V , typename H >
std::ostreamoperator<< (std::ostream &os, const std::unordered_map< K, V, H > &m)
 Output all the key, value pairs of a std::unordered_map.
 
template<typename K , typename V , typename C >
std::ostreamoperator<< (std::ostream &os, const std::map< K, V, C > &m)
 Output all the key, value pairs of a std::map.
 
template<typename T , typename H >
std::ostreamoperator<< (std::ostream &os, const std::unordered_set< T, H > &v)
 Output the items of a std::unordered_set.
 
template<typename T , typename H >
std::ostreamoperator<< (std::ostream &os, const std::unordered_multiset< T, H > &v)
 Output the items of a std::unordered_multiset.
 
template<typename T , typename C >
std::ostreamoperator<< (std::ostream &os, const std::set< T, C > &v)
 Output the items of a std::set.
 
template<typename T , Requires< tt::is_streamable< std::ostream, T >::value > >
std::ostreamoperator<< (std::ostream &os, const std::unique_ptr< T > &t)
 Stream operator for std::unique_ptr.
 
template<typename T , Requires< tt::is_streamable< std::ostream, T >::value > >
std::ostreamoperator<< (std::ostream &os, const std::shared_ptr< T > &t)
 Stream operator for std::shared_ptr.
 
template<typename T , typename U >
std::ostreamoperator<< (std::ostream &os, const std::pair< T, U > &t)
 Stream operator for std::pair.
 
template<typename T >
std::ostreamoperator<< (std::ostream &os, const std::optional< T > &t)
 Stream operator for std::optional.
 
template<typename T >
void print_stl (std::ostream &os, const T &t)
 Equivalent to os << t. More...
 
template<typename K , typename V , typename H >
std::string keys_of (const std::unordered_map< K, V, H > &m)
 Construct a string containing the keys of a std::unordered_map.
 
template<typename K , typename V , typename C >
std::string keys_of (const std::map< K, V, C > &m)
 Construct a string containing the keys of a std::map.
 
template<typename... Args>
std::string formatted_string (const std::string &fmt, Args... args)
 Format a string like printf. More...
 
std::string current_date_and_time ()
 Get the current date and time.
 
void sys::exit (int exit_code=0)
 Exit the program normally. This should only be called once over all processors.
 
int sys::number_of_procs ()
 Number of processing elements.
 
int sys::my_proc ()
 Index of my processing element.
 
int sys::number_of_nodes ()
 Number of nodes.
 
int sys::my_node ()
 Index of my node.
 
int sys::procs_on_node (int node_index)
 Number of processing elements on the given node.
 
int sys::my_local_rank ()
 The local index of my processing element on my node. This is in the interval 0, ..., procs_on_node(my_node()) - 1.
 
int sys::first_proc_on_node (int node_index)
 Index of first processing element on the given node.
 
int sys::node_of (int proc_index)
 Index of the node for the given processing element.
 
int sys::local_rank_of (int proc_index)
 The local index for the given processing element on its node.
 
double sys::wall_time ()
 The elapsed wall time in seconds.
 
template<typename... Ts>
constexpr void expand_pack (Ts &&...)
 Allows zero-cost unordered expansion of a parameter. More...
 
template<typename T , typename... Ts>
constexpr decltype(auto) get_first_argument (T &&t, Ts &&...)
 Returns the first argument of a parameter pack.
 
template<bool ReverseIteration = false, typename... Elements, typename N_aryOp , typename... Args>
constexpr void tuple_transform (const std::tuple< Elements... > &tuple, N_aryOp &&op, Args &&... args)
 Perform a transform over a std::tuple. More...
 
template<size_t Start, size_t Stop, typename Tuple >
constexpr auto tuple_slice (Tuple &&tuple)
 The subset of elements in tuple from index Start to (excluding) Stop
 
template<size_t Size, typename Tuple >
constexpr auto tuple_head (Tuple &&tuple)
 The first Size elements in tuple
 
template<size_t Size, typename Tuple >
constexpr auto tuple_tail (Tuple &&tuple)
 The last Size elements in tuple
 
std::string wrap_text (std::string str, size_t line_length, const std::string &indentation="")
 Wrap the string str so that it is no longer than line_length and indent each new line with indentation. The first line is also indented. More...
 

Variables

template<bool... Bs>
constexpr bool tmpl2::flat_all_v = flat_all<Bs...>::value
 A non-short-circuiting logical AND between bools 'B"". More...
 
template<bool... Bs>
constexpr bool tmpl2::flat_any_v = flat_any<Bs...>::value
 A non-short-circuiting logical OR between bools 'B"". More...
 
double ddot_ (const size_t &N, const double *X, const size_t &INCX, const double *Y, const size_t &INCY)
 
std::complex< double > zdotu_ (const size_t &N, const std::complex< double > *X, const size_t &INCX, const std::complex< double > *Y, const size_t &INCY)
 The unconjugated complex dot product \(x \cdot y\). See zdotc_ for the conjugated complex dot product, which is the standard dot product on the vector space of complex numbers.
 
std::complex< double > zdotc_ (const size_t &N, const std::complex< double > *X, const size_t &INCX, const std::complex< double > *Y, const size_t &INCY)
 The conjugated complex dot product \(\bar{x} \cdot y\). This is the standard dot product on the vector space of complex numbers.
 
template<bool UseLibXsmm = false>
void dgemm_ (const char &TRANSA, const char &TRANSB, const size_t &M, const size_t &N, const size_t &K, const double &ALPHA, const double *A, const size_t &LDA, const double *B, const size_t &LDB, const double &BETA, double *C, const size_t &LDC)
 Perform a matrix-matrix multiplication. More...
 
template<bool UseLibXsmm = false>
void zgemm_ (const char &TRANSA, const char &TRANSB, const size_t &M, const size_t &N, const size_t &K, const std::complex< double > &ALPHA, const std::complex< double > *A, const size_t &LDA, const std::complex< double > *B, const size_t &LDB, const std::complex< double > &BETA, std::complex< double > *C, const size_t &LDC)
 Perform a matrix-matrix multiplication. More...
 
template<>
void dgemm_< true > (const char &TRANSA, const char &TRANSB, const size_t &M, const size_t &N, const size_t &K, const double &ALPHA, const double *A, const size_t &LDA, const double *B, const size_t &LDB, const double &BETA, double *C, const size_t &LDC)
 Perform a matrix-matrix multiplication. More...
 
void dgemv_ (const char &TRANS, const size_t &M, const size_t &N, const double &ALPHA, const double *A, const size_t &LDA, const double *X, const size_t &INCX, const double &BETA, double *Y, const size_t &INCY)
 Perform a matrix-vector multiplication. More...
 
template<class T , std::size_t N, typename Size >
constexpr T & gsl::at (std::array< T, N > &arr, Size index)
 Retrieve a entry from a container, with checks in Debug mode that the index being retrieved is valid.
 
template<class T , std::size_t N, typename Size >
KOKKOS_FUNCTION constexpr T & gsl::at (cpp20::array< T, N > &arr, Size index)
 Retrieve a entry from a container, with checks in Debug mode that the index being retrieved is valid.
 
template<class T , std::size_t N, typename Size >
KOKKOS_FUNCTION constexpr const T & gsl::at (const cpp20::array< T, N > &arr, Size index)
 Retrieve a entry from a container, with checks in Debug mode that the index being retrieved is valid.
 
template<class Cont , typename Size >
constexpr const Cont::value_type & gsl::at (const Cont &cont, Size index)
 Retrieve a entry from a container, with checks in Debug mode that the index being retrieved is valid.
 
template<class T , typename Size >
constexpr const T & gsl::at (std::initializer_list< T > cont, Size index)
 Retrieve a entry from a container, with checks in Debug mode that the index being retrieved is valid.
 
template<class ElementType >
constexpr span< ElementType > gsl::make_span (ElementType *ptr, typename span< ElementType >::index_type count)
 Utility function for creating spans.
 
template<class ElementType >
constexpr span< ElementType > gsl::make_span (ElementType *firstElem, ElementType *lastElem)
 Utility function for creating spans.
 
template<class ElementType , std::size_t N>
constexpr span< ElementType, N > gsl::make_span (ElementType(&arr)[N])
 Utility function for creating spans.
 
template<class Container >
constexpr span< typename Container::value_type > gsl::make_span (Container &cont)
 Utility function for creating spans.
 
template<class Container >
constexpr span< const typename Container::value_type > gsl::make_span (const Container &cont)
 Utility function for creating spans.
 
template<class Ptr >
constexpr span< typename Ptr::element_type > gsl::make_span (Ptr &cont, std::ptrdiff_t count)
 Utility function for creating spans.
 
template<class Ptr >
constexpr span< typename Ptr::element_type > gsl::make_span (Ptr &cont)
 Utility function for creating spans.
 
template<typename T >
make_signaling_NaN (const T &)
 Returns an appropriate signaling NaN for fundamantal or multi-field types (such as std::complex).
 
template<typename T >
std::complex< T > make_signaling_NaN (const std::complex< T > &)
 Returns an appropriate signaling NaN for fundamantal or multi-field types (such as std::complex).
 
template<typename T >
make_signaling_NaN ()
 Returns an appropriate signaling NaN for fundamantal or multi-field types (such as std::complex).
 
template<typename T >
constexpr bool has_value (const T &)
 Returns t.has_value() if t is a std::optional otherwise returns true.
 
template<typename T >
constexpr bool has_value (const std::optional< T > &t)
 Returns t.has_value() if t is a std::optional otherwise returns true.
 
template<typename T >
constexpr T & value (T &t)
 Returns t.value() if t is a std::optional otherwise returns t.
 
template<typename T >
constexpr const T & value (const T &t)
 Returns t.value() if t is a std::optional otherwise returns t.
 
template<typename T >
constexpr const T & value (const std::optional< T > &t)
 Returns t.value() if t is a std::optional otherwise returns t.
 
template<typename T >
constexpr T & value (std::optional< T > &t)
 Returns t.value() if t is a std::optional otherwise returns t.
 
template<typename ForwardIt , typename Func >
void unordered_print_helper (std::ostream &out, ForwardIt begin, const ForwardIt &end, Func f)
 
template<typename ForwardIt >
void unordered_print_helper (std::ostream &out, ForwardIt begin, const ForwardIt &end)
 
template<typename SizeList , typename... TupleTypes>
constexpr auto split_tuple (std::tuple< TupleTypes... > tuple)
 Split a std::tuple into multiple tuples. More...
 
template<typename T >
decltype(auto) magnitude (const std::array< T, 1 > &a)
 Euclidean magnitude of the elements of the array. More...
 
template<typename T >
decltype(auto) magnitude (const std::array< T, 2 > &a)
 Euclidean magnitude of the elements of the array. More...
 
template<typename T >
decltype(auto) magnitude (const std::array< T, 3 > &a)
 Euclidean magnitude of the elements of the array. More...
 
template<typename T , typename R >
decltype(auto) dot (const std::array< T, 1 > &first, const std::array< R, 1 > &second)
 Dot product between two arrays. More...
 
template<typename T , typename R >
decltype(auto) dot (const std::array< T, 2 > &first, const std::array< R, 2 > &second)
 Dot product between two arrays. More...
 
template<typename T , typename R >
decltype(auto) dot (const std::array< T, 3 > &first, const std::array< R, 3 > &second)
 Dot product between two arrays. More...
 
std::string sys::pretty_wall_time (double total_seconds)
 Format the wall time in DD-HH:MM:SS format. More...
 
std::string sys::pretty_wall_time ()
 Format the wall time in DD-HH:MM:SS format. More...
 
template<class Tag , class... Tags>
constexpr const Tag::type & tuples::get (const TaggedTuple< Tags... > &t)
 Retrieve the element of Tag in the TaggedTuple.
 
template<class Tag , class... Tags>
constexpr Tag::type & tuples::get (TaggedTuple< Tags... > &t)
 Retrieve the element of Tag in the TaggedTuple.
 
template<class Tag , class... Tags>
constexpr const Tag::type && tuples::get (const TaggedTuple< Tags... > &&t)
 Retrieve the element of Tag in the TaggedTuple.
 
template<class Tag , class... Tags>
constexpr Tag::type && tuples::get (TaggedTuple< Tags... > &&t)
 Retrieve the element of Tag in the TaggedTuple.
 
template<typename ApplyTags , typename F , typename... Tags>
constexpr decltype(auto) tuples::apply (F &&f, const TaggedTuple< Tags... > &t)
 Invoke f with the ApplyTags taken from t expanded in a parameter pack. More...
 
template<typename F , typename... Tags>
constexpr decltype(auto) tuples::apply (F &&f, const TaggedTuple< Tags... > &t)
 Invoke f with the ApplyTags taken from t expanded in a parameter pack. More...
 
template<bool ReverseIteration = false, typename... Elements, typename N_aryOp , typename... Args>
constexpr void tuple_fold (const std::tuple< Elements... > &tuple, N_aryOp &&op, Args &&... args)
 Perform a fold over a std::tuple. More...
 
template<bool ReverseIteration = false, typename... Elements, typename N_aryOp , typename... Args>
constexpr void tuple_counted_fold (const std::tuple< Elements... > &tuple, N_aryOp &&op, Args &&... args)
 Perform a fold over a std::tuple. More...
 
template<typename LhsVectorType , typename RhsVectorType , typename ResultVectorType = typename blaze::MultTrait<LhsVectorType, RhsVectorType>::Type>
void outer_product (const gsl::not_null< ResultVectorType * > result, const LhsVectorType &lhs, const RhsVectorType &rhs)
 Computes the outer product between two vectors. More...
 
template<typename LhsVectorType , typename RhsVectorType , typename ResultVectorType = typename blaze::MultTrait<LhsVectorType, RhsVectorType>::Type>
ResultVectorType outer_product (const LhsVectorType &lhs, const RhsVectorType &rhs)
 Computes the outer product between two vectors. More...
 
template<typename VectorType >
void fill_with_n_copies (const gsl::not_null< VectorType * > result, const VectorType &to_copy, const size_t times_to_copy)
 Creates or fills a vector with data from to_repeat copied times_to_repeat times in sequence. More...
 
template<typename VectorType >
VectorType create_vector_of_n_copies (const VectorType &to_copy, const size_t times_to_copy)
 Creates or fills a vector with data from to_repeat copied times_to_repeat times in sequence. More...
 

Detailed Description

A collection of useful classes, functions and metafunctions.

Macro Definition Documentation

◆ DEFINE_STD_ARRAY_BINOP

#define DEFINE_STD_ARRAY_BINOP (   RESULT_TYPE,
  LTYPE,
  RTYPE,
  OP_FUNCTION_NAME,
  BINARY_OP 
)
Value:
template <size_t Dim> \
std::array<RESULT_TYPE, Dim> OP_FUNCTION_NAME( \
const std::array<LTYPE, Dim>& lhs, const std::array<RTYPE, Dim>& rhs) { \
std::array<RESULT_TYPE, Dim> result; /*NOLINT*/ \
std::transform(lhs.begin(), lhs.end(), rhs.begin(), result.begin(), \
BINARY_OP); \
return result; \
}
void transform(const gsl::not_null< History< DestVars > * > dest, const History< SourceVars > &source, ValueTransformer &&value_transformer, DerivativeTransformer &&derivative_transformer)
Initialize a History object based on the contents of another, applying a transformation to each value...
Definition: History.hpp:1046

Declares a binary function on an array, intended for binary operators such as +

Parameters
RESULT_TYPEthe value_type that is the result of the operation (e.g. A for resulting std::array<A,2>)
LTYPEthe value_type of the first argument of the function (so the left value if the function is an operator overload)
RTYPEthe value_type of the second argument of the function
OP_FUNCTION_NAMEthe function which should be declared (e.g. operator+)
BINARY_OPthe binary function which should be applied elementwise to the pair of arrays. (e.g. std::plus<>())

◆ DEFINE_STD_ARRAY_INPLACE_BINOP

#define DEFINE_STD_ARRAY_INPLACE_BINOP (   LTYPE,
  RTYPE,
  OP_FUNCTION_NAME,
  BINARY_OP 
)
Value:
template <size_t Dim> \
std::array<LTYPE, Dim>& OP_FUNCTION_NAME( \
std::transform(lhs.begin(), lhs.end(), rhs.begin(), lhs.begin(), \
BINARY_OP); \
return lhs; \
}

Declares an in-place binary function on an array, intended for operations such as +=

Parameters
LTYPEthe value_type of the first argument of the function which is also the result value_tye of the operation (so the left value if the function is an operator overload)
RTYPEthe value_type of the second argument of the function
OP_FUNCTION_NAMEthe function which should be declared (e.g. operator+=)
BINARY_OPthe binary function which should be applied elementwise to the pair of arrays. (e.g. std::plus<>())

◆ EXPAND_PACK_LEFT_TO_RIGHT

#define EXPAND_PACK_LEFT_TO_RIGHT (   ...)     (void)std::initializer_list<char> { ((void)(__VA_ARGS__), '0')... }

Expand a parameter pack evaluating the terms from left to right.

The parameter pack inside the argument to the macro must not be expanded since the macro will do the expansion correctly for you. In the below example a parameter pack of std::integral_constant<size_t, I> is passed to the function. The closure lambda is used to sum up the values of all the Ts. Note that the Ts passed to EXPAND_PACK_LEFT_TO_RIGHT is not expanded.

template <typename... Ts>
void test_expand_pack_left_to_right(const size_t expected,
tmpl::list<Ts...> /*meta*/) {
size_t sum = 0;
const auto lambda = [&sum](auto tag) { sum += decltype(tag)::value; };
CHECK(sum == expected);
}
constexpr T & value(T &t)
Returns t.value() if t is a std::optional otherwise returns t.
Definition: OptionalHelpers.hpp:32
#define EXPAND_PACK_LEFT_TO_RIGHT(...)
Expand a parameter pack evaluating the terms from left to right.
Definition: TMPL.hpp:594
See also
tuple_fold tuple_counted_fold tuple_transform std::tuple expand_pack

◆ GENERATE_INSTANTIATIONS

#define GENERATE_INSTANTIATIONS (   INSTANTIATION_MACRO,
  ... 
)
Value:
GENERATE_INSTANTIATIONS_DO_PRODUCT( \
INSTANTIATION_MACRO, \
BOOST_PP_LIST_TRANSFORM(GENERATE_INSTANTIATION_TUPLES_TO_LISTS, _, \
BOOST_PP_VARIADIC_TO_LIST(__VA_ARGS__)))

Macro useful for generating many explicit instantiations of function or class templates.

It is often necessary to generate explicit instantiations of function or class templates. Since the total number of explicit instantiations scales as the product of the number of possible number of parameter values of each template parameter, this quickly becomes tedious. This macro allows you to easily generate hundreds of explicit instantiations.

The first argument to the macro is a macro that takes two arguments and is described below. The remaining arguments are macro-tuples, e.g. (1, 2, 3). The Cartesian product of the macro-tuples is then computed and each term is passed as a tuple as the second argument to the INSTANTIATION_MACRO. The first argument to the INSTANTIATION_MACRO is a Boost.Preprocessor internal variable so just make it _. The INSTANTIATION(_, data) macro below serves as an example. A concrete example is generating explicit instantiations of the class Index<Dim> for Dim = 0,1,2,3, which you would do as follows:

#define GET_DIM(data) BOOST_PP_TUPLE_ELEM(0, data)
#define INSTANTIATION(_, data) \
template class Index<GET_DIM(data)>;
GENERATE_INSTANTIATIONS(INSTANTIATION, (0, 1, 2, 3))
#undef GET_DIM
#undef INSTANTIATION
#define GENERATE_INSTANTIATIONS(INSTANTIATION_MACRO,...)
Macro useful for generating many explicit instantiations of function or class templates.
Definition: GenerateInstantiations.hpp:158

This will generate:

template class Index<0>;
template class Index<1>;
template class Index<2>;
template class Index<3>;
An integer multi-index.
Definition: Index.hpp:31

It is also possible to generate explicit instantiations for multiple classes or functions in a single call to GENERATE_INSTANTIATIONS. For example, the (in)equivalence operators can be generated using:

#define GET_DIM(data) BOOST_PP_TUPLE_ELEM(0, data)
#define GEN_OP(op, dim) \
template bool operator op(const Index<dim>& lhs, \
const Index<dim>& rhs);
#define INSTANTIATION(_, data) \
template class Index<GET_DIM(data)>; \
GEN_OP(==, GET_DIM(data)) \
GEN_OP(!=, GET_DIM(data))
GENERATE_INSTANTIATIONS(INSTANTIATION, (0, 1, 2, 3))
#undef GET_DIM
#undef GEN_OP
#undef INSTANTIATION

which will result in the instantiations:

template class Index<0>;
template bool operator==(const Index<0>& lhs, const Index<0>& rhs);
template bool operator!=(const Index<0>& lhs, const Index<0>& rhs);
template class Index<1>;
template bool operator==(const Index<1>& lhs, const Index<1>& rhs);
template bool operator!=(const Index<1>& lhs, const Index<1>& rhs);
template class Index<2>;
template bool operator==(const Index<2>& lhs, const Index<2>& rhs);
template bool operator!=(const Index<2>& lhs, const Index<2>& rhs);
template class Index<3>;
template bool operator==(const Index<3>& lhs, const Index<3>& rhs);
template bool operator!=(const Index<3>& lhs, const Index<3>& rhs);
T operator!=(T... args)

Now let's look at generating instantiations of member function templates of class templates, which will be a common use case. In this example we generate explicit instantiations of all the member function templates of the class ScalarWave::Solutions::PlaneWave. In total, for Dim = 1,2,3 and types double and DataVector this is about 42 explicit instantiations, which would be extremely annoying to write by hand. The macro code is surprisingly simple:

#define DIM(data) BOOST_PP_TUPLE_ELEM(0, data)
#define DTYPE(data) BOOST_PP_TUPLE_ELEM(1, data)
#define INSTANTIATE(_, data) \
template Scalar<DTYPE(data)> \
ScalarWave::Solutions::PlaneWave<DIM(data)>::psi( \
const tnsr::I<DTYPE(data), DIM(data)>& x, double t) const; \
template Scalar<DTYPE(data)> \
ScalarWave::Solutions::PlaneWave<DIM(data)>::dpsi_dt( \
const tnsr::I<DTYPE(data), DIM(data)>& x, double t) const;
GENERATE_INSTANTIATIONS(INSTANTIATE, (1, 2, 3), (double, DataVector))
#undef DIM
#undef DTYPE
#undef INSTANTIATE
Stores a collection of function values.
Definition: DataVector.hpp:48

We don't show the result from preprocessor since for all of the member functions of PlaneWave the total output is approximately 150 lines, but you can hopefully see the benefits of generating explicit instantiations using the GENERATE_INSTANTIATIONS way.

One thing that can be difficult is debugging metaprograms (be they template or macro-based). To this end we provide a make target DebugPreprocessor which prints the output of running the preprocessor on the file src/Executables/DebugPreprocessor/DebugPreprocessor.cpp. Note that the output of the GENERATE_INSTANTIATIONS macro will be on a single line, so it often proves useful to copy-paste the output into an editor and run clang-format over the code so it's easier to reason about.

◆ LIKELY

#define LIKELY (   x)    (x)

The if statement is expected to evaluate true most of the time

◆ UNLIKELY

#define UNLIKELY (   x)    (x)

The if statement is expected to evaluate false most of the time

Typedef Documentation

◆ flat_all

template<bool... Bs>
using tmpl2::flat_all = typedef std::is_same<value_list<bool, Bs...>, value_list<bool, (static_cast<void>(Bs), true)...> >

A non-short-circuiting logical AND between bools 'B"".

Useful when arbitrarily large parameter packs need to be evaluated, since std::conjunction and std::disjunction use recursion

◆ flat_any

template<bool... Bs>
using tmpl2::flat_any = typedef std::integral_constant< bool, not std::is_same< value_list<bool, Bs...>, value_list<bool, (static_cast<void>(Bs), false)...> >::value>

A non-short-circuiting logical OR between bools 'B"".

Useful when arbitrarily large parameter packs need to be evaluated, since std::conjunction and std::disjunction use recursion

◆ make_std_variant_over

template<typename Sequence >
using brigand::make_std_variant_over = typedef typename detail::make_std_variant_over_impl< tmpl::remove_duplicates<Sequence> >::type

Create a std::variant with all all the types inside the typelist Sequence.

Returns: std::variant of all types inside Sequence

◆ owner

template<class T , Requires< std::is_pointer< T >::value > = nullptr>
using gsl::owner = typedef typename detail::owner_impl<T>::type

Mark a raw pointer as owning its data.

Warning
You should never actually use gsl::owner. Instead you should use std::unique_ptr, and if shared ownership is required, std::shared_ptr.

◆ Requires

template<bool B>
using Requires = typename Requires_detail::requires_impl< B>::template_error_type_failed_to_meet_requirements_on_template_parameters

Express requirements on the template parameters of a function or class, replaces std::enable_if_t

Replacement for std::enable_if_t and Concepts for expressing requirements on template parameters. This does not require merging of the Concepts TS (whose merit is debatable) and provides an "error message" if substitution of a template parameter failed. Specifically, the compiler error will contain "template_error_type_failed_to_meet_requirements_on_template_parameters", aiding the user of a function or class in tracking down the list of requirements on the deduced type.

For example, if a function foo is defined as:

template <typename T, Requires<tt::is_a_v<std::vector, T>> = nullptr>
std::string foo(const T& /*unused*/) {
return "vector";
}

then calling the function with a list, foo(std::list<double>{}); results in the following compilation error from clang:

./tests/Unit/Utilities/Test_Requires.cpp:29:3: error: no matching function
for call to 'foo'
^~~
./tests/Unit/Utilities/Test_Requires.cpp:15:13: note: candidate
template ignored: substitution failure [with T = std::__1::list<double,
std::__1::allocator<double> >]: no type named
'template_error_type_failed_to_meet_requirements_on_template_parameters'
in 'Requires_detail::requires_impl<false>'
std::string foo(const T&) {
^
1 error generated.
ReturnType call(const std::string &module_name, const std::string &function_name, const Args &... t)
Calls a Python function from a module/file with given parameters.
Definition: Pypp.hpp:660

Here is an example of how write function overloads using Requires or to express constraints on the template parameters:

// [foo_definition]
template <typename T, Requires<tt::is_a_v<std::vector, T>> = nullptr>
std::string foo(const T& /*unused*/) {
return "vector";
}
// [foo_definition]
template <typename T, Requires<tt::is_a_v<std::list, T>> = nullptr>
std::string foo(const T& /*unused*/) {
return "list";
}
Note
Using Requires is safer than using std::enable_if_t because the nested type alias is of type std::nullptr_t and so usage is always:
template <typename T, Requires<(bool depending on T)> = nullptr>

Function Documentation

◆ accumulate()

template<class InputIt , class T >
constexpr T cpp2b::accumulate ( InputIt  first,
InputIt  last,
init 
)
constexpr

Reimplementation of std::accumulate that is constexpr; taken from the LLVM source at https://github.com/llvm-mirror/libcxx/blob/master/include/numeric

◆ apply() [1/2]

template<typename ApplyTags , typename F , typename... Tags>
constexpr decltype(auto) tuples::apply ( F &&  f,
const TaggedTuple< Tags... > &  t 
)
constexpr

Invoke f with the ApplyTags taken from t expanded in a parameter pack.

ApplyTags defaults to the full list of tags in t.

Here is an example how to use the function:

const double extra_factor = 3.;
const double result = tuples::apply(
[&extra_factor](const auto&... expanded_args) {
return extra_factor * test_function(expanded_args...);
},
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:264
constexpr decltype(auto) apply(F &&f, const TaggedTuple< Tags... > &t)
Invoke f with the ApplyTags taken from t expanded in a parameter pack.
Definition: TaggedTuple.hpp:746

This is the function being called in the above example:

struct FirstArg {
using type = int;
};
struct SecondArg {
using type = double;
};
double test_function(const int first_arg, const double second_arg) {
return static_cast<double>(first_arg) + second_arg;
}
See also
std::apply

◆ apply() [2/2]

template<typename F , typename... Tags>
constexpr decltype(auto) tuples::apply ( F &&  f,
const TaggedTuple< Tags... > &  t 
)
constexpr

Invoke f with the ApplyTags taken from t expanded in a parameter pack.

ApplyTags defaults to the full list of tags in t.

Here is an example how to use the function:

const double extra_factor = 3.;
const double result = tuples::apply(
[&extra_factor](const auto&... expanded_args) {
return extra_factor * test_function(expanded_args...);
},

This is the function being called in the above example:

struct FirstArg {
using type = int;
};
struct SecondArg {
using type = double;
};
double test_function(const int first_arg, const double second_arg) {
return static_cast<double>(first_arg) + second_arg;
}
See also
std::apply

◆ call_with_dynamic_type()

template<typename Result , typename Classes , typename Base , typename Callable , typename... Args>
Result call_with_dynamic_type ( Base *const  obj,
Callable &&  f,
Args &&...  args 
)

Call a functor with the derived type of a base class pointer.

Details

Calls functor with obj cast to type T* where T is the dynamic type of *obj. The decay type of T must be in the provided list of classes.

Extra arguments can be passed by const& to the functor.

Template Parameters
Resultthe return type
Classesthe typelist of derived classes

◆ cartesian_product() [1/3]

template<typename... Containers>
std::vector< std::tuple< typename Containers::value_type... > > cartesian_product ( const Containers &...  containers)

The Cartesian product of several containers.

Returns a std::vector with all possible combinations of the values of the input containers. The value of the last container varies fastest.

◆ cartesian_product() [2/3]

template<typename... Ts, size_t... Lens>
std::array< std::tuple< Ts... >,(... *Lens)> cartesian_product ( const std::array< Ts, Lens > &...  dimensions)

The Cartesian product of a sequence of arrays.

Returns a std::array with all possible combinations of the input arrays. The last dimension varies fastest.

Example

Here's an example using this function to replace a nested for loop:

for (const auto& [halves, orientation, with_equiangular_map,
with_adapted_equiangular_map, radial_distribution] :
random_sample<5>(
halves_array, all_wedge_directions(), make_array(true, false),
make_array(true, false),
make_array(CoordinateMaps::Distribution::Linear,
CoordinateMaps::Distribution::Linear,
CoordinateMaps::Distribution::Linear,
CoordinateMaps::Distribution::Logarithmic,
CoordinateMaps::Distribution::Inverse)),
make_not_null(&gen))) {
std::array< OrientationMap< 3 >, 6 > all_wedge_directions()
Wedge OrientationMap in each of the six directions used in the Sphere domain creator.
Definition: TestMapHelpers.hpp:871
void cartesian_product(OutputIterator result, std::pair< InputIterator, InputIterator >... dimensions)
Fill the result iterator with the Cartesian product of a sequence of iterators.
Definition: CartesianProduct.hpp:49
constexpr std::array< T, Size > make_array(Args &&... args)
Create a std::array<T, Size>{{T(args...), T(args...), ...}}
Definition: MakeArray.hpp:65

◆ cartesian_product() [3/3]

template<class OutputIterator , class... InputIterator>
void cartesian_product ( OutputIterator  result,
std::pair< InputIterator, InputIterator >...  dimensions 
)

Fill the result iterator with the Cartesian product of a sequence of iterators.

The result will hold all possible combinations of the input iterators. The last dimension varies fastest.

◆ create_vector_of_n_copies()

template<typename VectorType >
VectorType create_vector_of_n_copies ( const VectorType &  to_copy,
const size_t  times_to_copy 
)

Creates or fills a vector with data from to_repeat copied times_to_repeat times in sequence.

Details

This can be useful for generating data that consists of the same block of values duplicated a number of times. For instance, this can be used to create a vector representing three-dimensional volume data from a corresponding two-dimensional vector data, if the two-dimensional data corresponds to the two fastest-varying directions of the desired three-dimensional representation. The result would then be uniform in the slowest-varying direction of the three dimensional grid.

◆ ddot_()

double ddot_ ( const size_t &  N,
const double *  X,
const size_t &  INCX,
const double *  Y,
const size_t &  INCY 
)
inline

The dot product of two vectors.

Parameters
Nthe length of the vectors.
Xa pointer to the first element of the first vector.
INCXthe stride for the elements of the first vector.
Ya pointer to the first element of the second vector.
INCYthe stride for the elements of the second vector.

Returns: the dot product of the given vectors.

◆ dgemm_()

template<bool UseLibXsmm = false>
void dgemm_ ( const char &  TRANSA,
const char &  TRANSB,
const size_t &  M,
const size_t &  N,
const size_t &  K,
const double &  ALPHA,
const double *  A,
const size_t &  LDA,
const double *  B,
const size_t &  LDB,
const double &  BETA,
double *  C,
const size_t &  LDC 
)
inline

Perform a matrix-matrix multiplication.

Perform the matrix-matrix multiplication

\[ C = \alpha \mathrm{op}(A) \mathrm{op}(B) + \beta \mathrm{op}(C) \]

where \(\mathrm{op}(A)\) represents either \(A\) or \(A^{T}\) (transpose of \(A\)).

LIBXSMM, which is much faster than BLAS for small matrices, can be called instead of BLAS by passing the template parameter true.

Parameters
TRANSAeither 'N', 'T' or 'C', transposition of matrix A
TRANSBeither 'N', 'T' or 'C', transposition of matrix B
MNumber of rows in \(\mathrm{op}(A)\)
NNumber of columns in \(\mathrm{op}(B)\) and \(\mathrm{op}(C)\)
KNumber of columns in \(\mathrm{op}(A)\)
ALPHAspecifies \(\alpha\)
AMatrix \(A\)
LDASpecifies first dimension of \(\mathrm{op}(A)\)
BMatrix \(B\)
LDBSpecifies first dimension of \(\mathrm{op}(B)\)
BETAspecifies \(\beta\)
CMatrix \(C\)
LDCSpecifies first dimension of \(\mathrm{op}(C)\)
Template Parameters
UseLibXsmmif true then use LIBXSMM

◆ dgemm_< true >()

template<>
void dgemm_< true > ( const char &  TRANSA,
const char &  TRANSB,
const size_t &  M,
const size_t &  N,
const size_t &  K,
const double &  ALPHA,
const double *  A,
const size_t &  LDA,
const double *  B,
const size_t &  LDB,
const double &  BETA,
double *  C,
const size_t &  LDC 
)
inline

Perform a matrix-matrix multiplication.

Perform the matrix-matrix multiplication

\[ C = \alpha \mathrm{op}(A) \mathrm{op}(B) + \beta \mathrm{op}(C) \]

where \(\mathrm{op}(A)\) represents either \(A\) or \(A^{T}\) (transpose of \(A\)).

LIBXSMM, which is much faster than BLAS for small matrices, can be called instead of BLAS by passing the template parameter true.

Parameters
TRANSAeither 'N', 'T' or 'C', transposition of matrix A
TRANSBeither 'N', 'T' or 'C', transposition of matrix B
MNumber of rows in \(\mathrm{op}(A)\)
NNumber of columns in \(\mathrm{op}(B)\) and \(\mathrm{op}(C)\)
KNumber of columns in \(\mathrm{op}(A)\)
ALPHAspecifies \(\alpha\)
AMatrix \(A\)
LDASpecifies first dimension of \(\mathrm{op}(A)\)
BMatrix \(B\)
LDBSpecifies first dimension of \(\mathrm{op}(B)\)
BETAspecifies \(\beta\)
CMatrix \(C\)
LDCSpecifies first dimension of \(\mathrm{op}(C)\)
Template Parameters
UseLibXsmmif true then use LIBXSMM

◆ dgemv_()

void dgemv_ ( const char &  TRANS,
const size_t &  M,
const size_t &  N,
const double &  ALPHA,
const double *  A,
const size_t &  LDA,
const double *  X,
const size_t &  INCX,
const double &  BETA,
double *  Y,
const size_t &  INCY 
)
inline

Perform a matrix-vector multiplication.

\[ y = \alpha \mathrm{op}(A) x + \beta y \]

where \(\mathrm{op}(A)\) represents either \(A\) or \(A^{T}\) (transpose of \(A\)).

Parameters
TRANSeither 'N', 'T' or 'C', transposition of matrix A
MNumber of rows in \(\mathrm{op}(A)\)
NNumber of columns in \(\mathrm{op}(A)\)
ALPHAspecifies \(\alpha\)
AMatrix \(A\)
LDASpecifies first dimension of \(\mathrm{op}(A)\)
XVector \(x\)
INCXSpecifies the increment for the elements of \(x\)
BETASpecifies \(\beta\)
YVector \(y\)
INCYSpecifies the increment for the elements of \(y\)

◆ dot() [1/3]

template<typename T , typename R >
decltype(auto) dot ( const std::array< T, 1 > &  first,
const std::array< R, 1 > &  second 
)

Dot product between two arrays.

Details

This also works elementwise if T is a container and R is a float or the other way round. The return type will always be the same as the return type of the multiplication which may be a blaze expression template.

◆ dot() [2/3]

template<typename T , typename R >
decltype(auto) dot ( const std::array< T, 2 > &  first,
const std::array< R, 2 > &  second 
)

Dot product between two arrays.

Details

This also works elementwise if T is a container and R is a float or the other way round. The return type will always be the same as the return type of the multiplication which may be a blaze expression template.

◆ dot() [3/3]

template<typename T , typename R >
decltype(auto) dot ( const std::array< T, 3 > &  first,
const std::array< R, 3 > &  second 
)

Dot product between two arrays.

Details

This also works elementwise if T is a container and R is a float or the other way round. The return type will always be the same as the return type of the multiplication which may be a blaze expression template.

◆ equal_within_roundoff()

template<typename Lhs , typename Rhs >
constexpr bool equal_within_roundoff ( const Lhs &  lhs,
const Rhs &  rhs,
const double  eps = std::numeric_limits<double>::epsilon() * 100.0,
const double  scale = 1.0 
)
constexpr

Checks if two values lhs and rhs are equal within roundoff, by comparing abs(lhs - rhs) < (max(abs(lhs), abs(rhs)) + scale) * eps.

The two values can be floating-point numbers, or any types for which EqualWithinRoundoffImpls::EqualWithinRoundoffImpl has been specialized. For example, a default implementation exists for the case where lhs, rhs, or both, are iterable, and compares the values point-wise.

◆ evaluate_polynomial()

template<typename CoeffsIterable , typename DataType >
DataType evaluate_polynomial ( const CoeffsIterable &  coeffs,
const DataType &  x 
)

Evaluate a polynomial \(\sum_{p=0}^N c_p x^p\) with Horner's rule.

Parameters
coeffsThe polynomial coefficients \(c_p\) ordered from constant to largest power
xThe polynomial variable \(x\)
Template Parameters
CoeffsIterableThe type of the polynomial coefficients coeffs. Can be a std::vector<double> or std::array<double>, which means the coefficients are constant for all values in x. Each coefficient can also be a vector type of typically the same size as x, which means the coefficients vary with the elements in x.
DataTypeThe type of the polynomial variable x. Must support make_with_value<DataType, DataType>, as well as (elementwise) addition with CoeffsIterable::value_type and multiplication with DataType.

◆ expand_pack()

template<typename... Ts>
constexpr void expand_pack ( Ts &&  ...)
constexpr

Allows zero-cost unordered expansion of a parameter.

Details

Expands a parameter pack, typically useful for runtime evaluation via a Callable such as a lambda, function, or function object. For example, an unordered transform of a std::tuple can be implemented as:

template <typename... Elements, size_t... Is>
const auto func = [](const auto& in, auto& out) {
out = in * static_cast<decltype(in)>(2);
return 0;
};
expand_pack(func(std::get<Is>(tupull), std::get<Is>(out_tupull))...);
}
void test_expand_pack() {
std::tuple<int, double, float> my_tupull = std::make_tuple(3, 2.7, 8.2);
transform(my_tupull, my_tupull_output, std::make_index_sequence<3>{});
CHECK(std::get<0>(my_tupull_output) == 6);
CHECK(std::get<1>(my_tupull_output) == 5.4);
CHECK(std::get<2>(my_tupull_output) == 16.4f);
}
constexpr void expand_pack(Ts &&...)
Allows zero-cost unordered expansion of a parameter.
Definition: TMPL.hpp:578
See also
tuple_fold tuple_counted_fold tuple_transform std::tuple EXPAND_PACK_LEFT_TO_RIGHT

◆ fill_with_n_copies()

template<typename VectorType >
void fill_with_n_copies ( const gsl::not_null< VectorType * >  result,
const VectorType &  to_copy,
const size_t  times_to_copy 
)

Creates or fills a vector with data from to_repeat copied times_to_repeat times in sequence.

Details

This can be useful for generating data that consists of the same block of values duplicated a number of times. For instance, this can be used to create a vector representing three-dimensional volume data from a corresponding two-dimensional vector data, if the two-dimensional data corresponds to the two fastest-varying directions of the desired three-dimensional representation. The result would then be uniform in the slowest-varying direction of the three dimensional grid.

◆ find()

template<class InputIt , class T >
constexpr InputIt cpp20::find ( InputIt  first,
InputIt  last,
const T &  value 
)
constexpr

Reimplementation of std::find that is constexpr

◆ find_if()

template<class InputIt , class UnaryPredicate >
constexpr InputIt cpp20::find_if ( InputIt  first,
InputIt  last,
UnaryPredicate  p 
)
constexpr

Reimplementation of std::find_if that is constexpr

◆ find_if_not()

template<class InputIt , class UnaryPredicate >
constexpr InputIt cpp20::find_if_not ( InputIt  first,
InputIt  last,
UnaryPredicate  q 
)
constexpr

Reimplementation of std::find_if_not that is constexpr

◆ formatted_string()

template<typename... Args>
std::string formatted_string ( const std::string fmt,
Args...  args 
)

Format a string like printf.

Given a formatting string and arguments this returns the corresponding string. Similar to printf but using std::strings.

◆ get_element()

template<typename T , typename SubscriptFunction = GetContainerElement>
decltype(auto) get_element ( T &  t,
const size_t  i,
SubscriptFunction  at = GetContainerElement{} 
)

Returns the ith element if T has a subscript operator, otherwise if T is fundamental or a std::complex of a fundamental type, returns t.

Details

This function also optionally takes the user-defined subscript function at, which can be used to specify a custom indexing function. For instance, for a type which is a std::array of a std::arrays, the indexing function could be the below callable struct:

struct ArrayOfArraysIndexFunctor {
template <size_t OuterArraySize, size_t InnerArraySize, typename T>
T& operator()(std::array<std::array<T, InnerArraySize>, OuterArraySize>&
array_of_arrays,
size_t index) {
return array_of_arrays.at(index % OuterArraySize)
.at(index / OuterArraySize);
}
};

which would index the data structure in a manner in which the outer array index varies fastest. The indexing function must take as arguments the applicable container and a size_t index, in that order. This follows the convention of gsl::at.

Note
std::complex are regarded as non-indexable (despite a predictable memory layout), so this function acts as the identity on std::complex of fundamental types

◆ get_size()

template<typename T , typename SizeFunction = GetContainerSize>
decltype(auto) get_size ( const T &  t,
SizeFunction  size = GetContainerSize{} 
)

Retrieve the size of t if t.size() is a valid expression, otherwise if T is fundamental or a std::complex of a fundamental type, returns 1.

Details

This function also optionally takes the user-defined size function, which can be used to specify a custom size function. For instance, for a type which is a std::array of a std::array, the size function could be the below callable struct:

struct ArrayOfArraysSizeFunctor {
template <size_t OuterArraySize, size_t InnerArraySize, typename T>
size_t operator()(
const std::array<std::array<T, InnerArraySize>, OuterArraySize>&
/*array_of_arrays*/) {
return OuterArraySize * InnerArraySize;
}
};

The size function must take the single argument of the applicable container, and should return a size_t. This follows the convention of std::size() as of C++17.

Note
std::complex are regarded as non-indexable (despite a predictable memory layout), so this function will return 1 for a std::complex of a fundamental type

◆ iota()

template<class ForwardIterator , class T >
constexpr void cpp2b::iota ( ForwardIterator  first,
ForwardIterator  last,
value 
)
constexpr

Reimplementation of std::iota that is constexpr; taken from the LLVM source at https://github.com/llvm-mirror/libcxx/blob/master/include/numeric

◆ iter_swap()

template<class ForwardIt1 , class ForwardIt2 >
constexpr void cpp20::iter_swap ( ForwardIt1  a,
ForwardIt2  b 
)
constexpr

Reimplementation of std::iter_swap that is constexpr; taken from the LLVM source at https://github.com/llvm-mirror/libcxx/blob/master/include/type_traits

◆ magnitude() [1/3]

template<typename T >
decltype(auto) magnitude ( const std::array< T, 1 > &  a)

Euclidean magnitude of the elements of the array.

Details

If T is a container the magnitude is computed separately for each element of the container.

Requires: If T is a container, T must have following mathematical operators: abs(), sqrt(), and element-wise addition and multiplication. In addition, each T in the array must have the same size.

◆ magnitude() [2/3]

template<typename T >
decltype(auto) magnitude ( const std::array< T, 2 > &  a)

Euclidean magnitude of the elements of the array.

Details

If T is a container the magnitude is computed separately for each element of the container.

Requires: If T is a container, T must have following mathematical operators: abs(), sqrt(), and element-wise addition and multiplication. In addition, each T in the array must have the same size.

◆ magnitude() [3/3]

template<typename T >
decltype(auto) magnitude ( const std::array< T, 3 > &  a)

Euclidean magnitude of the elements of the array.

Details

If T is a container the magnitude is computed separately for each element of the container.

Requires: If T is a container, T must have following mathematical operators: abs(), sqrt(), and element-wise addition and multiplication. In addition, each T in the array must have the same size.

◆ make_array() [1/3]

template<size_t Size, typename T , typename... Args>
constexpr std::array< T, Size > make_array ( Args &&...  args)
constexpr

Create a std::array<T, Size>{{T(args...), T(args...), ...}}

Template Parameters
Sizethe size of the array
Tthe type of the element in the array

◆ make_array() [2/3]

template<typename T , size_t size, typename Seq >
constexpr std::array< T, size > make_array ( Seq &&  seq)
constexpr

Create an std::array<T, size> from the first size values of seq

Requires: Seq has a begin function

Template Parameters
Tthe type held by the array
sizethe size of the created array

◆ make_array() [3/3]

template<size_t Size, typename T >
constexpr auto make_array ( T &&  t) -> std::array<std::decay_t<T>, Size>
constexpr

Create a std::array<std::decay_t<T>, Size>{{t, t, ...}}

Template Parameters
Sizethe size of the array

◆ next_permutation() [1/2]

template<class BidirectionalIterator >
constexpr bool cpp20::next_permutation ( BidirectionalIterator  first,
BidirectionalIterator  last 
)
constexpr

Reimplementation of std::next_permutation that is constexpr, with less as the comparator; taken from the LLVM source at https://github.com/llvm-mirror/libcxx/blob/master/include/algorithm

◆ next_permutation() [2/2]

template<class Compare , class BidirectionalIterator >
constexpr bool cpp20::next_permutation ( BidirectionalIterator  first,
BidirectionalIterator  last,
Compare  comp 
)
constexpr

Reimplementation of std::next_permutation that is constexpr, for a generic comparator; taken from the LLVM source at https://github.com/llvm-mirror/libcxx/blob/master/include/algorithm

◆ outer_product() [1/2]

template<typename LhsVectorType , typename RhsVectorType , typename ResultVectorType = typename blaze::MultTrait<LhsVectorType, RhsVectorType>::Type>
void outer_product ( const gsl::not_null< ResultVectorType * >  result,
const LhsVectorType &  lhs,
const RhsVectorType &  rhs 
)

Computes the outer product between two vectors.

Details

For vectors \(A\) and \(B\), the resulting outer product is \(\{A_1 B_1,\, A_2 B_1\, \dots\, A_N B_1,\, A_1 B_2\, \dots\, A_N B_M\}\). This is useful for generating separable volume data from its constituent inputs.

◆ outer_product() [2/2]

template<typename LhsVectorType , typename RhsVectorType , typename ResultVectorType = typename blaze::MultTrait<LhsVectorType, RhsVectorType>::Type>
ResultVectorType outer_product ( const LhsVectorType &  lhs,
const RhsVectorType &  rhs 
)

Computes the outer product between two vectors.

Details

For vectors \(A\) and \(B\), the resulting outer product is \(\{A_1 B_1,\, A_2 B_1\, \dots\, A_N B_1,\, A_1 B_2\, \dots\, A_N B_M\}\). This is useful for generating separable volume data from its constituent inputs.

◆ pretty_wall_time() [1/2]

std::string sys::pretty_wall_time ( )

Format the wall time in DD-HH:MM:SS format.

If the walltime is shorter than a day, omit the DD- part.

◆ pretty_wall_time() [2/2]

std::string sys::pretty_wall_time ( double  total_seconds)

Format the wall time in DD-HH:MM:SS format.

If the walltime is shorter than a day, omit the DD- part.

◆ print_stl()

template<typename T >
void print_stl ( std::ostream os,
const T &  t 
)

Equivalent to os << t.

For some reason this sometimes works when trying to stream directly doesn't find our STL container stream operators.

◆ reverse()

template<class BidirectionalIterator >
constexpr void cpp20::reverse ( BidirectionalIterator  first,
BidirectionalIterator  last 
)
constexpr

Reimplementation of std::reverse that is constexpr; taken from the LLVM source at https://github.com/llvm-mirror/libcxx/blob/master/include/algorithm

◆ simplest_fraction_in_interval()

template<typename Fraction , typename T1 , typename T2 >
Fraction simplest_fraction_in_interval ( const T1 &  end1,
const T2 &  end2 
)

Find the fraction in the supplied interval with the smallest denominator.

The endpoints are considered to be in the interval. The order of the arguments is not significant. The answer is unique as long as the interval has length less than 1; for longer intervals, an integer in the range will be returned.

◆ smoothstep()

template<size_t N, typename DataType >
DataType smoothstep ( const double  lower_edge,
const double  upper_edge,
const DataType &  arg 
)

Smoothly interpolates from 0 to 1 between lower_edge and upper_edge with a Hermite polynomial of degree 2 * N + 1.

The smoothstep function is

\begin{align*} S_N(x) = \begin{cases} 0 &\quad \text{for} \quad x\leq x_0 \\ \tilde{S}_N((x - x_0) / (x_1 - x_0)) &\quad \text{for} \quad x_0 \leq x\leq x_1 \\ 1 &\quad \text{for} \quad x_1\leq x \\ \end{cases} \end{align*}

where \(x_0\) is lower_edge, \(x_1\) is upper_edge, and, up to \(N=3\),

\begin{align*} \tilde{S}_0(x) &= x \\ \tilde{S}_1(x) &= 3x^2 - 2x^3 \\ \tilde{S}_2(x) &= 10x^3 - 15x^4 + 6x^5 \\ \tilde{S}_3(x) &= 35x^4 - 84x^5 + 70x^6 - 20x^7 \text{.} \end{align*}

◆ split_tuple()

template<typename SizeList , typename... TupleTypes>
constexpr auto split_tuple ( std::tuple< TupleTypes... >  tuple)
constexpr

Split a std::tuple into multiple tuples.

Note
There are two functions with this name, but doxygen can't figure that out. They have signatures
template <typename SizeList, typename... TupleTypes>
constexpr auto split_tuple(std::tuple<TupleTypes...> tuple);
template <size_t... Sizes, typename... TupleTypes>
constexpr auto split_tuple(std::tuple<TupleTypes...> tuple);
constexpr auto split_tuple(std::tuple< TupleTypes... > tuple)
Split a std::tuple into multiple tuples.
Definition: SplitTuple.hpp:60

Given a list of sizes, either directly as template parameters or as a typelist of integral constant types, split the passed tuple into pieces containing the specified number of entries. The passed sizes must sum to the size of the tuple.

Returns: a std::tuple of std::tuples

See also
std::tuple_cat for the inverse operation.
static_assert(split_tuple<2, 1>(std::tuple{1, 2, 3}) ==
static_assert(split_tuple<tmpl::integral_list<size_t, 2, 1>>(std::tuple{
1, 2, 3}) == std::tuple{std::tuple{1, 2}, std::tuple{3}});

◆ swap()

template<class T >
constexpr void cpp20::swap ( T &  a,
T &  b 
)
constexpr

Reimplementation of std::swap that is constexpr; taken from the LLVM source at https://github.com/llvm-mirror/libcxx/blob/master/include/type_traits

◆ tuple_counted_fold()

template<bool ReverseIteration = false, typename... Elements, typename N_aryOp , typename... Args>
constexpr void tuple_counted_fold ( const std::tuple< Elements... > &  tuple,
N_aryOp &&  op,
Args &&...  args 
)
inlineconstexpr

Perform a fold over a std::tuple.

Details

Iterates over the elements in a std::tuple tuple from left to right (left fold) calling op(element, args...) on each element in tuple. A right fold can be done by explicitly setting the first template parameter to true. Folds are easily implemented using tuple_fold by updating one of the args... at each iteration. If you need the index of the current element you can use the tuple_counted_fold variant. tuple_counted_fold passes the current index as the second argument to the Callable op. That is, op(element, index, args...).

Example

The sum of a std::tuple of Arithmetics can be computed in several ways. First, you can use a lambda:

const auto my_tupull = std::make_tuple(2, 7, -3.8, 20.9);
double sum_value = 0.0;
tuple_fold(my_tupull,
[](const auto& element, double& state) { state += element; },
sum_value);
CHECK(sum_value == approx(26.1));
constexpr void tuple_fold(const std::tuple< Elements... > &tuple, N_aryOp &&op, Args &&... args)
Perform a fold over a std::tuple.
Definition: Tuple.hpp:90

You'll notice that state is taken by reference and mutated.

You can do the same thing with a struct defined as

template <typename T>
struct tuple_fold_plus {
T value = 0.0;
template <typename S>
void operator()(const S& element) {
value += element;
}
};

and then using an instance of the struct

const auto my_tupull = std::make_tuple(2, 7, -3.8, 20.9);
tuple_fold_plus<double> sum_value{};
tuple_fold(my_tupull, sum_value);
CHECK(sum_value.value == approx(26.1));
Note
You are not able to pass a function pointer to tuple_fold or tuple_counted_fold because you cannot pass a pointer to a function template, only a function.
See also
expand_pack tuple_transform tuple_fold tuple_counted_fold std::tuple

◆ tuple_fold()

template<bool ReverseIteration = false, typename... Elements, typename N_aryOp , typename... Args>
constexpr void tuple_fold ( const std::tuple< Elements... > &  tuple,
N_aryOp &&  op,
Args &&...  args 
)
inlineconstexpr

Perform a fold over a std::tuple.

Details

Iterates over the elements in a std::tuple tuple from left to right (left fold) calling op(element, args...) on each element in tuple. A right fold can be done by explicitly setting the first template parameter to true. Folds are easily implemented using tuple_fold by updating one of the args... at each iteration. If you need the index of the current element you can use the tuple_counted_fold variant. tuple_counted_fold passes the current index as the second argument to the Callable op. That is, op(element, index, args...).

Example

The sum of a std::tuple of Arithmetics can be computed in several ways. First, you can use a lambda:

const auto my_tupull = std::make_tuple(2, 7, -3.8, 20.9);
double sum_value = 0.0;
tuple_fold(my_tupull,
[](const auto& element, double& state) { state += element; },
sum_value);
CHECK(sum_value == approx(26.1));

You'll notice that state is taken by reference and mutated.

You can do the same thing with a struct defined as

template <typename T>
struct tuple_fold_plus {
T value = 0.0;
template <typename S>
void operator()(const S& element) {
value += element;
}
};

and then using an instance of the struct

const auto my_tupull = std::make_tuple(2, 7, -3.8, 20.9);
tuple_fold_plus<double> sum_value{};
tuple_fold(my_tupull, sum_value);
CHECK(sum_value.value == approx(26.1));
Note
You are not able to pass a function pointer to tuple_fold or tuple_counted_fold because you cannot pass a pointer to a function template, only a function.
See also
expand_pack tuple_transform tuple_fold tuple_counted_fold std::tuple

◆ tuple_transform()

template<bool ReverseIteration = false, typename... Elements, typename N_aryOp , typename... Args>
constexpr void tuple_transform ( const std::tuple< Elements... > &  tuple,
N_aryOp &&  op,
Args &&...  args 
)
inlineconstexpr

Perform a transform over a std::tuple.

Details

Iterates over the elements in a std::tuple tuple from left to right calling op.operator()(element, index, args...) on each element in tuple. A right-to-left transform can be done by explicitly setting the first template parameter to true. The second argument of the invokable will be a deduced std::integral_constant<size_t, value>, from which the current index can be extracted by using decltype(index)::value. For a function object the decltype(index) can be replaced by the deduced type of index. For example,

struct negate {
template <typename T, typename Index, typename S>
void operator()(const T& element, Index /*index*/,
S& second_tuple_element) const {
std::get<Index::value>(second_tuple_element) = -element;
}
};

Using tuple_transform with a generic lambda goes as follows,

const auto my_tupull = std::make_tuple(2, 7, -3.8, 20.9);
std::decay_t<decltype(my_tupull)> out_tupull;
tuple_transform(my_tupull,
[](const auto& element, auto index, auto& out_tuple) {
constexpr size_t index_v = decltype(index)::value;
std::get<index_v>(out_tuple) = -element;
},
out_tupull);
CHECK(std::get<0>(out_tupull) == -2);
CHECK(std::get<1>(out_tupull) == -7);
CHECK(std::get<2>(out_tupull) == 3.8);
CHECK(std::get<3>(out_tupull) == -20.9);
constexpr void tuple_transform(const std::tuple< Elements... > &tuple, N_aryOp &&op, Args &&... args)
Perform a transform over a std::tuple.
Definition: Tuple.hpp:129
See also
expand_pack tuple_fold tuple_counted_fold std::tuple

◆ unordered_print_helper() [1/2]

template<typename ForwardIt >
void unordered_print_helper ( std::ostream out,
ForwardIt  begin,
const ForwardIt &  end 
)

Like sequence_print_helper, but sorts the string representations.

◆ unordered_print_helper() [2/2]

template<typename ForwardIt , typename Func >
void unordered_print_helper ( std::ostream out,
ForwardIt  begin,
const ForwardIt &  end,
Func  f 
)

Like sequence_print_helper, but sorts the string representations.

◆ wrap_text()

std::string wrap_text ( std::string  str,
size_t  line_length,
const std::string indentation = "" 
)

Wrap the string str so that it is no longer than line_length and indent each new line with indentation. The first line is also indented.

Single words longer than line_length are hyphenated.

◆ zgemm_()

template<bool UseLibXsmm = false>
void zgemm_ ( const char &  TRANSA,
const char &  TRANSB,
const size_t &  M,
const size_t &  N,
const size_t &  K,
const std::complex< double > &  ALPHA,
const std::complex< double > *  A,
const size_t &  LDA,
const std::complex< double > *  B,
const size_t &  LDB,
const std::complex< double > &  BETA,
std::complex< double > *  C,
const size_t &  LDC 
)
inline

Perform a matrix-matrix multiplication.

Perform the matrix-matrix multiplication

\[ C = \alpha \mathrm{op}(A) \mathrm{op}(B) + \beta \mathrm{op}(C) \]

where \(\mathrm{op}(A)\) represents either \(A\) or \(A^{T}\) (transpose of \(A\)).

LIBXSMM, which is much faster than BLAS for small matrices, can be called instead of BLAS by passing the template parameter true.

Parameters
TRANSAeither 'N', 'T' or 'C', transposition of matrix A
TRANSBeither 'N', 'T' or 'C', transposition of matrix B
MNumber of rows in \(\mathrm{op}(A)\)
NNumber of columns in \(\mathrm{op}(B)\) and \(\mathrm{op}(C)\)
KNumber of columns in \(\mathrm{op}(A)\)
ALPHAspecifies \(\alpha\)
AMatrix \(A\)
LDASpecifies first dimension of \(\mathrm{op}(A)\)
BMatrix \(B\)
LDBSpecifies first dimension of \(\mathrm{op}(B)\)
BETAspecifies \(\beta\)
CMatrix \(C\)
LDCSpecifies first dimension of \(\mathrm{op}(C)\)
Template Parameters
UseLibXsmmif true then use LIBXSMM

Variable Documentation

◆ flat_all_v

template<bool... Bs>
constexpr bool tmpl2::flat_all_v = flat_all<Bs...>::value
constexpr

A non-short-circuiting logical AND between bools 'B"".

Useful when arbitrarily large parameter packs need to be evaluated, since std::conjunction and std::disjunction use recursion

◆ flat_any_v

template<bool... Bs>
constexpr bool tmpl2::flat_any_v = flat_any<Bs...>::value
constexpr

A non-short-circuiting logical OR between bools 'B"".

Useful when arbitrarily large parameter packs need to be evaluated, since std::conjunction and std::disjunction use recursion