MRPT  1.9.9
static_string.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 #pragma once
10 
11 /** \file static string for constexpr. Based on:
12  * https://akrzemi1.wordpress.com/2017/06/28/compile-time-string-concatenation/
13  * (Boost License)
14  */
15 
16 #include <mrpt/typemeta/xassert.h>
17 
18 namespace mrpt
19 {
20 namespace typemeta
21 {
22 template <int N>
24 {
25  const char (&_lit)[N + 1];
26 
27  public:
28  /** Ctor from C string literal, with trailing zero. */
29  constexpr string_literal(const char (&lit)[N + 1])
30  : _lit((MRPT_X_ASSERT(lit[N] == '\0'), lit))
31  {
32  }
33  constexpr std::size_t size() const { return N; }
34  constexpr char operator[](int i) const
35  {
36  return MRPT_X_ASSERT(i >= 0 && i < N), _lit[i];
37  }
38  constexpr const char* c_str() const { return _lit; }
39  constexpr operator const char*() const { return c_str(); }
40 };
41 
42 template <int N_PLUS_1>
43 constexpr auto literal(const char (&lit)[N_PLUS_1])
44  -> string_literal<N_PLUS_1 - 1>
45 {
46  return string_literal<N_PLUS_1 - 1>(lit);
47 }
48 
49 #define REQUIRES(...) typename std::enable_if<(__VA_ARGS__), bool>::type = true
50 
51 namespace internal
52 {
53 // the type used to receive the pack
54 template <int... I>
55 struct sequence
56 {
57 };
58 
59 // auxiliary meta-function for making (N+1)-sized sequence
60 // from an N-sized sequence
61 template <typename T>
62 struct append;
63 
64 template <int... I>
65 struct append<sequence<I...>>
66 {
67  using type = sequence<I..., sizeof...(I)>;
68 };
69 
70 // recursive implementation of make_sequence
71 
72 template <int I>
74 
75 template <int I>
77 
78 template <>
79 struct make_sequence_<0> // recursion end
80 {
81  using type = sequence<>;
82 };
83 
84 template <int I>
85 struct make_sequence_ : append<make_sequence<I - 1>>
86 {
87  static_assert(I >= 0, "negative size");
88 };
89 } // end NS internal
90 
91 template <int N>
93 {
94  char _array[N + 1];
95 
96  template <typename S1, typename S2, int... PACK1, int... PACK2>
97  constexpr array_string(
98  const S1& s1, const S2& s2, internal::sequence<PACK1...>,
100  : _array{s1[PACK1]..., s2[PACK2]..., '\0'}
101  {
102  }
103 
104  public:
105  /** ctor: literal + literal */
106  template <int N1, REQUIRES(N1 <= N)>
107  constexpr array_string(
108  const string_literal<N1>& s1, const string_literal<N - N1>& s2)
109  : array_string{s1, s2, internal::make_sequence<N1>{},
110  internal::make_sequence<N - N1>{}}
111  {
112  }
113 
114  /** ctor: string + literal */
115  template <int N1, REQUIRES(N1 <= N)>
116  constexpr array_string(
117  const array_string<N1>& s1, const string_literal<N - N1>& s2)
118  : array_string{s1, s2, internal::make_sequence<N1>{},
119  internal::make_sequence<N - N1>{}}
120  {
121  }
122 
123  /** ctor: string + string */
124  template <int N1, REQUIRES(N1 <= N)>
125  constexpr array_string(
126  const array_string<N1>& s1, const array_string<N - N1>& s2)
127  : array_string{s1, s2, internal::make_sequence<N1>{},
128  internal::make_sequence<N - N1>{}}
129  {
130  }
131 
132  constexpr std::size_t size() const { return N; }
133  constexpr char operator[](int i) const
134  {
135  return MRPT_X_ASSERT(i >= 0 && i < N), _array[i];
136  }
137  constexpr const char* c_str() const { return _array; }
138  constexpr operator const char*() const { return c_str(); }
139 };
140 
141 template <int N1, int N2>
142 constexpr auto operator+(
143  const string_literal<N1>& s1, const string_literal<N2>& s2)
145 {
146  return array_string<N1 + N2>(s1, s2);
147 }
148 
149 template <int N1, int N2>
150 constexpr auto operator+(
151  const array_string<N1>& s1, const string_literal<N2>& s2)
153 {
154  return array_string<N1 + N2>(s1, s2);
155 }
156 
157 template <int N1, int N2>
158 constexpr auto operator+(const array_string<N1>& s1, const array_string<N2>& s2)
160 {
161  return array_string<N1 + N2>(s1, s2);
162 }
163 
164 } // namespace typemeta
165 } // namespace mrpt
constexpr const char * c_str() const
Definition: static_string.h:38
constexpr auto operator+(const array_string< N1 > &s1, const array_string< N2 > &s2) -> array_string< N1+N2 >
constexpr const char * c_str() const
constexpr auto literal(const char(&lit)[N_PLUS_1]) -> string_literal< N_PLUS_1 - 1 >
Definition: static_string.h:43
constexpr array_string(const S1 &s1, const S2 &s2, internal::sequence< PACK1... >, internal::sequence< PACK2... >)
Definition: static_string.h:97
#define MRPT_X_ASSERT(CHECK)
MRPT_X_ASSERT(): build error if condition is known not to work at compile time, throw an exception at...
Definition: xassert.h:27
constexpr string_literal(const char(&lit)[N+1])
Ctor from C string literal, with trailing zero.
Definition: static_string.h:29
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
typename make_sequence_< I >::type make_sequence
Definition: static_string.h:76
constexpr std::size_t size() const
Definition: static_string.h:33
constexpr char operator[](int i) const
Definition: static_string.h:34



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020