vector.hpp (4062B)
1 #ifndef _C4_STD_VECTOR_HPP_ 2 #define _C4_STD_VECTOR_HPP_ 3 4 /** @file vector.hpp provides conversion and comparison facilities 5 * from/between std::vector<char> to c4::substr and c4::csubstr. 6 * @todo add to_span() and friends 7 */ 8 9 #ifndef C4CORE_SINGLE_HEADER 10 #include "c4/substr.hpp" 11 #endif 12 13 #include <vector> 14 15 namespace c4 { 16 17 //----------------------------------------------------------------------------- 18 19 /** get a substr (writeable string view) of an existing std::vector<char> */ 20 template<class Alloc> 21 c4::substr to_substr(std::vector<char, Alloc> &vec) 22 { 23 char *data = vec.empty() ? nullptr : vec.data(); // data() may or may not return a null pointer. 24 return c4::substr(data, vec.size()); 25 } 26 27 /** get a csubstr (read-only string) view of an existing std::vector<char> */ 28 template<class Alloc> 29 c4::csubstr to_csubstr(std::vector<char, Alloc> const& vec) 30 { 31 const char *data = vec.empty() ? nullptr : vec.data(); // data() may or may not return a null pointer. 32 return c4::csubstr(data, vec.size()); 33 } 34 35 //----------------------------------------------------------------------------- 36 // comparisons between substrings and std::vector<char> 37 38 template<class Alloc> C4_ALWAYS_INLINE bool operator!= (c4::csubstr ss, std::vector<char, Alloc> const& s) { return ss != to_csubstr(s); } 39 template<class Alloc> C4_ALWAYS_INLINE bool operator== (c4::csubstr ss, std::vector<char, Alloc> const& s) { return ss == to_csubstr(s); } 40 template<class Alloc> C4_ALWAYS_INLINE bool operator>= (c4::csubstr ss, std::vector<char, Alloc> const& s) { return ss >= to_csubstr(s); } 41 template<class Alloc> C4_ALWAYS_INLINE bool operator> (c4::csubstr ss, std::vector<char, Alloc> const& s) { return ss > to_csubstr(s); } 42 template<class Alloc> C4_ALWAYS_INLINE bool operator<= (c4::csubstr ss, std::vector<char, Alloc> const& s) { return ss <= to_csubstr(s); } 43 template<class Alloc> C4_ALWAYS_INLINE bool operator< (c4::csubstr ss, std::vector<char, Alloc> const& s) { return ss < to_csubstr(s); } 44 45 template<class Alloc> C4_ALWAYS_INLINE bool operator!= (std::vector<char, Alloc> const& s, c4::csubstr ss) { return ss != to_csubstr(s); } 46 template<class Alloc> C4_ALWAYS_INLINE bool operator== (std::vector<char, Alloc> const& s, c4::csubstr ss) { return ss == to_csubstr(s); } 47 template<class Alloc> C4_ALWAYS_INLINE bool operator>= (std::vector<char, Alloc> const& s, c4::csubstr ss) { return ss <= to_csubstr(s); } 48 template<class Alloc> C4_ALWAYS_INLINE bool operator> (std::vector<char, Alloc> const& s, c4::csubstr ss) { return ss < to_csubstr(s); } 49 template<class Alloc> C4_ALWAYS_INLINE bool operator<= (std::vector<char, Alloc> const& s, c4::csubstr ss) { return ss >= to_csubstr(s); } 50 template<class Alloc> C4_ALWAYS_INLINE bool operator< (std::vector<char, Alloc> const& s, c4::csubstr ss) { return ss > to_csubstr(s); } 51 52 //----------------------------------------------------------------------------- 53 54 /** copy a std::vector<char> to a writeable string view */ 55 template<class Alloc> 56 inline size_t to_chars(c4::substr buf, std::vector<char, Alloc> const& s) 57 { 58 C4_ASSERT(!buf.overlaps(to_csubstr(s))); 59 size_t len = buf.len < s.size() ? buf.len : s.size(); 60 // calling memcpy with null strings is undefined behavior 61 // and will wreak havoc in calling code's branches. 62 // see https://github.com/biojppm/rapidyaml/pull/264#issuecomment-1262133637 63 if(len > 0) 64 { 65 memcpy(buf.str, s.data(), len); 66 } 67 return s.size(); // return the number of needed chars 68 } 69 70 /** copy a string view to an existing std::vector<char> */ 71 template<class Alloc> 72 inline bool from_chars(c4::csubstr buf, std::vector<char, Alloc> * s) 73 { 74 s->resize(buf.len); 75 C4_ASSERT(!buf.overlaps(to_csubstr(*s))); 76 // calling memcpy with null strings is undefined behavior 77 // and will wreak havoc in calling code's branches. 78 // see https://github.com/biojppm/rapidyaml/pull/264#issuecomment-1262133637 79 if(buf.len > 0) 80 { 81 memcpy(&(*s)[0], buf.str, buf.len); 82 } 83 return true; 84 } 85 86 } // namespace c4 87 88 #endif // _C4_STD_VECTOR_HPP_