diff --git a/include/doorkeeper/helpers/hashing.hpp b/include/doorkeeper/helpers/hashing.hpp index dd2dca9..3bd5875 100644 --- a/include/doorkeeper/helpers/hashing.hpp +++ b/include/doorkeeper/helpers/hashing.hpp @@ -1,7 +1,23 @@ #ifndef id4E5F8A0ABA6047BA988D512351B9DD2D #define id4E5F8A0ABA6047BA988D512351B9DD2D -//#include "doorkeeper/implem/string_bt.hpp" +#include "doorkeeper/implem/doorkeeper_conf.h" + +#if (defined(__clang__) && \ + (__clang_major__ == 3 && __clang_minor__ > 5) || (__clang_major__ > 3) \ + ) || (defined(IS_ORIGINAL_GNUC) && \ + (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 5) \ + ) +# define IS_PRETTY_FUNC_CONSTEXPR +#elif defined(__GNUC__) +//uhm.. nothing :p +#else +# error "Unknown compiler" +#endif + +#if defined(IS_PRETTY_FUNC_CONSTEXPR) +# include "doorkeeper/implem/string_bt.hpp" +#endif #include "doorkeeper/implem/compatibility.h" #include #include @@ -27,4 +43,8 @@ namespace dk { #include "doorkeeper/implem/hashing.inl" +#if defined(IS_PRETTY_FUNC_CONSTEXPR) +# undef IS_PRETTY_FUNC_CONSTEXPR +#endif + #endif diff --git a/include/doorkeeper/implem/hashing.inl b/include/doorkeeper/implem/hashing.inl index 6389642..62a95c1 100644 --- a/include/doorkeeper/implem/hashing.inl +++ b/include/doorkeeper/implem/hashing.inl @@ -1,15 +1,13 @@ namespace dk { template HashType make_signature_hash() { -#if defined(__GNUC__) - //TODO: use bt::string if possible +#if IS_PRETTY_FUNC_CONSTEXPR + constexpr bt::string func_pretty(__PRETTY_FUNCTION__); + return implem::hash_string(func_pretty.data(), func_pretty.size()); +#else const char* const pf = __PRETTY_FUNCTION__; const std::size_t len = sizeof(__PRETTY_FUNCTION__) - 1; - //constexpr bt::string func_pretty(pf); -#else -# error "Unknown compiler" -#endif - //return implem::hash_string(func_pretty.data(), func_pretty.size()); return implem::hash_string(pf, len); +#endif } } //namespace dk diff --git a/include/doorkeeper/implem/sequence_bt.hpp b/include/doorkeeper/implem/sequence_bt.hpp new file mode 100644 index 0000000..131aabc --- /dev/null +++ b/include/doorkeeper/implem/sequence_bt.hpp @@ -0,0 +1,31 @@ +#ifndef id4FAEF395B9ED47CB9D6B50B54C9A289A +#define id4FAEF395B9ED47CB9D6B50B54C9A289A + +#include + +namespace dk { + namespace bt { + template + struct index_seq { + }; + + namespace implem { + template + struct range_builder; + + template + struct range_builder { + typedef index_seq type; + }; + + template + struct range_builder : public range_builder { + }; + } //namespace implem + + template + using index_range = typename implem::range_builder::type; + } //namespace bt +} //namespace dk + +#endif diff --git a/include/doorkeeper/implem/string_bt.hpp b/include/doorkeeper/implem/string_bt.hpp new file mode 100644 index 0000000..e92bff5 --- /dev/null +++ b/include/doorkeeper/implem/string_bt.hpp @@ -0,0 +1,95 @@ +#ifndef id170B0E6C34D14EBA9B92A35977BDBFB3 +#define id170B0E6C34D14EBA9B92A35977BDBFB3 + +#include "doorkeeper/implem/sequence_bt.hpp" +#include +#include +#include + +namespace dk { + namespace bt { + template + class string; + + template + std::ostream& operator<< ( std::ostream& parStream, const string& parString ); + + template + class string { + public: + friend std::ostream& operator<< <>( std::ostream& parStream, const string& parString ); + constexpr string ( const char* parString ); + + constexpr std::size_t size ( void ) const { return S - 1; } + template + constexpr string operator+ ( const string& parOther ) const; + constexpr char operator[] ( std::size_t parIndex ) const; + + template + constexpr string ( Args... ); + + constexpr const char (&data_arr() const)[S] { return m_data; } + constexpr const char* data() const { return m_data; } + + private: + template + constexpr string ( const index_seq&, const char* parString ); + + const char m_data[S]; + }; + + namespace implem { + template + constexpr string concat ( const index_seq&, const string& parLeft, const string& parRight ) { + return string( + (I < S - 1 ? parLeft[I] : (I < S + S2 - 2 ? parRight[I - (S - 1)] : '\0'))... + ); + } + + } //namespace implem + + template + template + constexpr string::string (const index_seq&, const char* parString) : + m_data{parString[I]...} + { + } + + template + inline constexpr string::string (const char* parString) : + string(index_range<0, S>(), parString) + { + } + + template + template + inline constexpr string::string (Args... parArgs) : + m_data{parArgs...} + { + } + + template + template + constexpr inline string string::operator+ (const string& parOther) const { + return implem::concat(index_range<0, S + S2 - 1>(), string(m_data), parOther); + } + + template + inline std::ostream& operator<< (std::ostream& parStream, const string& parString) { + parStream << parString.m_data; + return parStream; + } + + template + constexpr char string::operator[] (std::size_t parIndex) const { + return (parIndex < S ? m_data[parIndex] : throw std::out_of_range("")); + } + + template + constexpr string make_string (const char (&parData)[S]) { + return string(parData); + } + } //namespace bt +} //namespace dk + +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6dd5bb1..173f74d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,8 +1,15 @@ cmake_minimum_required(VERSION 2.8 FATAL_ERROR) project(doorkeeper CXX C) -include_directories( - . +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + set(ID_IS_ORIGINAL_GNUC "1") +else() + set(ID_IS_ORIGINAL_GNUC "0") +endif() + +configure_file( + ${PROJECT_NAME}_conf.h.in + ${CMAKE_CURRENT_BINARY_DIR}/include/doorkeeper/implem/${PROJECT_NAME}_conf.h ) add_library(${PROJECT_NAME} @@ -11,3 +18,8 @@ add_library(${PROJECT_NAME} tiger.c hashing.cpp ) + +target_include_directories(${PROJECT_NAME} + PRIVATE . + PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/include +) diff --git a/src/doorkeeper_conf.h.in b/src/doorkeeper_conf.h.in new file mode 100644 index 0000000..f2bde48 --- /dev/null +++ b/src/doorkeeper_conf.h.in @@ -0,0 +1,8 @@ +#ifndef idB523F14441E649E089C21CDE8189640C +#define idB523F14441E649E089C21CDE8189640C + +#if @ID_IS_ORIGINAL_GNUC@ != 0 +# define IS_ORIGINAL_GNUC +#endif + +#endif