sharg 1.0.0
THE argument parser for bio-c++ tools.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages Concepts
type_name_as_string.hpp
Go to the documentation of this file.
1// --------------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2022, Knut Reinert & MPI für molekulare Genetik
4// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5// shipped with this file and also available at: https://github.com/seqan/sharg-parser/blob/main/LICENSE.md
6// --------------------------------------------------------------------------------------------------------
7
13#pragma once
14
15#if defined(__GNUC__) || defined(__clang__)
16# include <cxxabi.h>
17#endif // defined(__GNUC__) || defined(__clang__)
18
19#include <functional>
20#include <memory>
21#include <string>
22#include <typeinfo>
23
24#include <sharg/platform.hpp>
25
26namespace sharg::detail
27{
28
42template <typename type>
43inline std::string const type_name_as_string = []()
44{
45 std::string demangled_name{};
46#if defined(__GNUC__) || defined(__clang__) // clang and gcc only return a mangled name.
47 using safe_ptr_t = std::unique_ptr<char, std::function<void(char *)>>;
48
49 // https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a01696.html
50 int status{};
51 safe_ptr_t demangled_name_ptr{abi::__cxa_demangle(typeid(type).name(), 0, 0, &status),
52 [](char * name_ptr)
53 {
54 free(name_ptr);
55 }};
56
57 // We exclude status != 0, because this code can't be reached normally, only if there is a defect in the compiler
58 // itself, since the type is directly given by the compiler. See https://github.com/seqan/seqan3/pull/2311.
59 // LCOV_EXCL_START
60 // clang-format off
61 if (status != 0)
62 return std::string{typeid(type).name()} +
63 " (abi::__cxa_demangle error status (" + std::to_string(status) + "): " +
64 (status == -1 ? "A memory allocation failure occurred." :
65 (status == -2 ? "mangled_name is not a valid name under the C++ ABI mangling rules." :
66 (status == -3 ? "One of the arguments is invalid." : "Unknown Error"))) + ")";
67 // clang-format on
68 // LCOV_EXCL_STOP
69
70 demangled_name = std::string{std::addressof(*demangled_name_ptr)};
71#else // e.g. MSVC
72 demangled_name = typeid(type).name();
73#endif // defined(__GNUC__) || defined(__clang__)
74
75 if constexpr (std::is_const_v<std::remove_reference_t<type>>)
76 demangled_name += " const";
77 if constexpr (std::is_lvalue_reference_v<type>)
78 demangled_name += " &";
79 if constexpr (std::is_rvalue_reference_v<type>)
80 demangled_name += " &&";
81
82 return demangled_name;
83}();
84
85} // namespace sharg::detail
T addressof(T... args)
T free(T... args)
Provides platform and dependency checks.
T to_string(T... args)