Utility module

Template metaprogramming utilities and type manipulation tools.

The Utility module provides a comprehensive set of template metaprogramming utilities for type manipulation, parameter pack handling, and compile-time computations used throughout the Rodin finite element library.

Classes

template<class T>
struct Rodin::Utility::BottomTemplate
Metafunction to extract the innermost (bottom) type from nested templates.
template<template<class> class T, class S>
struct Rodin::Utility::BottomTemplate<T<S>>
Specialization for single-parameter template instantiations.
template<class From, class To>
class Rodin::Utility::Cast
Template for defining type conversion operations.
template<class T, T Value_, class ... Args>
struct Rodin::Utility::DependentValue
Creates a type-dependent compile-time constant value.
template<class ...>
struct Rodin::Utility::Extract
Template metafunction for extracting types from tuple structures.
template<class T, class ... Ts>
struct Rodin::Utility::Extract<Tuple<T, Ts...>>
Specialization of Extract for Tuple types.
template<typename T, typename = void>
struct Rodin::Utility::HasTypeMember
Type trait to detect if a type has a nested Type member.
template<class T>
struct Rodin::Utility::HasTypeMember<T, std::void_t<typename T::Type>>
Specialization for types that have a nested Type member.
template<typename T, typename = void>
struct Rodin::Utility::HasValueMember
Type trait to detect if a type has a nested Value member type.
template<class T>
struct Rodin::Utility::HasValueMember<T, std::void_t<typename T::Value>>
Specialization for types that have a nested Value member type.
template<typename T, T... Is>
class Rodin::Utility::IntegerSequence
Represents a compile-time sequence of integers.
template<typename ...>
struct Rodin::Utility::IsOneOf
Type trait to check if a type is one of a specified list of types.
template<typename F, typename S, typename ... T>
struct Rodin::Utility::IsOneOf<F, S, T...>
Specialization for non-empty type lists.
template<class Test, template<class...> class Ref>
struct Rodin::Utility::IsSpecialization
Type trait to check if a type is a specialization of a given template.
template<template<class...> class Ref, class... Args>
struct Rodin::Utility::IsSpecialization<Ref<Args...>, Ref>
Specialization for types that are specializations of the reference template.
template<class T>
struct Rodin::Utility::Make
Factory template for perfect forwarding construction.
template<typename T>
class Rodin::Utility::OptionalReference
A wrapper providing optional reference semantics.
template<class... Ts>
struct Rodin::Utility::Overloaded
Helper type for creating overloaded function objects from lambdas.
template<std::size_t N, class ... Types>
struct Rodin::Utility::Internal::AtImpl
Internal implementation for accessing parameter pack elements by index.
template<class First, class ... Rest>
struct Rodin::Utility::Internal::AtImpl<0, First, Rest...>
Base case specialization for index 0.
template<std::size_t N, class First, class ... Rest>
struct Rodin::Utility::Internal::AtImpl<N, First, Rest...>
Recursive case for index N > 0.
template<template<class> class Predicate, class ...>
struct Rodin::Utility::Internal::AllImpl
Internal implementation for checking if all types satisfy a predicate.
template<template<class> class Predicate, class T1>
struct Rodin::Utility::Internal::AllImpl<Predicate, T1>
Base case for a single type.
template<template<class> class Predicate, class T1, class T2, class ... Ts>
struct Rodin::Utility::Internal::AllImpl<Predicate, T1, T2, Ts...>
Recursive case for multiple types.
template<class ... Params>
class Rodin::Utility::ParameterPack
Template metaprogramming utilities for parameter packs.
template<class ...>
struct Rodin::Utility::Product
Metafunction to compute the Cartesian product of two Tuple type-lists.
template<class H1, class H2, class ... Hs, class ... Gs>
struct Rodin::Utility::Product<Tuple<H1, H2, Hs...>, Tuple<Gs...>>
Specialization for Tuple with at least two elements (H1, H2, Hs…).
template<class H, class ... Gs>
struct Rodin::Utility::Product<Tuple<H>, Tuple<Gs...>>
Specialization for Tuple with exactly one element.
template<class ... Gs>
struct Rodin::Utility::Product<Tuple<>, Tuple<Gs...>>
Specialization for empty first Tuple.
template<class ... Gs>
struct Rodin::Utility::Product<Tuple<Gs...>, Tuple<>>
Specialization for empty second Tuple.
template<size_t N, class T>
struct Rodin::Utility::Repeat
Metafunction to create a Tuple with N repetitions of type T.
template<class T>
struct Rodin::Utility::Repeat<0, T>
Specialization for N = 0.
template<class T>
struct Rodin::Utility::Repeat<1, T>
Specialization for N = 1.
template<class T>
struct Rodin::Utility::UnwrapReference
Metafunction to unwrap std::reference_wrapper types.
template<class U>
struct Rodin::Utility::UnwrapReference<std::reference_wrapper<U>>
Specialization for std::reference_wrapper.
template<class T>
struct Rodin::Utility::UnwrapRefDecay
Combines decay and reference unwrapping.
template<class ...>
class Rodin::Utility::Wrap
Metafunction to wrap all types in a Tuple with an external template.
template<class ... Ts>
class Rodin::Utility::Wrap<Tuple<Ts...>>
Specialization for Tuple types.
template<class ...>
struct Rodin::Utility::Zip
Metafunction to combine two Tuples element-wise using a binary template.
template<class ... Ts, class ... Gs>
struct Rodin::Utility::Zip<Tuple<Ts...>, Tuple<Gs...>>
Specialization for two Tuples.

Typedefs

template<class T>
using IsCompleteType = decltype(Internal::IsCompleteTypeImpl(std::declval<T*>()))
Type trait to detect if a type is complete (fully defined).

Functions

template<class F, class... Args>
void For(F&& f, Args && ... args) constexpr
Performs the application of a function over all arguments.
template<size_t N, class F>
void ForIndex(F&& f) constexpr
Executes a function N times with compile-time index access.
template<class T, std::size_t = sizeof(T)>
auto IsCompleteTypeImpl(T*) -> std::true_type
Helper function for IsCompleteType detection (complete type case).
auto IsCompleteTypeImpl(...) -> std::false_type
Helper function for IsCompleteType detection (incomplete type case).
template<class... Ts>
Overloaded(Ts...) -> Overloaded< Ts... >
Deduction guide for Overloaded.

Variables

template<class...>
bool False constexpr
Dependent false value for use in static_assert within template contexts.

Typedef documentation

template<class T>
using IsCompleteType = decltype(Internal::IsCompleteTypeImpl(std::declval<T*>()))

Type trait to detect if a type is complete (fully defined).

Template parameters
T The type to check.

A type is complete if its size is known (i.e., it has been fully defined). Incomplete types include forward declarations and array types of unknown bound.

This trait is useful for SFINAE-based conditional compilation when different behavior is needed for complete vs. incomplete types.

Example usage:

struct Complete { int x; };
struct Incomplete;

static_assert(IsCompleteType<Complete>::value == true);
static_assert(IsCompleteType<Incomplete>::value == false);

Function documentation

template<class F, class... Args>
void For(F&& f, Args && ... args) constexpr

Performs the application of a function over all arguments.

Template parameters
F The callable type.
Args The argument types.
Parameters
f The function to apply.
args The arguments to apply the function to.

This function uses fold expressions to apply the callable f to each argument in args in sequence. Useful for compile-time iteration over heterogeneous argument packs.

Example usage:

auto printer = [](auto x) { std::cout << x << " "; };
Utility::For(printer, 1, 2.5, "hello");
// Output: 1 2.5 hello

template<size_t N, class F>
void ForIndex(F&& f) constexpr

Executes a function N times with compile-time index access.

Template parameters
N Number of times to execute the function.
F Callable type.
Parameters
f Function to execute; receives an object with a v.value member for each iteration.

This utility enables compile-time loops where the loop index is available as a compile-time constant.

Example usage:

Utility::ForIndex<5>(
  [&](auto i){ std::cout << i.value << std::endl; });
// Output: 0 1 2 3 4

template<class T, std::size_t = sizeof(T)>
std::true_type IsCompleteTypeImpl(T*)

Helper function for IsCompleteType detection (complete type case).

This overload is selected when sizeof(T) is valid, indicating T is complete.

std::false_type IsCompleteTypeImpl(...)

Helper function for IsCompleteType detection (incomplete type case).

This fallback overload is selected when sizeof(T) is not valid.

template<class... Ts>
Overloaded(Ts...) -> Overloaded< Ts... >

Deduction guide for Overloaded.

Template parameters
Ts The types of the callable objects.

This deduction guide allows the compiler to automatically deduce the template parameters when constructing an Overloaded object from a set of callable objects.

Variable documentation

template<class...>
bool False constexpr

Dependent false value for use in static_assert within template contexts.

This utility provides a way to create a static_assert(false, ...) that only triggers when a template is actually instantiated, rather than when it is parsed. This is essential for implementing proper error messages in template specializations that should never be instantiated.

Example usage:

template <typename T>
struct MyStruct
{
    static_assert(Utility::False<T>, "This template should not be instantiated");
};

template <>
struct MyStruct<int>
{
    // Valid specialization
};