siplasplas
A library for C++ reflection and introspection
stringview.hpp
1 #ifndef SIPLASPLAS_CONSTEXPR_STRINGVIEW_HPP
2 #define SIPLASPLAS_CONSTEXPR_STRINGVIEW_HPP
3 
4 #include "arrayview.hpp"
5 #include <string>
6 
7 namespace cpp
8 {
9 
10 namespace constexp
11 {
12 
17 class StringView : public ArrayView<char>
18 {
19 public:
20  using ArrayView<char>::ArrayView;
21 
22  constexpr StringView(const ArrayView<char>& arrayView) :
23  ArrayView<char>{arrayView}
24  {}
25 
26  constexpr StringView(ArrayView<char>&& arrayView) :
27  ArrayView<char>{std::move(arrayView)}
28  {}
29 
30  constexpr StringView(char* const str) :
31  ArrayView<char>{str, str + ::cpp::constexp::strlen(str)}
32  {}
33 
34  StringView(std::string& str) :
35  ArrayView<char>{&str[0], &str[str.size()]}
36  {}
37 
38  std::string str() const
39  {
40  /*
41  * The range std::string constructor takes the string as is, so passing
42  * a range including a null terminator at the end (Such as when passing an
43  * string literal to a [Const]ArrayView) leads to a string with a
44  * \0 character at the end. Instead, return a range without that final
45  * null terminator so std::string gets the right string
46  */
47  if((*this)[size() - 1] == '\0')
48  {
49  return { begin(), end() - 1};
50  }
51  else
52  {
53  return { begin(), end() };
54  }
55  }
56 
57  constexpr const char* c_str() const
58  {
59  return begin();
60  }
61 };
62 
63 class ConstStringView : public ConstArrayView<char>
64 {
65 public:
66  using ConstArrayView<char>::ConstArrayView;
67 
68  constexpr ConstStringView(const ConstArrayView<char>& arrayView) :
69  ConstArrayView<char>{arrayView}
70  {}
71 
72  constexpr ConstStringView(ConstArrayView<char>&& arrayView) :
73  ConstArrayView<char>{std::move(arrayView)}
74  {}
75 
76  constexpr ConstStringView(const char* str) :
77  ConstArrayView<char>{str, str + ::cpp::constexp::strlen(str)}
78  {}
79 
80  ConstStringView(const std::string& str) :
81  ConstArrayView<char>{&str[0], &str[str.size()]}
82  {}
83 
84  std::string str() const
85  {
86  /*
87  * The range std::string constructor takes the string as is, so passing
88  * a range including a null terminator at the end (Such as when passing an
89  * string literal to a [Const]ArrayView) leads to a string with a
90  * \0 character at the end. Instead, return a range without that final
91  * null terminator so std::string gets the right string
92  */
93  if((*this)[size() - 1] == '\0')
94  {
95  return { begin(), end() - 1};
96  }
97  else
98  {
99  return { begin(), end() };
100  }
101  }
102 
103  constexpr const char* c_str() const
104  {
105  return begin();
106  }
107 };
108 
109 using StringViews = ArrayView<const char*>;
110 using ConstStringViews = ConstArrayView<const char*>;
111 
112 }
113 
114 }
115 
116 #endif // SIPLASPLAS_CONSTEXPR_STRINGVIEW_HPP
Definition: canary_allocator.hpp:7
constexpr auto end(const Sequence &sequence)
Returns an iterator pointing to the end of a sequence.
Definition: algorithm.hpp:86
constexpr auto begin(const Sequence &sequence)
Returns an iterator pointing to the beginning of a sequence.
Definition: algorithm.hpp:62
Implements a constexpr reference to an slice of an string.
Definition: stringview.hpp:17