Home

Awesome

type_name_pp

C++ templates for pretty-printing type names and 'auto' names

<details><summary>Copyright &copy; 2019 Will Wray. Distributed under the Boost Software License, V1.0</summary>

Boost Software License - Version 1.0 - August 17th, 2003

Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:

The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

License

Also at boost.org and accompanying file LICENSE_1_0.txt

</details>

C++17. Targets GCC, Clang, MSVC.
Namespace ltl.
Depends on ltl lib ntbs.hpp for constexpr C-string slicing.
Uses non-standard, non-portable 'pretty function' compiler extensions.
Tested with recent compilers only.

Variable templates type_name_pp and auto_name_pp are defined in namespace ltl,
taking type T and auto v template arguments:

  ltl::type_name_pp<T>; // 'Pretty print' name for type T.
  ltl::auto_name_pp<v>; // 'Pretty print' output for auto/NTTP value v.

The result is a 'constexpr C-string', a null-terminated char array class type that is
usable as a generic char[N] (including decay-to-pointer, for const values only).

For convenience, _pu versions return the string that follows any final "::" separator:

  ltl::type_name_pu<T>; // type name with leading qualifiers stripped.
  ltl::auto_name_pu<v>; // auto name with leading qualifiers stripped.

The names are sliced from preprocessor 'pretty function' extensions:

           __FUNCSIG__         on MSVC
           __PRETTY_FUNCTION__ on GCC, Clang

These are constexpr-usable strings of unspecified format that differs between compilers
and between releases of a compiler; this method is not backward or forward compatible.
This library does not provide portable names. Test for your use-case and target platforms.

Usage examples

Simple fundamental type int:

  puts( ltl::type_name_pp<int> ); // Outputs "int"

Namespace-scope struct type (an incomplete struct type here):

  namespace Hello { struct World; }
  puts( ltl::type_name_pp<Hello::World> );
  // Outputs             "Hello::World"    on GCC & Clang
  // or           "struct Hello::World"    on MSVC

Use decltype(expr) to query the type of an expression such as a variable:

  const volatile char abc[1][2][3]{};
  std::cout << type_name_pp<decltype(abc)>;

Outputs:

"const volatile char[1][2][3]" on GCC9
"char const volatile[1][2][3]" on Clang8
"volatile const char[1][2][3]" on MSVC 19.22.xxxxx

String splicing

The output may include nested name qualifiers for scoped types and ids.
'type_name_pu' and 'auto_name_pu' help to 'unqualify' simple names.
Templated types may list their template arguments, recursively...

For more complex name-string-splicing, the included ntbs lib provides
function templates cat(C-strings...) and cut<B,E>(C-string)
where B,E are signed-integer indices for the range [B,E):

Design notes

As noted, 'pretty function' output is fickle. I've observed that most changes
between versions of a compiler affect the start of the output, the 'prefix',
while the end of the output, the 'suffix', has stayed relatively stable.
The library functions assume a fixed suffix string and adapt to prefix changes
by comparing with a call for type int or value 0.

The returned char array type has an implicit conversion (for const values only)
to its contained built-in char array, which itself decays to const char*.
This implicit conversion to char array is convenient for compatibility with:

Build

Be sure to keep the copyright and license with any copy of the library header
as well as the GitHub repo link.

As a single header lib there's really nothing to build.
The only dependency is the ntbs single-header library.

A simple Meson build script is provided which will automatically clone ntbs
(assuming network access) as a git submodule subproject.

Example with default ninja backend:

meson build
ninja -C build

On Windows, Meson can target various backends including vs2019.
An MSI installer for Meson and Ninja is available on the Meson GitHub release page.

The meson build compiles a test file with static asserts that are likely to fail
on any slightly different platform.

Linux TravisWindows Appveyor
gcc-9, clang-7<br>-std=c++17MSVC 19.21.27702.2<br>/std:c++latest
Build StatusBuild status