duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

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_