// // Copyright (c) 2019-2020 Krystian Stasiowski (sdkrystian at gmail dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // Official repository: https://github.com/boostorg/static_string // #include #include namespace boost { namespace static_strings { // char_traits aren't fully constexpr until c++20 #ifdef BOOST_STATIC_STRING_CPP14 struct cxper_char_traits { using char_type = char; using int_type = int; using state_type = std::mbstate_t; static constexpr void assign(char_type& a, const char_type& b) noexcept { a = b; } static constexpr bool eq(char_type a, char_type b) noexcept { return a == b; } static constexpr bool lt(char_type a, char_type b) noexcept { return a < b; } static constexpr int compare(const char_type*, const char_type*, std::size_t) { return 0; } static constexpr std::size_t length(const char_type* s) { std::size_t n = 0; while (*(s++)); return n; } static constexpr const char_type* find(const char_type*, std::size_t, const char_type&){ return 0; } static constexpr char_type* move(char_type* dest, const char_type* src, std::size_t n) { const auto temp = dest; while (n--) *(dest++) = *(src++); return temp; } static constexpr char_type* copy(char_type* dest, const char_type* src, std::size_t n) { const auto temp = dest; while (n--) *(dest++) = *(src++); return temp; } static constexpr char_type* assign(char_type* dest, std::size_t n, char_type ch) { const auto temp = dest; while (n--) *(dest++) = ch; return temp; } }; #else using cxper_char_traits = std::char_traits; #endif using cstatic_string = basic_static_string<50, char, cxper_char_traits>; inline constexpr bool testConstantEvaluation() { #ifdef BOOST_STATIC_STRING_CPP20 // c++20 constexpr tests cstatic_string a; cstatic_string b(1, 'a'); cstatic_string(b, 0); cstatic_string(b, 0, 1); cstatic_string("a", 1); cstatic_string("a"); cstatic_string{b}; cstatic_string({'a'}); // assignment a = b; a = "a"; a = 'a'; a = {'a'}; // assign a.assign(b); a.assign(b, 0, 1); a.assign("a", 1); a.assign("a"); a.assign(b.begin(), b.end()); a.assign({'a'}); a.assign(1, 'a'); // element access { auto j = a.at(0); static_cast(j); } { auto j = a[0]; static_cast(j); } { auto j = a.front(); static_cast(j); } { auto j = a.back(); static_cast(j); } a.data(); a.c_str(); a.begin(); a.cbegin(); a.end(); a.cend(); // reverse iterators a.rbegin(); a.crbegin(); a.rend(); a.crend(); // capacity and size cstatic_string().size(); // this is potentially marked nodiscard static_cast(cstatic_string().empty()); cstatic_string().length(); cstatic_string().max_size(); cstatic_string().capacity(); // clear a.clear(); // insert a.insert(a.begin(), 1, 'a'); a.insert(0, a.begin()); a.insert(0, a.begin(), 1); a.insert(a.begin(), 'a'); a.insert(a.begin(), {'a'}); // erase a.erase(0, 1); a.erase(a.begin()); a.erase(a.begin(), a.end()); // push a.push_back('a'); a.pop_back(); // append a.append(1, 'a'); a.append("a", 1); a.append("a"); a.append(a.begin(), a.end()); a.append({'a'}); // append operator a += 'a'; a += "a"; a += {'a'}; // compare a.compare(b); a.compare(0, 1, b); a.compare(0, 1, b, 0, 1); a.compare("a"); a.compare(0, 1, "a"); a.compare(0, 1, "a", 1); a.substr(0); // subview a.subview(0); // copy char k[20]{}; a.copy(k, 1, 0); // resize a.resize(1); a.resize(1, 'a'); // swap a.swap(b); // replace a.replace(0, 1, a); a.replace(0, 1, a, 0, 1); a.replace(0, 1, a.data(), 1); a.replace(0, 1, a.data()); a.replace(0, 1, 1, 'a'); a.replace(a.begin(), a.end(), a); a.replace(a.begin(), a.end(), a.data(), 1); a.replace(a.begin(), a.end(), a.data()); a.replace(a.begin(), a.end(), 1, 'a'); a.replace(a.begin(), a.end(), a.begin(), a.end()); a.replace(a.begin(), a.end(), {'a'}); #ifdef BOOST_STATIC_STRING_IS_CONST_EVAL a.clear(); a.replace(a.begin(), a.end(), "a"); a.replace(a.begin(), a.end(), "a", 1); #endif // find a.find(a); a.find("a", 0, 1); a.find("a", 0); a.find('a', 0); // rfind a.rfind(a); a.rfind("a", 0, 1); a.rfind("a", 0); a.rfind('a', 0); // find_first_of a.find_first_of(a); a.find_first_of("a", 0, 1); a.find_first_of("a", 0); a.find_first_of('a', 0); // find_first_not_of a.find_first_not_of(a); a.find_first_not_of("a", 0, 1); a.find_first_not_of("a", 0); a.find_first_not_of('a', 0); // starts_with a.starts_with('a'); a.starts_with("a"); // ends_with a.ends_with('a'); a.ends_with("a"); return true; #elif defined(BOOST_STATIC_STRING_CPP17) //c++17 constexpr tests // ctors cstatic_string a; cstatic_string b(1, 'a'); cstatic_string(b, 0); cstatic_string(b, 0, 1); cstatic_string("a", 1); cstatic_string("a"); cstatic_string{b}; cstatic_string({'a'}); // assignment a = b; a = "a"; a = 'a'; a = {'a'}; // assign a.assign(b); a.assign(b, 0, 1); a.assign("a", 1); a.assign("a"); a.assign(b.begin(), b.end()); a.assign({'a'}); a.assign(1, 'a'); // element access { auto j = a.at(0); static_cast(j); } { auto j = a[0]; static_cast(j); } { auto j = a.front(); static_cast(j); } { auto j = a.back(); static_cast(j); } a.data(); a.c_str(); a.begin(); a.cbegin(); a.end(); a.cend(); // reverse iterators //{ // auto j = a.rbegin(); //} //{ // auto j = a.crbegin(); //} //{ // auto j = a.rend(); //} //{ // auto j = a.crend(); //} // capacity and size cstatic_string().size(); // this is potentially marked nodiscard static_cast(cstatic_string().empty()); cstatic_string().length(); cstatic_string().max_size(); cstatic_string().capacity(); // clear a.clear(); // insert a.insert(a.begin(), 1, 'a'); a.insert(0, a.begin()); a.insert(0, a.begin(), 1); a.insert(a.begin(), 'a'); a.insert(a.begin(), {'a'}); // erase a.erase(0, 1); a.erase(a.begin()); a.erase(a.begin(), a.end()); // push a.push_back('a'); a.pop_back(); // append a.append(1, 'a'); a.append("a", 1); a.append("a"); a.append(a.begin(), a.end()); a.append({'a'}); // append operator a += 'a'; a += "a"; a += {'a'}; // compare a.compare(b); a.compare(0, 1, b); a.compare(0, 1, b, 0, 1); a.compare("a"); a.compare(0, 1, "a"); a.compare(0, 1, "a", 1); // substr // in gcc 5, a constexpr non-static member function returning the class // is a member of causes an ICE #ifndef BOOST_STATIC_STRING_GCC5_BAD_CONSTEXPR a.substr(0); #endif // subview a.subview(0); // copy char k[20]{}; a.copy(k, 1, 0); // resize a.resize(1); a.resize(1, 'a'); // swap a.swap(b); // replace a.replace(0, 1, a); a.replace(0, 1, a, 0, 1); a.replace(0, 1, a.data(), 1); a.replace(0, 1, a.data()); a.replace(0, 1, 1, 'a'); a.replace(a.begin(), a.end(), a); a.replace(a.begin(), a.end(), a.data(), 1); a.replace(a.begin(), a.end(), a.data()); a.replace(a.begin(), a.end(), 1, 'a'); a.replace(a.begin(), a.end(), a.begin(), a.end()); a.replace(a.begin(), a.end(), {'a'}); #ifdef BOOST_STATIC_STRING_IS_CONST_EVAL a.clear(); a.replace(a.begin(), a.end(), "a"); a.replace(a.begin(), a.end(), "a", 1); #endif // find a.find(a); a.find("a", 0, 1); a.find("a", 0); a.find('a', 0); // rfind a.rfind(a); a.rfind("a", 0, 1); a.rfind("a", 0); a.rfind('a', 0); // find_first_of a.find_first_of(a); a.find_first_of("a", 0, 1); a.find_first_of("a", 0); a.find_first_of('a', 0); // find_first_not_of a.find_first_not_of(a); a.find_first_not_of("a", 0, 1); a.find_first_not_of("a", 0); a.find_first_not_of('a', 0); // starts_with a.starts_with('a'); a.starts_with("a"); // ends_with a.ends_with('a'); a.ends_with("a"); return true; #elif defined(BOOST_STATIC_STRING_CPP14) // c++14 constexpr tests // ctors cstatic_string a; cstatic_string b(1, 'a'); cstatic_string(b, 0); cstatic_string(b, 0, 1); cstatic_string("a", 1); cstatic_string("a"); cstatic_string{b}; cstatic_string({'a'}); // assignment a = b; a = "a"; a = 'a'; a = {'a'}; // assign a.assign(b); a.assign(b, 0, 1); a.assign("a", 1); a.assign("a"); a.assign(b.begin(), b.end()); a.assign({'a'}); a.assign(1, 'a'); // element access { auto j = a.at(0); static_cast(j); } { auto j = a[0]; static_cast(j); } { auto j = a.front(); static_cast(j); } { auto j = a.back(); static_cast(j); } a.data(); a.c_str(); a.begin(); a.cbegin(); a.end(); a.cend(); // capacity and size cstatic_string().size(); // this is potentially marked nodiscard static_cast(cstatic_string().empty()); cstatic_string().length(); cstatic_string().max_size(); cstatic_string().capacity(); // clear a.clear(); // insert a.insert(a.begin(), 1, 'a'); a.insert(0, a.begin()); a.insert(0, a.begin(), 1); a.insert(a.begin(), 'a'); a.insert(a.begin(), {'a'}); // erase a.erase(0, 1); a.erase(a.begin()); a.erase(a.begin(), a.end()); // push a.push_back('a'); a.pop_back(); // append a.append(1, 'a'); a.append("a", 1); a.append("a"); a.append(a.begin(), a.end()); a.append({'a'}); // append operator a += 'a'; a += "a"; a += {'a'}; // compare a.compare(b); a.compare(0, 1, b); a.compare(0, 1, b, 0, 1); a.compare("a"); a.compare(0, 1, "a"); a.compare(0, 1, "a", 1); // substr // in gcc 5, a constexpr non-static member function returning the class // is a member of causes an ICE #ifndef BOOST_STATIC_STRING_GCC5_BAD_CONSTEXPR a.substr(0, 1); #endif // subview a.subview(0); // copy char k[20]{}; a.copy(k, 1, 0); // resize a.resize(1); a.resize(1, 'a'); // swap a.swap(b); // replace a.replace(0, 1, a); a.replace(0, 1, a, 0, 1); a.replace(0, 1, a.data(), 1); a.replace(0, 1, a.data()); a.replace(0, 1, 1, 'a'); a.replace(a.begin(), a.end(), a); a.replace(a.begin(), a.end(), a.data(), 1); a.replace(a.begin(), a.end(), a.data()); a.replace(a.begin(), a.end(), 1, 'a'); a.replace(a.begin(), a.end(), a.begin(), a.end()); a.replace(a.begin(), a.end(), {'a'}); #ifdef BOOST_STATIC_STRING_IS_CONST_EVAL a.clear(); a.replace(a.begin(), a.end(), "a"); a.replace(a.begin(), a.end(), "a", 1); #endif // find a.find(a); a.find("a", 0, 1); a.find("a", 0); a.find('a', 0); // rfind a.rfind(a); a.rfind("a", 0, 1); a.rfind("a", 0); a.rfind('a', 0); // find_first_of a.find_first_of(a); a.find_first_of("a", 0, 1); a.find_first_of("a", 0); a.find_first_of('a', 0); // find_first_not_of a.find_first_not_of(a); a.find_first_not_of("a", 0, 1); a.find_first_not_of("a", 0); a.find_first_not_of('a', 0); // starts_with a.starts_with('a'); a.starts_with("a"); // ends_with a.ends_with('a'); a.ends_with("a"); return true; #elif defined(BOOST_STATIC_STRING_CPP11) // c++11 constexpr tests return (cstatic_string().size() + cstatic_string().length() + cstatic_string().max_size() + cstatic_string().capacity()) != 0 && cstatic_string().empty(); #endif } } // static_strings } // boost