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



Page generated by Doxygen 1.8.14 for MRPT 2.0.1 Git: 0fef1a6d7 Fri Apr 3 23:00:21 2020 +0200 at vie abr 3 23:20:28 CEST 2020