fork download
  1.  
  2. #include <iostream> // for operator <<
  3.  
  4. namespace ces { //ConstexprString
  5.  
  6.  
  7. using Size = int;
  8.  
  9. template<Size n, typename Char>
  10. using char_array = Char[n];
  11.  
  12. template<Size n, typename Char>
  13. using const_char_array_ref = const Char(&)[n]; //zu nem eigenen typ machen => in den implizit gecastet wird , der ConstexprStringView;
  14.  
  15. template<typename Char>
  16. using ConstexprString_iterator = Char*;
  17.  
  18. template<typename Char>
  19. using ConstexprString_const_iterator = const Char*;
  20.  
  21. template<Size capacity, typename Char>
  22. class ConstexprString{
  23.  
  24. template<Size,typename> friend class ConstexprString;
  25.  
  26. public:
  27.  
  28.  
  29. using Classtype = ConstexprString<capacity,Char>;
  30. static constexpr Size StorageArraySize = capacity+1;
  31. using StorageArray = char_array<StorageArraySize,Char>; // the + 1 asserts '\0' terminatability
  32.  
  33. using iterator = ConstexprString_iterator<Char>;
  34. using const_iterator = ConstexprString_const_iterator<Char>;
  35.  
  36. static_assert(capacity>=0,"");
  37.  
  38. constexpr ConstexprString() : _length(0) { updateNullTerminator();}
  39.  
  40. template<Size N>
  41. constexpr ConstexprString(ConstexprString<N, Char> const& other) : _length(other._length){
  42. static_assert(N <= capacity, "invalid size");
  43. for(Size i=0;i<other._length;++i) str[i] = other.str[i];
  44. updateNullTerminator();
  45. }
  46.  
  47. template<Size N>
  48. constexpr ConstexprString(const_char_array_ref<N, Char> s) : _length(N-1){
  49. static_assert(N<=capacity+1,"invalid size");
  50. for(Size i=0;i<_length;++i) str[i] = s[i];
  51. updateNullTerminator();
  52. }
  53.  
  54. template<Size N>
  55. constexpr Classtype& operator=(ConstexprString<N, Char> const& other) {
  56. static_assert(N <= capacity, "invalid size");
  57. _length = other._length;
  58. for(Size i=0;i<other._length;++i) str[i] = other.str[i];
  59. updateNullTerminator();
  60. return *this;
  61. }
  62.  
  63. template<Size N>
  64. constexpr Classtype& operator=(const_char_array_ref<N, Char> s) {
  65. static_assert(N <= capacity+1, "invalid size");
  66. _length = N-1;
  67. for(Size i=0;i<_length;++i) str[i] = s[i];
  68. updateNullTerminator();
  69. return *this;
  70. }
  71.  
  72. constexpr void resize (Size n){
  73. _length = n;
  74. updateNullTerminator();
  75. }
  76.  
  77.  
  78. constexpr Char& operator[](Size idx){ return str[idx]; }
  79. constexpr Char const& operator[](Size idx) const{ return str[idx]; }
  80.  
  81. using const_char_array_ref_equivalent = const_char_array_ref<StorageArraySize,Char>;
  82.  
  83. constexpr const Char* c_str() const{ return static_cast<const Char*>(str); }
  84. constexpr Size length() const { return _length;}
  85. constexpr Size size() const { return _length;}
  86. constexpr bool empty() const { return _length==0;}
  87.  
  88. constexpr iterator begin(){ return &str[0];}
  89. constexpr iterator end(){ return &str[_length];}
  90. constexpr const_iterator begin() const{ return &str[0];}
  91. constexpr const_iterator end() const{ return &str[_length];}
  92.  
  93. private:
  94.  
  95. constexpr void updateNullTerminator(){ str[_length] = '\0'; }
  96.  
  97. Size _length;
  98. StorageArray str = {};
  99. };
  100.  
  101.  
  102. template<Size N, typename Char>
  103. constexpr ConstexprString<N-1,Char> make_string(const_char_array_ref<N,Char> s) {
  104. return {s};
  105. }
  106.  
  107.  
  108.  
  109. template<Size M, typename Char>
  110. constexpr Size length(ConstexprString<M,Char> const& t) {
  111. return t.length();
  112. }
  113.  
  114. template<Size M, typename Char>
  115. constexpr Size length(const_char_array_ref<M,Char>) {
  116. return M-1;
  117. }
  118.  
  119. template<Size N, typename T, typename Char>
  120. constexpr ConstexprString<N,Char> & append( ConstexprString<N, Char> & s1, T const& s2) {
  121.  
  122. const auto start =length(s1);
  123.  
  124. s1.resize(length(s1) + length(s2)); //adds \0 terminator
  125.  
  126. for(Size i=0;i<length(s2);++i)
  127. s1[start + i] = s2[i];
  128.  
  129. return s1;
  130. }
  131.  
  132.  
  133.  
  134. template<Size N, Size M, typename Char>
  135. constexpr auto conditional(bool condition, const_char_array_ref<N,Char> s1, ConstexprString<M,Char> const& s2) {
  136. constexpr auto l1 = length(s1);
  137. constexpr auto l2 = M;
  138. constexpr auto OutSize = l1 > l2 ? l1 : l2;
  139.  
  140. return condition ?
  141. ConstexprString<OutSize,Char>(s1) :
  142. ConstexprString<OutSize,Char>(s2) ;
  143. }
  144.  
  145.  
  146. template<Size N, Size M, typename Char>
  147. constexpr bool operator==( ConstexprString<N,Char> const& s1, ConstexprString<M,Char> const& s2) {
  148.  
  149. if(length(s1) !=length(s2)) return false; //length does not include '\0'
  150.  
  151. for(Size i=0;i<s1.length();++i)
  152. if (s1[i]!=s2[i]) return false;
  153.  
  154. return true;
  155. }
  156.  
  157. template<Size N, Size M, typename Char>
  158. constexpr bool operator==( ConstexprString<N,Char> const& s1, const_char_array_ref<M,Char> s2) {
  159. return s1 == ConstexprString<M,Char> {s2};
  160. }
  161.  
  162. template<Size N, Size M, typename Char>
  163. constexpr bool operator==( const_char_array_ref<M,Char> s1, ConstexprString<N,Char> const& s2) {
  164. return ConstexprString<N,Char> {s1}==s2;
  165. }
  166.  
  167.  
  168.  
  169.  
  170. template<Size N, Size M, typename Char>
  171. constexpr auto operator+( ConstexprString<N,Char> const& s1, ConstexprString<M,Char> const& s2) {
  172. auto r = ConstexprString<N+M,Char>(s1);
  173. return append(r,s2);
  174. }
  175.  
  176. template<Size N, Size M, typename Char>
  177. constexpr auto operator+( ConstexprString<N,Char> const& s1, const_char_array_ref<M,Char> s2) {
  178. auto r = ConstexprString<N+length(s2),Char>(s1);
  179. return append(r,s2);
  180. }
  181.  
  182. template<Size N, Size M, typename Char>
  183. constexpr auto operator+( const_char_array_ref<N,Char> s1, ConstexprString<M,Char> const& s2) {
  184. auto r = ConstexprString<length(s1)+M,Char>(s1);
  185. return append(r,s2);
  186. }
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193. template<Size N, typename Char>
  194. constexpr std::ostream& operator<<(std::ostream& s, ConstexprString<N,Char> const& a) {
  195. return s<<a.c_str();
  196. }
  197.  
  198. } //ns
  199.  
  200.  
  201. constexpr char foo[] = "foo";
  202. constexpr char bar[] = "bar";
  203. constexpr auto foobar = ces::make_string(foo) + " " + bar;
  204.  
  205.  
  206. int main()
  207. {
  208. std::cout << foobar << std::endl; //prints "foo bar"
  209. return 0;
  210. }
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
Success #stdin #stdout 0s 4208KB
stdin
Standard input is empty
stdout
foo bar