Namespaces | Classes | Macros | Typedefs | Functions | Variables
Utilities

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

Namespaces

 alg
 Utility functions wrapping STL algorithms and additional algorithms.
 
 formaline
 Functions for retrieving system and source tree information.
 
 funcl
 Higher order function objects similar to std::plus, etc.
 
 gsl
 Implementations from the Guideline Support Library.
 
 Registration
 Helpers for derived class registration.
 
 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...
 
class  Overloader< Fs >
 Used for overloading lambdas, useful for lambda-SFINAE. More...
 
struct  PointerVector< Type, AF, PF, TF, ExprResultType >
 A raw pointer endowed with expression template support via the Blaze library. More...
 
class  Rational
 A rational number. More...
 
class  StaticCache< T, Ranges >
 A cache of objects intended to be stored in a static variable. More...
 
struct  CacheRange< Start, End >
 Range of values for StaticCache indices. The Start is inclusive and the End is exclusive. The range must not be empty. 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...
 
struct  cpp17::void_type
 Mark a return type as being "void". In C++17 void is a regular type under certain circumstances, so this can be replaced by void then. More...
 

Macros

#define DEFINE_FAKE_VIRTUAL(function)
 Define a function that acts similarly to a virtual function, but can take template parameters. More...
 
#define SPECTRE_ALWAYS_INLINE   inline
 Always inline a function. Only use this if you benchmarked the code.
 
#define SPECTRE_JUST_ALWAYS_INLINE
 Always inline a function, but do not mark it inline
 
#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<typename Sequence >
using make_boost_variant_over = typename detail::make_boost_variant_over_impl< tmpl::remove_duplicates< Sequence > >::type
 Create a boost::variant with all all the types inside the typelist Sequence. More...
 
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...
 

Functions

template<class T >
constexpr void cpp20::swap (T &a, T &b) noexcept
 
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)
 
double ddot_ (const size_t &N, const double *X, const size_t &INCX, const double *Y, const size_t &INCY)
 
template<typename... Ts>
std::string type_of_current_state (const boost::variant< Ts... > &variant) noexcept
 Get the type name of the current state of the boost::variant.
 
template<typename T , typename SubscriptFunction = GetContainerElement>
decltype(auto) get_element (T &t, const size_t i, SubscriptFunction at=GetContainerElement{}) noexcept
 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{}) noexcept
 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.
 
constexpr bool equal_within_roundoff (const double a, const double b, const double eps=std::numeric_limits< double >::epsilon() *100.0, const double scale=1.0) noexcept
 Checks if two values a and b are equal within roundoff, by comparing abs(a - b) < (max(abs(a), abs(b)) + scale) * eps.
 
template<typename Result , typename Classes , typename Base , typename Callable , Requires<(tmpl::size< Classes >::value !=0)> = nullptr>
Result call_with_dynamic_type (Base *const obj, Callable &&f) noexcept
 Call a functor with the derived type of a base class pointer. More...
 
template<typename Fraction , typename T1 , typename T2 >
Fraction simplest_fraction_in_interval (const T1 &end1, const T2 &end2) noexcept
 Find the fraction in the supplied interval with the smallest denominator. More...
 
template<typename T >
std::string get_output (const T &t) noexcept
 Get the streamed output of t as a std::string
 
template<class T , class U >
constexpr T gsl::narrow_cast (U &&u) noexcept
 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) noexcept(noexcept(MakeArray_detail::MakeArray< Size==0 >::template apply< T >(std::make_index_sequence<(Size==0 ? Size :Size - 1)>{}, std::forward< 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) noexcept(noexcept(MakeArray_detail::MakeArray< Size==0 >::template apply< std::decay_t< T >>(std::make_index_sequence<(Size==0 ? Size :Size - 1)>{}, std::forward< 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>
constexpr auto make_array (T &&t, V &&... values) noexcept(noexcept(std::array< std::decay_t< T >, sizeof...(V)+1 >{ {std::forward< T >(t), std::forward< 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) noexcept(noexcept(MakeArray_detail::make_array_from_iterator_impl< T, size >(std::forward< Seq >(seq), std::make_index_sequence< size >{})))
 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 U , typename T >
evaluate_polynomial (const std::vector< U > &coeffs, const T &x) noexcept
 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) noexcept
 Defines the Heaviside step function \(\Theta\) for arithmetic types. \(\Theta(0) = 1\).
 
template<typename T , Requires< std::is_arithmetic< T >::value or tt::is_a_v< std::complex, T >> = nullptr>
auto invsqrt (const T &arg) noexcept
 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) noexcept
 Defines the inverse cube-root ( \(1/\sqrt[3]{x}\)) for arithmetic types.
 
template<typename T >
constexpr T sgn (const T &val) noexcept
 Compute the sign function of val defined as 1 if val > 0, 0 if val == 0, and -1 if val < 0.
 
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<class... Fs>
Overloader< Fs... > make_overloader (Fs... fs)
 Create Overloader<Fs...>, see Overloader for details.
 
template<typename ForwardIt , typename Func >
void sequence_print_helper (std::ostream &out, ForwardIt &&begin, ForwardIt &&end, Func f) noexcept
 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, ForwardIt &&end) noexcept
 Prints all the items as a comma separated list surrounded by parens.
 
template<typename... Ranges, typename Generator >
auto make_static_cache (Generator &&generator) noexcept
 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) noexcept
 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) noexcept
 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) noexcept
 Construct an array from an existing array prepending a value.
 
template<typename T , size_t Dim, typename F >
auto map_array (const std::array< T, Dim > &array, const F &f) noexcept
 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 >
std::ostreamoperator<< (std::ostream &os, const std::unordered_set< T > &v)
 Output the items of a std::unordered_set.
 
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 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.
 
template<typename... Ts>
constexpr void expand_pack (Ts &&...) noexcept
 Allows zero-cost unordered expansion of a parameter. More...
 
template<typename T , typename... Ts>
decltype(auto) constexpr get_first_argument (T &&t, Ts &&...) noexcept
 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) noexcept(noexcept(tuple_impl_detail::tuple_transform_impl< ReverseIteration >(tuple, std::forward< N_aryOp >(op), std::make_index_sequence< sizeof...(Elements)>{}, args...)))
 Perform a transform over a std::tuple. 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...
 
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<>
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 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]) noexcept
 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 &) noexcept
 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 > &) noexcept
 Returns an appropriate signaling NaN for fundamantal or multi-field types (such as std::complex).
 
template<typename T >
make_signaling_NaN () noexcept
 Returns an appropriate signaling NaN for fundamantal or multi-field types (such as std::complex).
 
template<typename ForwardIt , typename Func >
void unordered_print_helper (std::ostream &out, ForwardIt &&begin, ForwardIt &&end, Func f) noexcept
 
template<typename ForwardIt >
void unordered_print_helper (std::ostream &out, ForwardIt &&begin, ForwardIt &&end) noexcept
 
template<typename T >
magnitude (const std::array< T, 1 > &a) noexcept
 Euclidean magnitude of the elements of the array. More...
 
template<>
double magnitude (const std::array< double, 1 > &a) noexcept
 Euclidean magnitude of the elements of the array. More...
 
template<typename T >
magnitude (const std::array< T, 2 > &a) noexcept
 Euclidean magnitude of the elements of the array. More...
 
template<typename T >
magnitude (const std::array< T, 3 > &a) noexcept
 Euclidean magnitude of the elements of the array. More...
 
template<class Tag , class... Tags>
constexpr const Tag::type & tuples::get (const TaggedTuple< Tags... > &t) noexcept
 Retrieve the element of Tag in the TaggedTuple.
 
template<class Tag , class... Tags>
constexpr Tag::type & tuples::get (TaggedTuple< Tags... > &t) noexcept
 Retrieve the element of Tag in the TaggedTuple.
 
template<class Tag , class... Tags>
constexpr const Tag::type && tuples::get (const TaggedTuple< Tags... > &&t) noexcept
 Retrieve the element of Tag in the TaggedTuple.
 
template<class Tag , class... Tags>
constexpr Tag::type && tuples::get (TaggedTuple< Tags... > &&t) noexcept
 Retrieve the element of Tag in the TaggedTuple.
 
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) noexcept(noexcept(tuple_impl_detail::tuple_fold_impl< ReverseIteration >(tuple, std::forward< N_aryOp >(op), std::make_index_sequence< sizeof...(Elements)>{}, 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) noexcept(noexcept(tuple_impl_detail::tuple_counted_fold_impl< ReverseIteration >(tuple, std::forward< N_aryOp >(op), std::make_index_sequence< sizeof...(Elements)>{}, args...)))
 Perform a fold over a std::tuple. More...
 

Detailed Description

A collection of useful classes, functions and metafunctions.

Macro Definition Documentation

◆ DEFINE_FAKE_VIRTUAL

#define DEFINE_FAKE_VIRTUAL (   function)
Value:
/* This struct is only needed for producing an error if the function */ \
/* is not overridden in the derived class. */ \
template <typename Base> \
struct FakeVirtualInherit_##function : public Base { \
using Base::Base; \
/* clang-tidy: I think "= delete" was overlooked in the guideline */ \
void function(...) const = delete; /* NOLINT */ \
}; \
\
template <typename Classes, typename... TArgs, typename Base, \
typename... Args> \
decltype(auto) fake_virtual_##function(Base* obj, Args&&... args) noexcept { \
/* clang-tidy: macro arg in parentheses */ \
return call_with_dynamic_type< \
decltype(obj->template function<TArgs...>(args...)), /* NOLINT */ \
Classes>( \
obj, [&args...](auto* const dynamic_obj) noexcept -> decltype(auto) { \
static_assert( \
cpp17::is_base_of_v<typename Base::Inherit, \
std::decay_t<decltype(*dynamic_obj)>>, \
"Derived class does not inherit from Base::Inherit"); \
/* clang-tidy: macro arg in parentheses */ \
return dynamic_obj->template function<TArgs...>(/* NOLINT */ \
std::forward<Args>( \
args)...); \
}); \
}

Define a function that acts similarly to a virtual function, but can take template parameters.

Details

DEFINE_FAKE_VIRTUAL(func) defines the function fake_virtual_func and the struct FakeVirtualInherit_func. It should usually be called in a detail namespace.

A base class Base using this functionality should define a type

using Inherit = FakeVirtualInherit_func<Base>;

and a member function func wrapping fake_virtual_func, with the wrapper passing the derived classes as a typelist as the first template argument and the this pointer as the first normal argument.

Derived classes should then inherit from Base::Inherit instead of directly from Base. (Base::Inherit inherits from Base.)

If the base class has no pure virtual functions remaining it will generally be desirable to mark the constructors and assignment operators protected so that a bare base class cannot be instantiated.

If it is necessary to use multiple fake virtual functions with the same base class, the Inherit definition can nest the fake virtual classes:

using Inherit = FakeVirtualInherit_func1<FakeVirtualInherit_func2<Base>>;

Example

class Derived;
class Base {
public:
using Inherit = FakeVirtualInherit_fv<Base>;
protected:
Base() = default;
Base(const Base&) = default;
Base(Base&&) = default;
Base& operator=(const Base&) = default;
Base& operator=(Base&&) = default;
public:
virtual ~Base() = default;
template <typename T>
int fv(int x) {
return fake_virtual_fv<tmpl::list<Derived>, T>(this, x);
}
};
class Derived : public Base::Inherit {
public:
template <typename T>
int fv(int x) {
return x + 3;
}
};
See also
call_with_dynamic_type

◆ 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) noexcept { \
std::array<RESULT_TYPE, Dim> result; /*NOLINT*/ \
std::transform(lhs.begin(), lhs.end(), rhs.begin(), result.begin(), \
BINARY_OP); \
return result; \
}

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( \
const std::array<RTYPE, Dim>& rhs) noexcept { \
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);
}
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

This will generate:

template class Index<0>;
template class Index<1>;
template class Index<2>;
template class Index<3>;

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) noexcept;
#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) noexcept;
template bool operator!=(const Index<0>& lhs, const Index<0>& rhs) noexcept;
template class Index<1>;
template bool operator==(const Index<1>& lhs, const Index<1>& rhs) noexcept;
template bool operator!=(const Index<1>& lhs, const Index<1>& rhs) noexcept;
template class Index<2>;
template bool operator==(const Index<2>& lhs, const Index<2>& rhs) noexcept;
template bool operator!=(const Index<2>& lhs, const Index<2>& rhs) noexcept;
template class Index<3>;
template bool operator==(const Index<3>& lhs, const Index<3>& rhs) noexcept;
template bool operator!=(const Index<3>& lhs, const Index<3>& rhs) noexcept;

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 noexcept; \
template Scalar<DTYPE(data)> \
ScalarWave::Solutions::PlaneWave<DIM(data)>::dpsi_dt( \
const tnsr::I<DTYPE(data), DIM(data)>& x, double t) const noexcept;
GENERATE_INSTANTIATIONS(INSTANTIATE, (1, 2, 3), (double, DataVector))
#undef DIM
#undef DTYPE
#undef INSTANTIATE

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 cpp17::conjunction and cpp17::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 cpp17::conjunction and cpp17::disjunction use recursion

◆ make_boost_variant_over

template<typename Sequence >
using make_boost_variant_over = typename detail::make_boost_variant_over_impl< tmpl::remove_duplicates<Sequence> >::type

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

Returns: boost::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.

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 
)

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

◆ call_with_dynamic_type()

template<typename Result , typename Classes , typename Base , typename Callable , Requires<(tmpl::size< Classes >::value !=0)> = nullptr>
Result call_with_dynamic_type ( Base *const  obj,
Callable &&  f 
)
noexcept

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.

See also
DEFINE_FAKE_VIRTUAL
Template Parameters
Resultthe return type
Classesthe typelist of derived classes

◆ 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\)

◆ evaluate_polynomial()

template<typename U , typename T >
T evaluate_polynomial ( const std::vector< U > &  coeffs,
const T &  x 
)
noexcept

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
UThe type of the polynomial coefficients coeffs. Can be double, which means the coefficients are constant for all values in x. Can also be a vector type of typically the same size as T, which means the coefficients vary with the elements in x.
TThe type of the polynomial variable x. Must support make_with_value<T, T>, as well as (elementwise) addition with U and multiplication with T.

◆ expand_pack()

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

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:

namespace {
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))...);
}
} // namespace
SPECTRE_TEST_CASE("Unit.Utilities.expand_pack", "[Utilities][Unit]") {
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);
}
See also
tuple_fold tuple_counted_fold tuple_transform std::tuple EXPAND_PACK_LEFT_TO_RIGHT

◆ 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{} 
)
noexcept

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) noexcept {
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{} 
)
noexcept

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*/) noexcept {
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 
)

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 
)

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/4]

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

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/4]

template<>
double magnitude ( const std::array< double, 1 > &  a)
inlinenoexcept

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/4]

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

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() [4/4]

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

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)
noexcept

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<size_t Size, typename T >
constexpr auto make_array ( T &&  t) -> std::array<std::decay_t<T>, Size>
noexcept

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

Template Parameters
Sizethe size of the array

◆ make_array() [3/3]

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

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

◆ next_permutation() [1/2]

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

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

◆ next_permutation() [2/2]

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

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

◆ reverse()

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

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 
)
noexcept

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.

◆ swap()

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

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 
)
inlinenoexcept

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_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 
)
inlinenoexcept

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 
)
inlinenoexcept

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 noexcept {
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);
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);
See also
expand_pack tuple_fold tuple_counted_fold std::tuple

◆ unordered_print_helper() [1/2]

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

Like sequence_print_helper, but sorts the string representations.

◆ unordered_print_helper() [2/2]

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

Like sequence_print_helper, but sorts the string representations.

Variable Documentation

◆ flat_all_v

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

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

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

◆ flat_any_v

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

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

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