generated from seqan/app-template
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #40 from Irallia/MISC/Remove_dependency_of_seqan3_…
…type_name_as_string [MISC] Remove dependency of seqan3::detail::type_name_as_string.
- Loading branch information
Showing
5 changed files
with
148 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// ----------------------------------------------------------------------------------------------------------- | ||
// Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin | ||
// Copyright (c) 2016-2021, Knut Reinert & MPI für molekulare Genetik | ||
// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License | ||
// shipped with this file and also available at: https://github.com/seqan/sharg-parser/blob/master/LICENSE.md | ||
// ----------------------------------------------------------------------------------------------------------- | ||
|
||
/*!\file | ||
* \brief Provides traits to inspect some information of a type, for example its name. | ||
* \author Lydia Buntrock <lydia.buntrock AT fu-berlin.de> | ||
*/ | ||
|
||
#pragma once | ||
|
||
#if defined(__GNUC__) || defined(__clang__) | ||
#include <cxxabi.h> | ||
#endif // defined(__GNUC__) || defined(__clang__) | ||
|
||
#include <functional> | ||
#include <memory> | ||
#include <string> | ||
#include <typeinfo> | ||
|
||
#include <sharg/platform.hpp> | ||
|
||
namespace sharg::detail | ||
{ | ||
|
||
/*!\brief Defines the human-readable name of the given type using the | ||
[typeid](https://en.cppreference.com/w/cpp/language/typeid) operator. | ||
* | ||
* \tparam type The type to get the human-readable name for. | ||
* | ||
* \details | ||
* | ||
* On gcc and clang std::type_info only returns a mangled name. | ||
* The mangled name can be converted to human-readable form using implementation-specific API such as | ||
* abi::__cxa_demangle. In other implementations the name returned is already human-readable. | ||
* | ||
* \note The returned name is implementation defined and might change between different tool chains. | ||
*/ | ||
template <typename type> | ||
inline std::string const type_name_as_string = [] () | ||
{ | ||
std::string demangled_name{}; | ||
#if defined(__GNUC__) || defined(__clang__) // clang and gcc only return a mangled name. | ||
using safe_ptr_t = std::unique_ptr<char, std::function<void(char *)>>; | ||
|
||
// https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a01696.html | ||
int status{}; | ||
safe_ptr_t demangled_name_ptr{abi::__cxa_demangle(typeid(type).name(), 0, 0, &status), | ||
[] (char * name_ptr) { free(name_ptr); }}; | ||
|
||
// We exclude status != 0, because this code can't be reached normally, only if there is a defect in the compiler | ||
// itself, since the type is directly given by the compiler. See https://github.com/seqan/seqan3/pull/2311. | ||
// LCOV_EXCL_START | ||
if (status != 0) | ||
return std::string{typeid(type).name()} + | ||
" (abi::__cxa_demangle error status (" + std::to_string(status) + "): " + | ||
(status == -1 ? "A memory allocation failure occurred." : | ||
(status == -2 ? "mangled_name is not a valid name under the C++ ABI mangling rules." : | ||
(status == -3 ? "One of the arguments is invalid." : "Unknown Error"))) + ")"; | ||
// LCOV_EXCL_STOP | ||
|
||
demangled_name = std::string{std::addressof(*demangled_name_ptr)}; | ||
#else // e.g. MSVC | ||
demangled_name = typeid(type).name(); | ||
#endif // defined(__GNUC__) || defined(__clang__) | ||
|
||
if constexpr (std::is_const_v<std::remove_reference_t<type>>) | ||
demangled_name += " const"; | ||
if constexpr (std::is_lvalue_reference_v<type>) | ||
demangled_name += " &"; | ||
if constexpr (std::is_rvalue_reference_v<type>) | ||
demangled_name += " &&"; | ||
|
||
return demangled_name; | ||
}(); | ||
|
||
} // namespace sharg::detail |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// ----------------------------------------------------------------------------------------------------------- | ||
// Copyright (c) 2006-2021, Knut Reinert & Freie Universität Berlin | ||
// Copyright (c) 2016-2021, Knut Reinert & MPI für molekulare Genetik | ||
// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License | ||
// shipped with this file and also available at: https://github.com/seqan/sharg-parser/blob/master/LICENSE.md | ||
// ----------------------------------------------------------------------------------------------------------- | ||
|
||
#include <gtest/gtest.h> | ||
|
||
#include <type_traits> | ||
|
||
#include <sharg/detail/type_name_as_string.hpp> | ||
|
||
// Some test namespace to check if namespace information are preserved within the naming. | ||
namespace foo | ||
{ | ||
template <typename ...type> | ||
struct bar | ||
{}; | ||
} // namespace foo | ||
|
||
// Some types to test if type inspection works as expected. | ||
// Note that the returned name might differ between compiler vendors and thus must be adapted accordingly | ||
// in case this tests fails for those vendors. | ||
using reflection_types = ::testing::Types<char, char16_t const, char32_t &, short *, double const * const, | ||
foo::bar<char> const &, foo::bar<foo::bar<char, double>>>; | ||
|
||
template <typename param_type> | ||
class type_inspection : public ::testing::Test | ||
{ | ||
|
||
public: | ||
// Returns the name of the type according to the list of names defined above. | ||
std::string const expected_name() const | ||
{ | ||
if constexpr (std::is_same_v<param_type, char>) | ||
return "char"; | ||
else if constexpr (std::is_same_v<param_type, char16_t const>) | ||
return "char16_t const"; | ||
else if constexpr (std::is_same_v<param_type, char32_t &>) | ||
return "char32_t &"; | ||
else if constexpr (std::is_same_v<param_type, short *>) | ||
return "short*"; | ||
else if constexpr (std::is_same_v<param_type, double const * const>) | ||
return "double const* const"; | ||
else if constexpr (std::is_same_v<param_type, foo::bar<char> const &>) | ||
return "foo::bar<char> const &"; | ||
else if constexpr (std::is_same_v<param_type, foo::bar<foo::bar<char, double>>>) | ||
return "foo::bar<foo::bar<char, double> >"; | ||
else | ||
throw std::runtime_error{"Encountered unknown type in test."}; | ||
} | ||
}; | ||
|
||
// Register test. | ||
TYPED_TEST_SUITE(type_inspection, reflection_types, ); | ||
|
||
TYPED_TEST(type_inspection, type_name_as_string) | ||
{ | ||
EXPECT_EQ(sharg::detail::type_name_as_string<TypeParam>, this->expected_name()); | ||
} |
27a1533
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs: