An emulation library for C++11-onward's "user defined literals" concept, providing a more compatible interface intended to also work in C++03. Built as an extension to the cxxomfort backports library. http://ryan.gulix.cl/fossil.cgi/cxxomfort/

Git Admin 8b29ace0ab Corrections to integral affixes. 5 years ago
library 8b29ace0ab Corrections to integral affixes. 5 years ago
tests 8b29ace0ab Corrections to integral affixes. 5 years ago
LICENSE 70707cba9f Initial commit 5 years ago
README.md 11df1df1bf Initial commit. 5 years ago

README.md

cxxo-literal_affixes

An emulation library for C++11-onward's "user defined literals" concept, providing a more compatible interface intended to also work in C++03.

Built as an extension to the cxxomfort backports library.

Brief on 'user-defined literals'

From C++11 onwards: "user-defined literals" extend notations for literals in source code so that literal expressions of integer or char-array type can be used to construct objects of user-defined types. They are implemented as suffixes to the value expression.

// {integer_expression}i --> "imaginary" std::complex<double>
// {"string_expression"}s --> std::string

template <typename T> foo (T const& t);

foo ("Hello World");  // Calls foo<char[...]>
foo ("Hello World"s); // calls foo<std::string>

auto i1 = 1001; // i1: int(1001)
auto i2 = 1001i; // i2: std::complex<double>(0,1001)

All is good and well except for one problem:

They don't work in C++03.

Hence, they fall under the domain of cxxomfort to work on.

What cxxo-literal_affixes does

Well... as the opening says, this library is a supplement to cxxomfort that emulates user-defined literal suffixes. This is done by providing an inheritance interface to construct a functio object, declaring the return_type of the suffix, and from there create a variable/object that is the actual "operator".

const struct MyUDL
: affix_implementation<return_type, implementation_stuff> {
    return_type operator() (unsigned long long u) {
        return somefunction(u); 
    }
} my; // <-- entry point for MAGIC

The resulting object, let's say my, can be used in two ways:

template <typename T> foo (T const& t);

foo (31);      // calls foo<int>
foo (31 | my); // suffix form: calls foo<MyT::return_type>
foo (my(31));  // object form: calls foo<MyT::return_type>
               // ...should there be a prefix form? Who knows...

auto i1 = 1002;       // i1: int
auto i2 = 1003 | my;  // i2: MyT::return_type

As it can be see, the new object can be used both as a suffix or as a wrapper/circumfix - that is, as various form of affixes. Hence, the name of this library is not "literal_suffixes" as per the C++11 UDL operators but rather literal_affixes.

Of course, the emulation also includes a layer for compatibility with C++11 UDL operators. It is possible to declare an equivalent C++11 UDL operator that will share the same name (and will be invoked with leading underscore as in _my as is the designation for userspace UDL operators):

const struct MyT { ... } my; // same as before

CXXO_GENERATE_AFFIX2_FOR(my); 
// form 2 is operator"" (unsigned long long).
// there are other forms AFFIX3, AFFIX4, ...  depending on the operator needed.
// The source code provides more details.

// ... later in code

foo (41);      // calls foo<int>
foo (42 | my); // suffix form: calls foo<MyT::return_type>
foo (43_my);   // UDL-operator form: calls foo<MyT::return_type>

Included Affixes

The repository provides seven affixes by default, all of which must be includes and using'd explicitly:

Defined by "library/affixes/integral.hpp"

  • 999 | hu : integer_constant to unsigned short, because short , as used in eg.: printf ; short types are among the ones that do not get any literal or lexical suffix to identify them in C/C++.
  • 999 | hi : integral_constant to short , the signed counterpart to the above. See, shorties always gets the short end of the stick in C++ (see what I did there?)
  • 12345678901 | ju : integral_constant to uintmax_t, as used in eg.: printf.
  • 5000 | zu : integer_constant to size_t, as used in eg.: printf and proposed in p0330r0 and subsequent. Useful for indexing in for loops whose index type is size_t (eg.: STL containers).

Defined by "library/affix/complex.hpp"

  • 3.1415 | i : floating_constant to a std::complex<double> with the real part set to zero: z = 0+3.1415i.

Defined by "library/affixes/string.hpp"

  • "Hello World" | s : character string literal to std::basic_string<character_type>. Works with char and wchar_t string literals (eg.: with "foo" and L"foo").

Defined by "library/affixes/hexdump.hpp"

  • "c001deadbeef" | hxd : char string literal to a std::vector<char>. Essentially reads a hexdump copied into the source file and generates the corresponding "blob" as a STL container.

Other affixes for demonstration purposes only

  • 400 | dbl - from int to int, but the numeric value is double (here it returns int(800)).
  • 400 | hlf - from int to int, but the numeric value is halved (here it returns int(200)).
  • "Hello World" | aesth - from std::string to std::string but turns boring, normal ASCII text into glorious AESTHETIC TEXT (aka "CJK fullwidth forms").

License

Library extension released under the GNU LGPL; see LICENSE.