Home

Awesome

Constant eXpression Library (abbreviated cxl)

Fundamental Utilities

include/cxl/utility.hpp contains basic template types and functions that are used across the whole library, such as cxl::index_t which is used in place of size_t and as indices, it should be a signed integer type capable of holding relatively large values, it is signed to allow negative indices. anything that requires a huge unsigned integer as an index value should probably not be done at compile-time. cxl::select_t<N, Types...> selects the Nth type in Types.... cxl::index_range<Indices...> holds a parameter pack of cxl::index_t, and provides some methods:

template function cxl::make_index_range<index_t First, index_t Last>() returns:

template function cxl::pow<auto N, auto E>() is a compile time power/exponent function:

Aggregate

include/cxl/aggregate.hpp contains the aggregate sublibrary. this sublibrary allows converting arbitrary aggregate class type objects into tuples of their member variables, or converting a sequence of variables into a struct. to convert a struct to tuple pass it into cxl::destructure(...), if it is an lvalue the tuple contains references to the members, otherwise it contains copied values. to make a struct out of a sequence of variables pass them into cxl::make_struct(...).

Integral

include/cxl/integral.hpp contains templated user-defined literal operators that allow you to easily convert literals to std::integral_constant<...>s.

Iterator

include/cxl/iterator.hpp contains an adaptable constexpr iterator class cxl::iterator<...> which can support any constexpr class that implements the following methods properly:

String

include/cxl/string.hpp contains a string class cxl::string<...> with a completely constexpr compatible interface. It also supports the cxl::iterator<...>s. Elements can be accesed through an iterator, operator[] or converting to const char*. String can be created through a macro STR("string"), because C++17 does not support templated user-defined string literals. The long way would be cxl::string<'s','t','r','i','n','g'>{}

Typelist

include/cxl/typelist.hpp contains the typelist sublibrary which has a few transform functions and different ways to apply/expand a typelist into a user template. It is compatible with the iterator sublibrary.

methods for empty typelists include:

methods for non-empty typelists include:

Parse

include/cxl/parse*.hpp headers contain the parsing sublibrary in cxl::parse namespace. There are a handful of predefined fundamental parsers, which operate on cxl::string<...>s. These parsers can be combined in many different ways to create more complex parsers. When a parse operation is performed using the parser, it will return a cxl::parse::parsed<...> that can tell you if the parse was a success, how far the parser matched, what remains to be parsed and a generated typelist. subparsers can generate custom types, however if they do not, the generated type will be a cxl::string<...> filled with what the subparser matched. custom generated types are just a templated class taking a parameter pack. see example csv parser-generator in example/csv

For example, here is a default generating parser:

using namespace cxl::parse;
constexpr auto parser = one_string(STR("abc"));
constexpr auto result = parser.parse(STR("abc"));

in this case result.tree() would return a typelist<string<'a','b','c'>>

But if we have a custom generated type:

template<typename... T>
struct synth{};

using namespace cxl::parse;
constexpr auto parser = one_string(STR("abc")).generate(synth<>{});
constexpr auto result = parser.parse(STR("abc"));

now result.tree() will return a typelist<synth<string<'a','b','c'>>>.

Built-in parser classes include:

Parser Generator