Add a way to use typename without relying on __PRETTY_FUNCTION__

This is now enabled by default in doorkeeper.
This commit is contained in:
King_DuckZ 2015-06-28 01:23:01 +02:00
parent 7140ee6b38
commit 9f9ab65ff3
8 changed files with 98 additions and 55 deletions

View file

@ -6,7 +6,10 @@ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++11 -g -O0 -Wall -Wex
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11 -O3 -Wall -Wextra") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++11 -O3 -Wall -Wextra")
#string(COMPARE EQUAL CMAKE_BINARY_DIR CMAKE_SOURCE_DIR IN_SOURCE_BUILD) #string(COMPARE EQUAL CMAKE_BINARY_DIR CMAKE_SOURCE_DIR IN_SOURCE_BUILD)
add_definitions(-DWITH_VECTOR_IOSTREAM) add_definitions(
-DWITH_VECTOR_IOSTREAM
-DUSE_MANUAL_TYPENAMES
)
find_library(Boost 1.53.0 REQUIRED) find_library(Boost 1.53.0 REQUIRED)
@ -21,7 +24,7 @@ target_include_directories(${PROJECT_NAME}
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/lib/sprout INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/lib/sprout
) )
add_subdirectory(lib/sprout) #add_subdirectory(lib/sprout)
add_subdirectory(src) add_subdirectory(src)
add_subdirectory(test) add_subdirectory(test)
add_subdirectory(game) add_subdirectory(game)

View file

@ -1,6 +1,7 @@
#include "doorkeeper/doorkeeper2d.hpp" #include "doorkeeper/doorkeeper2d.hpp"
#include "doorkeeper/helpers/maploader.hpp" #include "doorkeeper/helpers/maploader.hpp"
#include "doorkeeper/helpers/asciimapsource.hpp" #include "doorkeeper/helpers/asciimapsource.hpp"
#include "doorkeeper/helpers/typename_native.hpp"
#include "gameConfig.h" #include "gameConfig.h"
#include <iostream> #include <iostream>

View file

@ -15,10 +15,13 @@
# error "Unknown compiler" # error "Unknown compiler"
#endif #endif
#if defined(IS_PRETTY_FUNC_CONSTEXPR) #if defined(IS_PRETTY_FUNC_CONSTEXPR) || defined(USE_MANUAL_TYPENAMES)
# include "sprout/string.hpp" # include "sprout/string.hpp"
# include "doorkeeper/implem/tiger_bt.hpp" # include "doorkeeper/implem/tiger_bt.hpp"
# include <stdexcept> # include <stdexcept>
# if defined(USE_MANUAL_TYPENAMES)
# include "sprout/cstring/strlen.hpp"
# endif
#else #else
# include <string> # include <string>
#endif #endif
@ -27,20 +30,27 @@
#include <ciso646> #include <ciso646>
namespace dk { namespace dk {
#if !defined(IS_PRETTY_FUNC_CONSTEXPR) #if !defined(IS_PRETTY_FUNC_CONSTEXPR) && !defined(USE_MANUAL_TYPENAMES)
struct HashType { struct HashType {
uint64_t a; uint64_t a;
uint64_t b; uint64_t b;
uint64_t c; uint64_t c;
}; };
#endif #endif
#if defined(USE_MANUAL_TYPENAMES)
template <typename T>
constexpr const char* manual_type_name ( void ) a_pure;
#endif
bool operator< ( const HashType& parL, const HashType& parR ); bool operator< ( const HashType& parL, const HashType& parR );
namespace implem { namespace implem {
HashType hash_string ( const char* parString, std::size_t parLen ) a_pure; HashType hash_string ( const char* parString, std::size_t parLen ) a_pure;
#if defined(IS_PRETTY_FUNC_CONSTEXPR) #if defined(IS_PRETTY_FUNC_CONSTEXPR) || defined(USE_MANUAL_TYPENAMES)
template <typename T>
constexpr std::size_t type_name_len ( void ) a_pure;
template <typename T> template <typename T>
struct type_name_info { struct type_name_info {
constexpr type_name_info ( void ); constexpr type_name_info ( void );
@ -48,20 +58,17 @@ namespace dk {
const std::size_t len; const std::size_t len;
const char* const str; const char* const str;
}; };
template <typename T>
constexpr std::size_t type_name_len ( void ) a_pure;
#endif #endif
} //namespace implem } //namespace implem
template <typename T> template <typename T>
#if defined(IS_PRETTY_FUNC_CONSTEXPR) #if defined(IS_PRETTY_FUNC_CONSTEXPR) || defined(USE_MANUAL_TYPENAMES)
constexpr constexpr
#endif #endif
HashType type_name_hash ( void ) a_pure; HashType type_name_hash ( void ) a_pure;
template <typename T> template <typename T>
#if defined(IS_PRETTY_FUNC_CONSTEXPR) #if defined(IS_PRETTY_FUNC_CONSTEXPR) || defined(USE_MANUAL_TYPENAMES)
constexpr sprout::string<implem::type_name_len<T>()> type_name ( void ) a_pure; constexpr sprout::string<implem::type_name_len<T>()> type_name ( void ) a_pure;
#else #else
std::string type_name ( void ) a_pure; std::string type_name ( void ) a_pure;

View file

@ -0,0 +1,31 @@
#ifndef id8138A90B1FE448908902F69738CF6C4C
#define id8138A90B1FE448908902F69738CF6C4C
#include <cstdint>
#include "doorkeeper/helpers/typename.hpp"
namespace dk {
#if defined(USE_MANUAL_TYPENAMES)
template<> constexpr const char* manual_type_name<bool>() a_pure;
template<> constexpr const char* manual_type_name<float>() a_pure;
template<> constexpr const char* manual_type_name<double>() a_pure;
template<> constexpr const char* manual_type_name<long double>() a_pure;
template<> constexpr const char* manual_type_name<uint8_t>() a_pure;
template<> constexpr const char* manual_type_name<uint16_t>() a_pure;
template<> constexpr const char* manual_type_name<uint32_t>() a_pure;
template<> constexpr const char* manual_type_name<uint64_t>() a_pure;
template<> constexpr const char* manual_type_name<int8_t>() a_pure;
template<> constexpr const char* manual_type_name<int16_t>() a_pure;
template<> constexpr const char* manual_type_name<int32_t>() a_pure;
template<> constexpr const char* manual_type_name<int64_t>() a_pure;
template<> constexpr const char* manual_type_name<wchar_t>() a_pure;
template<> constexpr const char* manual_type_name<char16_t>() a_pure;
template<> constexpr const char* manual_type_name<char32_t>() a_pure;
#endif
} //namespace dk
#if defined(USE_MANUAL_TYPENAMES)
# include "doorkeeper/implem/typename_native.inl"
#endif
#endif

View file

@ -1,11 +1,18 @@
namespace dk { namespace dk {
#if defined(USE_MANUAL_TYPENAMES)
template <typename T> template <typename T>
#if defined(IS_PRETTY_FUNC_CONSTEXPR) inline constexpr const char* manual_type_name() {
static_assert(sizeof(T) == 0, "define an overload returning a const char* name for your type T");
return nullptr;
}
#endif
template <typename T>
#if defined(IS_PRETTY_FUNC_CONSTEXPR) || defined(USE_MANUAL_TYPENAMES)
constexpr constexpr
#endif #endif
inline HashType type_name_hash() { inline HashType type_name_hash() {
#if defined(IS_PRETTY_FUNC_CONSTEXPR) #if defined(IS_PRETTY_FUNC_CONSTEXPR) || defined(USE_MANUAL_TYPENAMES)
//static_assert(dk::tiger("a", 1, 0x01).a == 0xABF87E2EEFFBBE77ULL, "Bug in tiger hash"); //static_assert(dk::tiger("a", 1, 0x01).a == 0xABF87E2EEFFBBE77ULL, "Bug in tiger hash");
//static_assert(dk::tiger("message digest", 14, 0x01).a == 0x951A2078CBF881D9ULL, "Bug in tiger hash"); //static_assert(dk::tiger("message digest", 14, 0x01).a == 0x951A2078CBF881D9ULL, "Bug in tiger hash");
@ -18,14 +25,14 @@ namespace dk {
} }
template <typename T> template <typename T>
#if defined(IS_PRETTY_FUNC_CONSTEXPR) #if defined(IS_PRETTY_FUNC_CONSTEXPR) || defined(USE_MANUAL_TYPENAMES)
constexpr inline sprout::string<implem::type_name_len<T>()> type_name() constexpr inline sprout::string<implem::type_name_len<T>()> type_name()
#else #else
inline std::string type_name() inline std::string type_name()
#endif #endif
{ {
#if defined(__GNUC__) #if defined(__GNUC__)
# if defined(IS_PRETTY_FUNC_CONSTEXPR) # if defined(IS_PRETTY_FUNC_CONSTEXPR) || defined(USE_MANUAL_TYPENAMES)
typedef sprout::string<implem::type_name_info<T>().len> sproutstring; typedef sprout::string<implem::type_name_info<T>().len> sproutstring;
typedef sprout::string<implem::type_name_len<T>()> sproutstringret; typedef sprout::string<implem::type_name_len<T>()> sproutstringret;
@ -39,9 +46,14 @@ namespace dk {
# else # else
std::string pf(__PRETTY_FUNCTION__); std::string pf(__PRETTY_FUNCTION__);
const auto read_start = pf.find('=', pf.find('[') + 1) + 2; const auto read_start = pf.find('=', pf.find('[') + 1) + 2;
# if defined(__clang__)
const std::size_t typename_end = pf.size() - 1;
# else
const auto typename_end = pf.find(';', read_start);
#endif
return pf.substr( return pf.substr(
read_start, read_start,
pf.find(';', read_start) - read_start typename_end - read_start
); );
# endif # endif
#else #else
@ -52,12 +64,17 @@ namespace dk {
} }
namespace implem { namespace implem {
#if defined(IS_PRETTY_FUNC_CONSTEXPR) #if defined(IS_PRETTY_FUNC_CONSTEXPR) || defined(USE_MANUAL_TYPENAMES)
template <typename T> template <typename T>
constexpr type_name_info<T>::type_name_info() : constexpr type_name_info<T>::type_name_info() :
# if defined(__GNUC__) # if defined(__GNUC__)
# if defined(USE_MANUAL_TYPENAMES)
len(sprout::strlen(manual_type_name<T>())),
str(manual_type_name<T>())
# else
len(sizeof(__PRETTY_FUNCTION__)), len(sizeof(__PRETTY_FUNCTION__)),
str(__PRETTY_FUNCTION__) str(__PRETTY_FUNCTION__)
# endif
# else # else
# error "not implemented" # error "not implemented"
# endif # endif

View file

@ -0,0 +1,21 @@
#if !defined(USE_MANUAL_TYPENAMES)
# error "Only usable when USE_MANUAL_TYPENAMES is defined"
#endif
namespace dk {
template<> constexpr inline const char* manual_type_name<bool>() { return "bool"; }
template<> constexpr inline const char* manual_type_name<float>() { return "float"; }
template<> constexpr inline const char* manual_type_name<double>() { return "double"; }
template<> constexpr inline const char* manual_type_name<long double>() { return "long double"; }
template<> constexpr inline const char* manual_type_name<uint8_t>() { return "uint8_t"; }
template<> constexpr inline const char* manual_type_name<uint16_t>() { return "uint16_t"; }
template<> constexpr inline const char* manual_type_name<uint32_t>() { return "uint32_t"; }
template<> constexpr inline const char* manual_type_name<uint64_t>() { return "uint64_t"; }
template<> constexpr inline const char* manual_type_name<int8_t>() { return "int8_t"; }
template<> constexpr inline const char* manual_type_name<int16_t>() { return "int16_t"; }
template<> constexpr inline const char* manual_type_name<int32_t>() { return "int32_t"; }
template<> constexpr inline const char* manual_type_name<int64_t>() { return "int64_t"; }
template<> constexpr inline const char* manual_type_name<wchar_t>() { return "wchar_t"; }
template<> constexpr inline const char* manual_type_name<char16_t>() { return "char16_t"; }
template<> constexpr inline const char* manual_type_name<char32_t>() { return "char32_t"; }
} //namespace dk

View file

@ -1,6 +1,7 @@
#include "doorkeeper/helpers/asciimapsource.hpp" #include "doorkeeper/helpers/asciimapsource.hpp"
#include "doorkeeper/implem/compatibility.h" #include "doorkeeper/implem/compatibility.h"
#include "doorkeeper/helpers/typename.hpp" #include "doorkeeper/helpers/typename.hpp"
#include "doorkeeper/helpers/typename_native.hpp"
#include "asciimap_parser.hpp" #include "asciimap_parser.hpp"
#include <fstream> #include <fstream>
#include <iomanip> #include <iomanip>

View file

@ -23,13 +23,6 @@ struct LayerWithData {
std::string path; std::string path;
}; };
#include "doorkeeper/helpers/typename.hpp"
std::ostream& operator<< (std::ostream& parStream, const dk::HashType& parHash) {
parStream << std::hex << parHash.a << parHash.b << parHash.c;
return parStream;
}
namespace { namespace {
typedef std::unique_ptr<SDL_Renderer, void(*)(SDL_Renderer*)> SDLRendererUPtr; typedef std::unique_ptr<SDL_Renderer, void(*)(SDL_Renderer*)> SDLRendererUPtr;
typedef std::unique_ptr<SDL_Window, void(*)(SDL_Window*)> SDLWindowUPtr; typedef std::unique_ptr<SDL_Window, void(*)(SDL_Window*)> SDLWindowUPtr;
@ -49,37 +42,6 @@ namespace {
} //unnamed namespace } //unnamed namespace
int main() { int main() {
typedef dk::Tyler<2>::coords coords2;
std::cout << dk::type_name<coords2>() << '\n';
std::cout << dk::type_name<dk::Tyler<2>::coords>() << '\n';
std::cout << dk::type_name<int>() << '\n';
std::cout << dk::type_name<float>() << '\n';
std::cout << dk::type_name<std::vector<std::pair<std::map<std::string, unsigned short int>, bool>>>() << '\n';
std::cout << dk::type_name_hash<dk::Tyler<2>>() << '\n';
//static constexpr auto h = dk::tiger("message digest", 14, 0x01);
//std::cout << std::hex << h.a << '\n' << 0x951A2078CBF881D9ULL << std::endl;
//static constexpr auto h2 = dk::tiger("abc", 3, 0x01);
//std::cout << std::hex << h2.a << '\n' << 0xF258C1E88414AB2AULL << std::endl;
//static constexpr auto h3 = dk::tiger("", 0, 0x01);
//std::cout << std::hex << h3.a << '\n' << 0x24F0130C63AC9332ULL << std::endl;
//{
// static constexpr dk::HashType hashtest{1, 2, 3};
// static_assert(hashtest.a == 1, "wrong value");
// static_assert(hashtest.b == 2, "wrong value");
// static_assert(hashtest.c == 3, "wrong value");
//}
//{
// static constexpr dk::HashType hashtest(2, 'c', 0, 'a', 1, 'b');
// static_assert(hashtest.a == 'a', "wrong value");
// static_assert(hashtest.b == 'b', "wrong value");
// static_assert(hashtest.c == 'c', "wrong value");
//}
return 0;
typedef dk::Tyler<2>::coords coords2; typedef dk::Tyler<2>::coords coords2;
using dkh::AsciiMapSource; using dkh::AsciiMapSource;