string.hpp (4004B)
1 #ifndef _C4_STD_STRING_HPP_ 2 #define _C4_STD_STRING_HPP_ 3 4 /** @file string.hpp */ 5 6 #ifndef C4CORE_SINGLE_HEADER 7 #include "c4/substr.hpp" 8 #endif 9 10 #include <string> 11 12 namespace c4 { 13 14 //----------------------------------------------------------------------------- 15 16 /** get a writeable view to an existing std::string. 17 * When the string is empty, the returned view will be pointing 18 * at the character with value '\0', but the size will be zero. 19 * @see https://en.cppreference.com/w/cpp/string/basic_string/operator_at 20 */ 21 C4_ALWAYS_INLINE c4::substr to_substr(std::string &s) noexcept 22 { 23 #if C4_CPP < 11 24 #error this function will have undefined behavior 25 #endif 26 // since c++11 it is legal to call s[s.size()]. 27 return c4::substr(&s[0], s.size()); 28 } 29 30 /** get a readonly view to an existing std::string. 31 * When the string is empty, the returned view will be pointing 32 * at the character with value '\0', but the size will be zero. 33 * @see https://en.cppreference.com/w/cpp/string/basic_string/operator_at 34 */ 35 C4_ALWAYS_INLINE c4::csubstr to_csubstr(std::string const& s) noexcept 36 { 37 #if C4_CPP < 11 38 #error this function will have undefined behavior 39 #endif 40 // since c++11 it is legal to call s[s.size()]. 41 return c4::csubstr(&s[0], s.size()); 42 } 43 44 //----------------------------------------------------------------------------- 45 46 C4_ALWAYS_INLINE bool operator== (c4::csubstr ss, std::string const& s) { return ss.compare(to_csubstr(s)) == 0; } 47 C4_ALWAYS_INLINE bool operator!= (c4::csubstr ss, std::string const& s) { return ss.compare(to_csubstr(s)) != 0; } 48 C4_ALWAYS_INLINE bool operator>= (c4::csubstr ss, std::string const& s) { return ss.compare(to_csubstr(s)) >= 0; } 49 C4_ALWAYS_INLINE bool operator> (c4::csubstr ss, std::string const& s) { return ss.compare(to_csubstr(s)) > 0; } 50 C4_ALWAYS_INLINE bool operator<= (c4::csubstr ss, std::string const& s) { return ss.compare(to_csubstr(s)) <= 0; } 51 C4_ALWAYS_INLINE bool operator< (c4::csubstr ss, std::string const& s) { return ss.compare(to_csubstr(s)) < 0; } 52 53 C4_ALWAYS_INLINE bool operator== (std::string const& s, c4::csubstr ss) { return ss.compare(to_csubstr(s)) == 0; } 54 C4_ALWAYS_INLINE bool operator!= (std::string const& s, c4::csubstr ss) { return ss.compare(to_csubstr(s)) != 0; } 55 C4_ALWAYS_INLINE bool operator>= (std::string const& s, c4::csubstr ss) { return ss.compare(to_csubstr(s)) <= 0; } 56 C4_ALWAYS_INLINE bool operator> (std::string const& s, c4::csubstr ss) { return ss.compare(to_csubstr(s)) < 0; } 57 C4_ALWAYS_INLINE bool operator<= (std::string const& s, c4::csubstr ss) { return ss.compare(to_csubstr(s)) >= 0; } 58 C4_ALWAYS_INLINE bool operator< (std::string const& s, c4::csubstr ss) { return ss.compare(to_csubstr(s)) > 0; } 59 60 //----------------------------------------------------------------------------- 61 62 /** copy an std::string to a writeable string view */ 63 inline size_t to_chars(c4::substr buf, std::string const& s) 64 { 65 C4_ASSERT(!buf.overlaps(to_csubstr(s))); 66 size_t len = buf.len < s.size() ? buf.len : s.size(); 67 // calling memcpy with null strings is undefined behavior 68 // and will wreak havoc in calling code's branches. 69 // see https://github.com/biojppm/rapidyaml/pull/264#issuecomment-1262133637 70 if(len) 71 { 72 C4_ASSERT(s.data() != nullptr); 73 C4_ASSERT(buf.str != nullptr); 74 memcpy(buf.str, s.data(), len); 75 } 76 return s.size(); // return the number of needed chars 77 } 78 79 /** copy a string view to an existing std::string */ 80 inline bool from_chars(c4::csubstr buf, std::string * s) 81 { 82 s->resize(buf.len); 83 C4_ASSERT(!buf.overlaps(to_csubstr(*s))); 84 // calling memcpy with null strings is undefined behavior 85 // and will wreak havoc in calling code's branches. 86 // see https://github.com/biojppm/rapidyaml/pull/264#issuecomment-1262133637 87 if(buf.len) 88 { 89 C4_ASSERT(buf.str != nullptr); 90 memcpy(&(*s)[0], buf.str, buf.len); 91 } 92 return true; 93 } 94 95 } // namespace c4 96 97 #endif // _C4_STD_STRING_HPP_