Ticket #6815: templ_literal.h

File templ_literal.h, 1.5 KB (added by d.starosud@…, 11 years ago)
Line 
1#ifndef TEMPL_LITERAL_H
2#define TEMPL_LITERAL_H
3
4#include <cstddef>
5#include <boost/preprocessor.hpp>
6
7#ifndef TEMPLATE_LITERAL_MAX_SYM
8#define TEMPLATE_LITERAL_MAX_SYM 20
9#endif
10
11template< char... >
12struct TemplateLiteral { };
13
14template< std::size_t LEN, char CHAR, char... CHARS >
15struct TemplateLiteralTrim
16{
17private:
18 template< bool, class, char... >
19 struct Helper;
20 template< char... C1, char... C2 >
21 struct Helper< false, TemplateLiteral<C1...>, C2... >
22 {
23 static_assert(sizeof...(C1) == LEN, "Literal is too large. Extend it with #define TEMPLATE_LITERAL_MAX_SYM");
24 typedef TemplateLiteral<C1...> Result;
25 };
26 template< char... C1, char c1, char c2, char... C2 >
27 struct Helper< true, TemplateLiteral<C1...>, c1, c2, C2... >
28 {
29 typedef typename Helper< (bool)c2, TemplateLiteral<C1..., c1>, c2, C2...>::Result Result;
30 };
31public:
32 typedef typename Helper<(bool)CHAR, TemplateLiteral<>, CHAR, CHARS..., '\0' >::Result Result;
33};
34
35template< class T, std::size_t N >
36constexpr inline std::size_t sizeof_literal( const T (&)[N] )
37{
38 return N;
39}
40
41template< std::size_t M >
42constexpr inline char getNthCharSpec( std::size_t N, const char (&literal)[M] )
43{
44 return N < M ? literal[N] : '\0';
45}
46
47#define GET_Nth_CHAR_FOR_PP(I, N, LIT) ,getNthCharSpec(N, LIT)
48
49#define TEMPLATE_LITERAL_BASE(MAX, LIT) \
50 (typename TemplateLiteralTrim< sizeof_literal(LIT) - 1 \
51 BOOST_PP_REPEAT(MAX, GET_Nth_CHAR_FOR_PP, LIT) >::Result())
52
53#define TEMPLATE_LITERAL(LITERAL) TEMPLATE_LITERAL_BASE(TEMPLATE_LITERAL_MAX_SYM, LITERAL)
54
55#endif //TEMPL_LITERAL_H