• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (c) 2019-2020 Krystian Stasiowski (sdkrystian at gmail dot com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/boostorg/static_string
8 //
9 
10 #include <boost/static_string/static_string.hpp>
11 
12 #include <string>
13 
14 namespace boost {
15 namespace static_strings {
16 
17 // char_traits aren't fully constexpr until c++20
18 #ifdef BOOST_STATIC_STRING_CPP14
19 struct cxper_char_traits
20 {
21   using char_type = char;
22   using int_type = int;
23   using state_type = std::mbstate_t;
24 
assignboost::static_strings::cxper_char_traits25   static constexpr void assign(char_type& a, const char_type& b) noexcept { a = b;  }
eqboost::static_strings::cxper_char_traits26   static constexpr bool eq(char_type a, char_type b) noexcept { return a == b; }
ltboost::static_strings::cxper_char_traits27   static constexpr bool lt(char_type a, char_type b) noexcept { return a < b; }
28 
compareboost::static_strings::cxper_char_traits29   static constexpr int compare(const char_type*, const char_type*, std::size_t) { return 0; }
lengthboost::static_strings::cxper_char_traits30   static constexpr std::size_t length(const char_type* s)
31   {
32     std::size_t n = 0;
33     while (*(s++));
34     return n;
35   }
findboost::static_strings::cxper_char_traits36   static constexpr const char_type* find(const char_type*, std::size_t, const char_type&){ return 0; }
moveboost::static_strings::cxper_char_traits37   static constexpr char_type* move(char_type* dest, const char_type* src, std::size_t n)
38   {
39     const auto temp = dest;
40     while (n--)
41       *(dest++) = *(src++);
42     return temp;
43   }
copyboost::static_strings::cxper_char_traits44   static constexpr char_type* copy(char_type* dest, const char_type* src, std::size_t n)
45   {
46     const auto temp = dest;
47     while (n--)
48       *(dest++) = *(src++);
49     return temp;
50   }
assignboost::static_strings::cxper_char_traits51   static constexpr char_type* assign(char_type* dest, std::size_t n, char_type ch)
52   {
53     const auto temp = dest;
54     while (n--)
55       *(dest++) = ch;
56     return temp;
57   }
58 };
59 #else
60 using cxper_char_traits = std::char_traits<char>;
61 #endif
62 using cstatic_string = basic_static_string<50, char, cxper_char_traits>;
63 
64 inline
65 constexpr
66 bool
testConstantEvaluation()67 testConstantEvaluation()
68 {
69 #ifdef BOOST_STATIC_STRING_CPP20
70   // c++20 constexpr tests
71   cstatic_string a;
72   cstatic_string b(1, 'a');
73   cstatic_string(b, 0);
74   cstatic_string(b, 0, 1);
75   cstatic_string("a", 1);
76   cstatic_string("a");
77   cstatic_string{b};
78   cstatic_string({'a'});
79 
80   // assignment
81   a = b;
82   a = "a";
83   a = 'a';
84   a = {'a'};
85 
86   // assign
87   a.assign(b);
88   a.assign(b, 0, 1);
89   a.assign("a", 1);
90   a.assign("a");
91   a.assign(b.begin(), b.end());
92   a.assign({'a'});
93   a.assign(1, 'a');
94 
95   // element access
96   {
97     auto j = a.at(0);
98     static_cast<void>(j);
99   }
100   {
101     auto j = a[0];
102     static_cast<void>(j);
103   }
104   {
105     auto j = a.front();
106     static_cast<void>(j);
107   }
108   {
109     auto j = a.back();
110     static_cast<void>(j);
111   }
112   a.data();
113   a.c_str();
114   a.begin();
115   a.cbegin();
116   a.end();
117   a.cend();
118 
119   // reverse iterators
120   a.rbegin();
121   a.crbegin();
122   a.rend();
123   a.crend();
124 
125   // capacity and size
126   cstatic_string().size();
127   // this is potentially marked nodiscard
128   static_cast<void>(cstatic_string().empty());
129   cstatic_string().length();
130   cstatic_string().max_size();
131   cstatic_string().capacity();
132 
133   // clear
134   a.clear();
135 
136   // insert
137   a.insert(a.begin(), 1, 'a');
138   a.insert(0, a.begin());
139   a.insert(0, a.begin(), 1);
140   a.insert(a.begin(), 'a');
141   a.insert(a.begin(), {'a'});
142 
143   // erase
144   a.erase(0, 1);
145   a.erase(a.begin());
146   a.erase(a.begin(), a.end());
147 
148   // push
149   a.push_back('a');
150   a.pop_back();
151 
152   // append
153   a.append(1, 'a');
154   a.append("a", 1);
155   a.append("a");
156   a.append(a.begin(), a.end());
157   a.append({'a'});
158 
159   // append operator
160   a += 'a';
161   a += "a";
162   a += {'a'};
163 
164   // compare
165   a.compare(b);
166   a.compare(0, 1, b);
167   a.compare(0, 1, b, 0, 1);
168   a.compare("a");
169   a.compare(0, 1, "a");
170   a.compare(0, 1, "a", 1);
171 
172   a.substr(0);
173 
174   // subview
175   a.subview(0);
176 
177   // copy
178   char k[20]{};
179   a.copy(k, 1, 0);
180 
181   // resize
182   a.resize(1);
183   a.resize(1, 'a');
184 
185   // swap
186   a.swap(b);
187 
188   // replace
189   a.replace(0, 1, a);
190   a.replace(0, 1, a, 0, 1);
191   a.replace(0, 1, a.data(), 1);
192   a.replace(0, 1, a.data());
193   a.replace(0, 1, 1, 'a');
194   a.replace(a.begin(), a.end(), a);
195   a.replace(a.begin(), a.end(), a.data(), 1);
196   a.replace(a.begin(), a.end(), a.data());
197   a.replace(a.begin(), a.end(), 1, 'a');
198   a.replace(a.begin(), a.end(), a.begin(), a.end());
199   a.replace(a.begin(), a.end(), {'a'});
200 
201 #ifdef BOOST_STATIC_STRING_IS_CONST_EVAL
202   a.clear();
203   a.replace(a.begin(), a.end(), "a");
204   a.replace(a.begin(), a.end(), "a", 1);
205 #endif
206 
207   // find
208   a.find(a);
209   a.find("a", 0, 1);
210   a.find("a", 0);
211   a.find('a', 0);
212 
213   // rfind
214   a.rfind(a);
215   a.rfind("a", 0, 1);
216   a.rfind("a", 0);
217   a.rfind('a', 0);
218 
219   // find_first_of
220   a.find_first_of(a);
221   a.find_first_of("a", 0, 1);
222   a.find_first_of("a", 0);
223   a.find_first_of('a', 0);
224 
225   // find_first_not_of
226   a.find_first_not_of(a);
227   a.find_first_not_of("a", 0, 1);
228   a.find_first_not_of("a", 0);
229   a.find_first_not_of('a', 0);
230 
231   // starts_with
232   a.starts_with('a');
233   a.starts_with("a");
234 
235   // ends_with
236   a.ends_with('a');
237   a.ends_with("a");
238 
239   return true;
240 #elif defined(BOOST_STATIC_STRING_CPP17)
241   //c++17 constexpr tests
242 
243   // ctors
244   cstatic_string a;
245   cstatic_string b(1, 'a');
246   cstatic_string(b, 0);
247   cstatic_string(b, 0, 1);
248   cstatic_string("a", 1);
249   cstatic_string("a");
250   cstatic_string{b};
251   cstatic_string({'a'});
252 
253   // assignment
254   a = b;
255   a = "a";
256   a = 'a';
257   a = {'a'};
258 
259   // assign
260   a.assign(b);
261   a.assign(b, 0, 1);
262   a.assign("a", 1);
263   a.assign("a");
264   a.assign(b.begin(), b.end());
265   a.assign({'a'});
266   a.assign(1, 'a');
267 
268   // element access
269   {
270     auto j = a.at(0);
271     static_cast<void>(j);
272   }
273   {
274     auto j = a[0];
275     static_cast<void>(j);
276   }
277   {
278     auto j = a.front();
279     static_cast<void>(j);
280   }
281   {
282     auto j = a.back();
283     static_cast<void>(j);
284   }
285   a.data();
286   a.c_str();
287   a.begin();
288   a.cbegin();
289   a.end();
290   a.cend();
291 
292   // reverse iterators
293   //{
294   //  auto j = a.rbegin();
295   //}
296   //{
297   //  auto j = a.crbegin();
298   //}
299   //{
300   //  auto j = a.rend();
301   //}
302   //{
303   //  auto j = a.crend();
304   //}
305 
306   // capacity and size
307   cstatic_string().size();
308   // this is potentially marked nodiscard
309   static_cast<void>(cstatic_string().empty());
310   cstatic_string().length();
311   cstatic_string().max_size();
312   cstatic_string().capacity();
313 
314   // clear
315   a.clear();
316 
317   // insert
318   a.insert(a.begin(), 1, 'a');
319   a.insert(0, a.begin());
320   a.insert(0, a.begin(), 1);
321   a.insert(a.begin(), 'a');
322   a.insert(a.begin(), {'a'});
323 
324   // erase
325   a.erase(0, 1);
326   a.erase(a.begin());
327   a.erase(a.begin(), a.end());
328 
329   // push
330   a.push_back('a');
331   a.pop_back();
332 
333   // append
334   a.append(1, 'a');
335   a.append("a", 1);
336   a.append("a");
337   a.append(a.begin(), a.end());
338   a.append({'a'});
339 
340   // append operator
341   a += 'a';
342   a += "a";
343   a += {'a'};
344 
345   // compare
346   a.compare(b);
347   a.compare(0, 1, b);
348   a.compare(0, 1, b, 0, 1);
349   a.compare("a");
350   a.compare(0, 1, "a");
351   a.compare(0, 1, "a", 1);
352 
353   // substr
354   // in gcc 5, a constexpr non-static member function returning the class
355   // is a member of causes an ICE
356 #ifndef BOOST_STATIC_STRING_GCC5_BAD_CONSTEXPR
357   a.substr(0);
358 #endif
359 
360   // subview
361   a.subview(0);
362 
363   // copy
364   char k[20]{};
365   a.copy(k, 1, 0);
366 
367   // resize
368   a.resize(1);
369   a.resize(1, 'a');
370 
371   // swap
372   a.swap(b);
373 
374   // replace
375   a.replace(0, 1, a);
376   a.replace(0, 1, a, 0, 1);
377   a.replace(0, 1, a.data(), 1);
378   a.replace(0, 1, a.data());
379   a.replace(0, 1, 1, 'a');
380   a.replace(a.begin(), a.end(), a);
381   a.replace(a.begin(), a.end(), a.data(), 1);
382   a.replace(a.begin(), a.end(), a.data());
383   a.replace(a.begin(), a.end(), 1, 'a');
384   a.replace(a.begin(), a.end(), a.begin(), a.end());
385   a.replace(a.begin(), a.end(), {'a'});
386 
387 #ifdef BOOST_STATIC_STRING_IS_CONST_EVAL
388   a.clear();
389   a.replace(a.begin(), a.end(), "a");
390   a.replace(a.begin(), a.end(), "a", 1);
391 #endif
392 
393   // find
394   a.find(a);
395   a.find("a", 0, 1);
396   a.find("a", 0);
397   a.find('a', 0);
398 
399   // rfind
400   a.rfind(a);
401   a.rfind("a", 0, 1);
402   a.rfind("a", 0);
403   a.rfind('a', 0);
404 
405   // find_first_of
406   a.find_first_of(a);
407   a.find_first_of("a", 0, 1);
408   a.find_first_of("a", 0);
409   a.find_first_of('a', 0);
410 
411   // find_first_not_of
412   a.find_first_not_of(a);
413   a.find_first_not_of("a", 0, 1);
414   a.find_first_not_of("a", 0);
415   a.find_first_not_of('a', 0);
416 
417   // starts_with
418   a.starts_with('a');
419   a.starts_with("a");
420 
421   // ends_with
422   a.ends_with('a');
423   a.ends_with("a");
424 
425   return true;
426 #elif defined(BOOST_STATIC_STRING_CPP14)
427   // c++14 constexpr tests
428 
429   // ctors
430   cstatic_string a;
431   cstatic_string b(1, 'a');
432   cstatic_string(b, 0);
433   cstatic_string(b, 0, 1);
434   cstatic_string("a", 1);
435   cstatic_string("a");
436   cstatic_string{b};
437   cstatic_string({'a'});
438 
439   // assignment
440   a = b;
441   a = "a";
442   a = 'a';
443   a = {'a'};
444 
445   // assign
446   a.assign(b);
447   a.assign(b, 0, 1);
448   a.assign("a", 1);
449   a.assign("a");
450   a.assign(b.begin(), b.end());
451   a.assign({'a'});
452   a.assign(1, 'a');
453 
454   // element access
455   {
456     auto j = a.at(0);
457     static_cast<void>(j);
458   }
459   {
460     auto j = a[0];
461     static_cast<void>(j);
462   }
463   {
464     auto j = a.front();
465     static_cast<void>(j);
466   }
467   {
468     auto j = a.back();
469     static_cast<void>(j);
470   }
471   a.data();
472   a.c_str();
473   a.begin();
474   a.cbegin();
475   a.end();
476   a.cend();
477 
478   // capacity and size
479   cstatic_string().size();
480   // this is potentially marked nodiscard
481   static_cast<void>(cstatic_string().empty());
482   cstatic_string().length();
483   cstatic_string().max_size();
484   cstatic_string().capacity();
485 
486   // clear
487   a.clear();
488 
489   // insert
490   a.insert(a.begin(), 1, 'a');
491   a.insert(0, a.begin());
492   a.insert(0, a.begin(), 1);
493   a.insert(a.begin(), 'a');
494   a.insert(a.begin(), {'a'});
495 
496   // erase
497   a.erase(0, 1);
498   a.erase(a.begin());
499   a.erase(a.begin(), a.end());
500 
501   // push
502   a.push_back('a');
503   a.pop_back();
504 
505   // append
506   a.append(1, 'a');
507   a.append("a", 1);
508   a.append("a");
509   a.append(a.begin(), a.end());
510   a.append({'a'});
511 
512   // append operator
513   a += 'a';
514   a += "a";
515   a += {'a'};
516 
517   // compare
518   a.compare(b);
519   a.compare(0, 1, b);
520   a.compare(0, 1, b, 0, 1);
521   a.compare("a");
522   a.compare(0, 1, "a");
523   a.compare(0, 1, "a", 1);
524 
525   // substr
526   // in gcc 5, a constexpr non-static member function returning the class
527   // is a member of causes an ICE
528 #ifndef BOOST_STATIC_STRING_GCC5_BAD_CONSTEXPR
529   a.substr(0, 1);
530 #endif
531 
532   // subview
533   a.subview(0);
534 
535   // copy
536   char k[20]{};
537   a.copy(k, 1, 0);
538 
539   // resize
540   a.resize(1);
541   a.resize(1, 'a');
542 
543   // swap
544   a.swap(b);
545 
546   // replace
547   a.replace(0, 1, a);
548   a.replace(0, 1, a, 0, 1);
549   a.replace(0, 1, a.data(), 1);
550   a.replace(0, 1, a.data());
551   a.replace(0, 1, 1, 'a');
552   a.replace(a.begin(), a.end(), a);
553   a.replace(a.begin(), a.end(), a.data(), 1);
554   a.replace(a.begin(), a.end(), a.data());
555   a.replace(a.begin(), a.end(), 1, 'a');
556   a.replace(a.begin(), a.end(), a.begin(), a.end());
557   a.replace(a.begin(), a.end(), {'a'});
558 
559 #ifdef BOOST_STATIC_STRING_IS_CONST_EVAL
560   a.clear();
561   a.replace(a.begin(), a.end(), "a");
562   a.replace(a.begin(), a.end(), "a", 1);
563 #endif
564 
565   // find
566   a.find(a);
567   a.find("a", 0, 1);
568   a.find("a", 0);
569   a.find('a', 0);
570 
571   // rfind
572   a.rfind(a);
573   a.rfind("a", 0, 1);
574   a.rfind("a", 0);
575   a.rfind('a', 0);
576 
577   // find_first_of
578   a.find_first_of(a);
579   a.find_first_of("a", 0, 1);
580   a.find_first_of("a", 0);
581   a.find_first_of('a', 0);
582 
583   // find_first_not_of
584   a.find_first_not_of(a);
585   a.find_first_not_of("a", 0, 1);
586   a.find_first_not_of("a", 0);
587   a.find_first_not_of('a', 0);
588 
589   // starts_with
590   a.starts_with('a');
591   a.starts_with("a");
592 
593   // ends_with
594   a.ends_with('a');
595   a.ends_with("a");
596   return true;
597 #elif defined(BOOST_STATIC_STRING_CPP11)
598   // c++11 constexpr tests
599   return (cstatic_string().size() +
600     cstatic_string().length() +
601     cstatic_string().max_size() +
602     cstatic_string().capacity()) != 0 &&
603     cstatic_string().empty();
604 #endif
605 }
606 } // static_strings
607 } // boost