diff options
| author | Dan Goodliffe <dan@randomdan.homeip.net> | 2020-12-19 15:29:32 +0000 | 
|---|---|---|
| committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2020-12-19 19:18:12 +0000 | 
| commit | 6ea6e77967e0656790f33db2c3e1b3f141e905a5 (patch) | |
| tree | f48fddfb43ddfe8bd5f96d4664da3433d262b35a | |
| parent | Disable misc-no-recursion on Slice search functions (diff) | |
| download | icespider-6ea6e77967e0656790f33db2c3e1b3f141e905a5.tar.bz2 icespider-6ea6e77967e0656790f33db2c3e1b3f141e905a5.tar.xz icespider-6ea6e77967e0656790f33db2c3e1b3f141e905a5.zip  | |
Constexpr typename helpers
| -rw-r--r-- | icespider/core/Jamfile.jam | 4 | ||||
| -rw-r--r-- | icespider/core/util-test.cpp | 12 | ||||
| -rw-r--r-- | icespider/core/util.h | 71 | 
3 files changed, 86 insertions, 1 deletions
diff --git a/icespider/core/Jamfile.jam b/icespider/core/Jamfile.jam index 15648b8..7b7bd19 100644 --- a/icespider/core/Jamfile.jam +++ b/icespider/core/Jamfile.jam @@ -2,9 +2,11 @@ lib adhocutil : : : : <include>/usr/include/adhocutil ;  lib slicer : : : : <include>/usr/include/slicer ;  lib stdc++fs ; +obj util-test : util-test.cpp ; +  obj routeOptions : routeOptions.ice : <toolset>tidy:<checker>none ;  lib icespider-core : -	[ glob *.cpp ] +	[ glob *.cpp : *-test.cpp ]  	routeOptions  	:  	<library>../common//icespider-common diff --git a/icespider/core/util-test.cpp b/icespider/core/util-test.cpp new file mode 100644 index 0000000..32a7c42 --- /dev/null +++ b/icespider/core/util-test.cpp @@ -0,0 +1,12 @@ +#include "util.h" + +namespace foo ::bar { +	class really; +} + +static_assert(type_names<int>::name() == "int"); +static_assert(type_names<int>::namespaces() == 0); +static_assert(TypeName<int>::str() == "int"); +static_assert(type_names<foo::bar::really>::name() == "foo::bar::really"); +static_assert(type_names<foo::bar::really>::namespaces() == 2); +static_assert(TypeName<foo::bar::really>::str() == "foo.bar.really"); diff --git a/icespider/core/util.h b/icespider/core/util.h index 2089ce0..ca1350b 100644 --- a/icespider/core/util.h +++ b/icespider/core/util.h @@ -2,6 +2,8 @@  #define ICESPIDER_CORE_UTIL_H  #include <Ice/Optional.h> +#include <array> +#include <string_view>  namespace std::experimental::Ice {  	template<typename T, typename TF> @@ -37,4 +39,73 @@ orelse(const T & a, const T & b)  	return b;  } +template<typename T> struct type_names { +	static constexpr auto +	pf() +	{ +		return std::string_view {&__PRETTY_FUNCTION__[0], sizeof(__PRETTY_FUNCTION__)}; +	} + +	static constexpr auto +	name() +	{ +		const std::string_view with_T {"T = "}; +		const auto start {pf().find(with_T) + with_T.length()}; +		const auto end {pf().find(']', start)}; +		return pf().substr(start, end - start); +	} + +	static constexpr auto +	namespaces() +	{ +		auto ns {0U}; +		for (const auto & c : name()) { +			// cppcheck-suppress useStlAlgorithm; (not constexpr) +			ns += (c == ':') ? 1 : 0; +		} +		return ns / 2; +	} + +	using char_type = typename decltype(name())::value_type; +}; + +template<typename T> class TypeName : type_names<T> { +public: +	constexpr static inline auto +	str() +	{ +		return std::string_view {buf.data(), buf.size() - 1}; +	} + +	constexpr static inline auto +	c_str() +	{ +		return buf.data(); +	} + +private: +	using tn = type_names<T>; + +	constexpr static auto buf {[]() { +		std::array<typename tn::char_type, tn::name().length() - tn::namespaces() + 1> buf {}; +		auto out {buf.begin()}; +		auto cln {false}; +		for (const auto & in : tn::name()) { +			if (in == ':') { +				if (cln) { +					*out++ = '.'; +				} +				else { +					cln = true; +				} +			} +			else { +				*out++ = in; +				cln = false; +			} +		} +		return buf; +	}()}; +}; +  #endif  | 
