-   
- template<class _Ty> 
- struct buildpath; 
-   
- template<int N, class _Path, char ...chars> 
- struct build_path; 
-   
-   
- //----------------------------------------------------------------------------- 
- // constexpr for strlen 
- template<char ..._chars> 
- struct constexpr_strlen 
- { 
- 	static constexpr const int value = sizeof...(_chars); 
- }; 
-   
- //----------------------------------------------------------------------------- 
- // constexpr string 
- // holds a reference to a string and its size and length as a constexpr 
- template<const char *_Str, int _Sz> 
- struct constexpr_string 
- { 
- 	static constexpr const int size = _Sz; 
- 	static constexpr const int length = _Sz - 1; 
- 	static constexpr const char *str = _Str; 
- }; 
-   
- //----------------------------------------------------------------------------- 
- // a constexpr empty string 
- struct constexpr_string_empty 
- { 
- 	static constexpr const char *str = ""; 
- 	static constexpr const int size = 1; 
- 	static constexpr const int length = 0; 
- }; 
-   
- //----------------------------------------------------------------------------- 
- // exposes name and parent of this path element 
- template<class _Ty, class _NameStr, class _ParPathTy> 
- struct PathElemInfo : _NameStr 
- { 
- 	using parent = _ParPathTy; 
- }; 
-   
- //----------------------------------------------------------------------------- 
- // An empty path element info 
- struct PathElemInfoEmpty : constexpr_string_empty 
- {}; 
-   
- //----------------------------------------------------------------------------- 
- // An empty path 
- struct PathEmpty 
- { 
- 	using __info = PathElemInfoEmpty; 
- }; 
-   
- //----------------------------------------------------------------------------- 
- // Path is used to construct path element + parents which can then be 
- // serialize to compile-time static strings. 
- template<class _Ty, class _NameStr = constexpr_string_empty, class _ParPathTy = PathEmpty> 
- struct Path 
- { 
- 	using __type = Path<_Ty, _NameStr, _ParPathTy>; 
- 	using __info = PathElemInfo<_Ty, _NameStr, _ParPathTy>; 
- 	static constexpr const char *path() { return buildpath<__type>::value(); } 
- }; 
-   
- //============================================================================= 
- // Construct constexpr strings from paths 
-   
- //----------------------------------------------------------------------------- 
- // Add a '.' between path elements 
- template<int N, class _Path, char ...chars> 
- struct build_path_dot 
- { 
- 	static constexpr const char *value() { 
- 		return build_path<N, _Path, '.', chars...>::value(); 
- 	} 
- }; 
-   
- //----------------------------------------------------------------------------- 
- // Don't add a '.' on an empty path element (the root element is always empty) 
- template<int N, char ...chars> 
- struct build_path_dot<N, PathEmpty, chars...> 
- { 
- 	static constexpr const char *value() { 
- 		return build_path<N, PathEmpty, chars...>::value(); 
- 	} 
- }; 
-   
- //----------------------------------------------------------------------------- 
- // Don't add a '.' at the beginning of the string 
- template<char ...chars> 
- struct build_path_dot<0, PathEmpty, chars...> 
- { 
- 	static constexpr const char *value() { 
- 		return build_path<0, PathEmpty, chars...>::value; 
- 	} 
- }; 
-   
- //----------------------------------------------------------------------------- 
- // Compiler gets confused if we don't provide this one as well... 
- template<class _Path, char ...chars> 
- struct build_path_dot<0, _Path, chars...> 
- { 
- 	static constexpr const char *value() { 
- 		return build_path<0, _Path, chars...>::value(); 
- 	} 
- }; 
-   
- //----------------------------------------------------------------------------- 
- // Extract the Nth character from the current path element 
- template<int N, class _Path, char ...chars> 
- struct build_path 
- { 
- 	static constexpr const char *value() { 
- 		return build_path<N - 1, _Path, _Path::__info::str[N - 1], chars...>::value(); 
- 	} 
- }; 
-   
- //----------------------------------------------------------------------------- 
- // When a path element is depleted, add a dot and move on to the next path element 
- template<class _Path, char ...chars> 
- struct build_path<0, _Path, chars...> 
- { 
- 	static constexpr const char *value() { 
- 		return  build_path_dot<_Path::__info::parent::__info::length, typename _Path::__info::parent, chars...>::value(); 
- 	} 
- }; 
-   
- //----------------------------------------------------------------------------- 
- // When the last path element is depleted, build the actual string from all 
- // the characters we have extracted 
- template<char ...chars> 
- struct build_path<0, PathEmpty, chars...> 
- { 
- 	static constexpr const int size() { 
- 		return constexpr_strlen<chars...>::value + 1; 
- 	} 
- 	static const char value[size()]; 
- }; 
-   
- //----------------------------------------------------------------------------- 
- // Allocate static storage for this path 
- template<char ...chars> 
- const char build_path<0, PathEmpty, chars...>::value[] = { chars..., 0 }; 
-   
-   
- //----------------------------------------------------------------------------- 
- // shortcut to make usage easier 
- template<class _Ty> 
- struct buildpath { 
- 	static constexpr const char *value() { return build_path<_Ty::__info::length, _Ty>::value(); } 
- }; 
-   
- //============================================================================= 
- // Sample usage 
-   
- struct A; 
- struct B; 
- struct C; 
-   
- template<class _NameStr, class _ParPathTy> 
- struct Path<A, _NameStr, _ParPathTy> 
- { 
- 	using __type = Path<A, _NameStr, _ParPathTy>; 
- 	using __info = PathElemInfo<A, _NameStr, _ParPathTy>; 
-   
- 	static constexpr const char *path() { return buildpath<__type>::value(); } 
-   
- 	static constexpr const char __b[] = "obj_b"; 
- 	using b = Path<B, constexpr_string<__type::__b, sizeof(__type::__b)>, __type>; 
-   
- 	static constexpr const char __b2[] = "obj_b2"; 
- 	using b2 = Path<B, constexpr_string<__type::__b2, sizeof(__type::__b2)>, __type>; 
- }; 
-   
- template<class _NameStr, class _ParPathTy> 
- struct Path<B, _NameStr, _ParPathTy> 
- { 
- 	using __type = Path<B, _NameStr, _ParPathTy>; 
- 	using __info = PathElemInfo<B, _NameStr, _ParPathTy>; 
- 	static constexpr const char *path() { return buildpath<__type>::value(); } 
-   
- 	static constexpr const char __c[] = "obj_c"; 
- 	using c = Path<C, constexpr_string<__type::__c, sizeof(__type::__c)>, __type>; 
-   
- 	static constexpr const char __a[] = "obj_a"; 
- 	using a = Path<A, constexpr_string<__type::__a, sizeof(__type::__a)>, __type>; 
- }; 
-   
-   
- #include <iostream> 
- using namespace std; 
- int main(int argc, const char *argv[]) 
- { 
- 	using Q = Path<A>; 
- 	cout << "root: " << Q::path() << endl; 
- 	cout << "b: " << Q::b::path() << endl; 
- 	cout << "b.c: " << Q::b::c::path() << endl; 
-   
- 	// make sure we can have multiple identical types under the same path 
- 	cout << "b2.c: " << Q::b2::c::path() << endl; 
-   
- 	// make sure we can have recursive paths as well 
- 	cout << "b2.a.b.a.b.c: " << Q::b2::a::b::a::b::c::path() << endl; 
- } 
-