/** This file is a part of rexy's general purpose library Copyright (C) 2020 rexy712 This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ #ifndef REXY_CX_STRING_HPP #define REXY_CX_STRING_HPP namespace rexy::cx{ template class string; } #include "../string_base.hpp" #include "utility.hpp" #include #include //ptrdiff_t //This is different from rexy::static_string in that this doesn't hold a pointer to a constant string array. //This holds a mutable array of data which can be modified during compile time. static_string is //designed to be a thin wrapper around a raw char*, this is designed to allow compile time string concatenation namespace rexy::cx{ template class string { public: using value_type = Char; using size_type = size_t; using difference_type = ptrdiff_t; using pointer = value_type*; using const_pointer = const value_type*; using reference = value_type&; using const_reference = const value_type&; using iterator = pointer; using const_iterator = const_pointer; public: static constexpr size_t max_size = N; private: value_type m_data[N] = {}; size_type m_length = 0; public: constexpr string(void) = default; template constexpr string(const char(&data)[M])noexcept: m_length(M) { static_assert(M <= N); for(size_type i = 0;i < M;++i){ m_data[i] = data[i]; } } constexpr string(const_pointer data)noexcept: m_length(cx::strlen(data)) { for(size_type i = 0;i < m_length;++i){ m_data[i] = data[i]; } } constexpr string(const_pointer data, size_type len)noexcept: m_length(len) { for(size_type i = 0;i < m_length;++i){ m_data[i] = data[i]; } } constexpr string(const rexy::static_string& str)noexcept: m_length(str.length()) { for(size_type i = 0;i < m_length;++i){ m_data[i] = str[i]; } } template constexpr string(const rexy::string_cat_expr& expr) noexcept(std::is_nothrow_invocable>, decltype(expr)>::value) { rexy::detail::string_appender> append(*this); append(expr); } constexpr string(const string&)noexcept = default; constexpr string(string&&)noexcept = default; ~string(void)noexcept = default; constexpr string& operator=(const_pointer c)noexcept{ m_length = cx::strlen(c); for(size_type i = 0;i < m_length;++i){ m_data[i] = c[i]; } return *this; } constexpr string& operator=(const string&)noexcept = default; constexpr string& operator=(string&&)noexcept = default; constexpr size_type length(void)const noexcept{ return m_length; } constexpr size_type capacity(void)const noexcept{ return max_size; } constexpr pointer c_str(void)noexcept{ return m_data; } constexpr const_pointer c_str(void)const noexcept{ return m_data; } constexpr pointer get(void)noexcept{ return m_data; } constexpr const_pointer get(void)const noexcept{ return m_data; } constexpr operator pointer(void)noexcept{ return m_data; } constexpr operator const_pointer(void)const noexcept{ return m_data; } constexpr bool valid(void)const noexcept{ return m_length > 0; } constexpr reference operator[](size_type i)noexcept{ return m_data[i]; } constexpr const_reference operator[](size_type i)const noexcept{ return m_data[i]; } constexpr bool resize(size_type i)noexcept{ if(i >= capacity()) return false; m_length = i; m_data[m_length] = 0; return true; } constexpr void append(const_pointer data, size_type len)noexcept{ for(size_type i = 0;i < len;++i){ m_data[m_length++] = data[i]; } } constexpr void append(const_pointer data)noexcept{ append(data, cx::strlen(data)); } constexpr void append(const string& s)noexcept{ append(s.get(), s.length()); } constexpr void append(const rexy::static_string& s)noexcept{ append(s.get(), s.length()); } }; namespace detail{ template struct is_cx_string_helper{ static constexpr bool value = false; }; template struct is_cx_string_helper>{ static constexpr bool value = true; }; template struct is_cx_string{ static constexpr bool value = (is_cx_string_helper>::value && ...); }; } template::value,int> = 0> constexpr auto operator+(Str1&& l, Str2&& r)noexcept{ return string_cat_expr(std::forward(l), std::forward(r)); } template::value,int> = 0> constexpr auto operator+(Str1&& l, const char* r)noexcept{ return string_cat_expr(std::forward(l), rexy::static_string(r)); } template::value,int> = 0> constexpr auto operator+(const char* l, Str1&& r)noexcept{ return string_cat_expr(rexy::static_string(l), std::forward(r)); } } #ifdef REXY_CX_HASH_HPP #include "cx_string_hash.hpp" #endif #endif