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

tuple.hpp (5948B)


      1 #ifndef _C4_STD_TUPLE_HPP_
      2 #define _C4_STD_TUPLE_HPP_
      3 
      4 /** @file tuple.hpp */
      5 
      6 #ifndef C4CORE_SINGLE_HEADER
      7 #include "c4/format.hpp"
      8 #endif
      9 
     10 #include <tuple>
     11 
     12 /** this is a work in progress */
     13 #undef C4_TUPLE_TO_CHARS
     14 
     15 namespace c4 {
     16 
     17 #ifdef C4_TUPLE_TO_CHARS
     18 namespace detail {
     19 
     20 template< size_t Curr, class... Types >
     21 struct tuple_helper
     22 {
     23     static size_t do_cat(substr buf, std::tuple< Types... > const& tp)
     24     {
     25         size_t num = to_chars(buf, std::get<Curr>(tp));
     26         buf = buf.len >= num ? buf.sub(num) : substr{};
     27         num += tuple_helper< Curr+1, Types... >::do_cat(buf, tp);
     28         return num;
     29     }
     30 
     31     static size_t do_uncat(csubstr buf, std::tuple< Types... > & tp)
     32     {
     33         size_t num = from_str_trim(buf, &std::get<Curr>(tp));
     34         if(num == csubstr::npos) return csubstr::npos;
     35         buf = buf.len >= num ? buf.sub(num) : substr{};
     36         num += tuple_helper< Curr+1, Types... >::do_uncat(buf, tp);
     37         return num;
     38     }
     39 
     40     template< class Sep >
     41     static size_t do_catsep_more(substr buf, Sep const& sep, std::tuple< Types... > const& tp)
     42     {
     43         size_t ret = to_chars(buf, sep), num = ret;
     44         buf  = buf.len >= ret ? buf.sub(ret) : substr{};
     45         ret  = to_chars(buf, std::get<Curr>(tp));
     46         num += ret;
     47         buf  = buf.len >= ret ? buf.sub(ret) : substr{};
     48         ret  = tuple_helper< Curr+1, Types... >::do_catsep_more(buf, sep, tp);
     49         num += ret;
     50         return num;
     51     }
     52 
     53     template< class Sep >
     54     static size_t do_uncatsep_more(csubstr buf, Sep & sep, std::tuple< Types... > & tp)
     55     {
     56         size_t ret = from_str_trim(buf, &sep), num = ret;
     57         if(ret == csubstr::npos) return csubstr::npos;
     58         buf  = buf.len >= ret ? buf.sub(ret) : substr{};
     59         ret  = from_str_trim(buf, &std::get<Curr>(tp));
     60         if(ret == csubstr::npos) return csubstr::npos;
     61         num += ret;
     62         buf  = buf.len >= ret ? buf.sub(ret) : substr{};
     63         ret  = tuple_helper< Curr+1, Types... >::do_uncatsep_more(buf, sep, tp);
     64         if(ret == csubstr::npos) return csubstr::npos;
     65         num += ret;
     66         return num;
     67     }
     68 
     69     static size_t do_format(substr buf, csubstr fmt, std::tuple< Types... > const& tp)
     70     {
     71         auto pos = fmt.find("{}");
     72         if(pos != csubstr::npos)
     73         {
     74             size_t num = to_chars(buf, fmt.sub(0, pos));
     75             size_t out = num;
     76             buf  = buf.len >= num ? buf.sub(num) : substr{};
     77             num  = to_chars(buf, std::get<Curr>(tp));
     78             out += num;
     79             buf  = buf.len >= num ? buf.sub(num) : substr{};
     80             num  = tuple_helper< Curr+1, Types... >::do_format(buf, fmt.sub(pos + 2), tp);
     81             out += num;
     82             return out;
     83         }
     84         else
     85         {
     86             return format(buf, fmt);
     87         }
     88     }
     89 
     90     static size_t do_unformat(csubstr buf, csubstr fmt, std::tuple< Types... > & tp)
     91     {
     92         auto pos = fmt.find("{}");
     93         if(pos != csubstr::npos)
     94         {
     95             size_t num = pos;
     96             size_t out = num;
     97             buf  = buf.len >= num ? buf.sub(num) : substr{};
     98             num  = from_str_trim(buf, &std::get<Curr>(tp));
     99             out += num;
    100             buf  = buf.len >= num ? buf.sub(num) : substr{};
    101             num  = tuple_helper< Curr+1, Types... >::do_unformat(buf, fmt.sub(pos + 2), tp);
    102             out += num;
    103             return out;
    104         }
    105         else
    106         {
    107             return tuple_helper< sizeof...(Types), Types... >::do_unformat(buf, fmt, tp);
    108         }
    109     }
    110 
    111 };
    112 
    113 /** @todo VS compilation fails for this class */
    114 template< class... Types >
    115 struct tuple_helper< sizeof...(Types), Types... >
    116 {
    117     static size_t do_cat(substr /*buf*/, std::tuple<Types...> const& /*tp*/) { return 0; }
    118     static size_t do_uncat(csubstr /*buf*/, std::tuple<Types...> & /*tp*/) { return 0; }
    119 
    120     template< class Sep > static size_t do_catsep_more(substr /*buf*/, Sep const& /*sep*/, std::tuple<Types...> const& /*tp*/) { return 0; }
    121     template< class Sep > static size_t do_uncatsep_more(csubstr /*buf*/, Sep & /*sep*/, std::tuple<Types...> & /*tp*/) { return 0; }
    122 
    123     static size_t do_format(substr buf, csubstr fmt, std::tuple<Types...> const& /*tp*/)
    124     {
    125         return to_chars(buf, fmt);
    126     }
    127 
    128     static size_t do_unformat(csubstr buf, csubstr fmt, std::tuple<Types...> const& /*tp*/)
    129     {
    130         return 0;
    131     }
    132 };
    133 
    134 } // namespace detail
    135 
    136 template< class... Types >
    137 inline size_t cat(substr buf, std::tuple< Types... > const& tp)
    138 {
    139     return detail::tuple_helper< 0, Types... >::do_cat(buf, tp);
    140 }
    141 
    142 template< class... Types >
    143 inline size_t uncat(csubstr buf, std::tuple< Types... > & tp)
    144 {
    145     return detail::tuple_helper< 0, Types... >::do_uncat(buf, tp);
    146 }
    147 
    148 template< class Sep, class... Types >
    149 inline size_t catsep(substr buf, Sep const& sep, std::tuple< Types... > const& tp)
    150 {
    151     size_t num = to_chars(buf, std::cref(std::get<0>(tp)));
    152     buf  = buf.len >= num ? buf.sub(num) : substr{};
    153     num += detail::tuple_helper< 1, Types... >::do_catsep_more(buf, sep, tp);
    154     return num;
    155 }
    156 
    157 template< class Sep, class... Types >
    158 inline size_t uncatsep(csubstr buf, Sep & sep, std::tuple< Types... > & tp)
    159 {
    160     size_t ret = from_str_trim(buf, &std::get<0>(tp)), num = ret;
    161     if(ret == csubstr::npos) return csubstr::npos;
    162     buf  = buf.len >= ret ? buf.sub(ret) : substr{};
    163     ret  = detail::tuple_helper< 1, Types... >::do_uncatsep_more(buf, sep, tp);
    164     if(ret == csubstr::npos) return csubstr::npos;
    165     num += ret;
    166     return num;
    167 }
    168 
    169 template< class... Types >
    170 inline size_t format(substr buf, csubstr fmt, std::tuple< Types... > const& tp)
    171 {
    172     return detail::tuple_helper< 0, Types... >::do_format(buf, fmt, tp);
    173 }
    174 
    175 template< class... Types >
    176 inline size_t unformat(csubstr buf, csubstr fmt, std::tuple< Types... > & tp)
    177 {
    178     return detail::tuple_helper< 0, Types... >::do_unformat(buf, fmt, tp);
    179 }
    180 #endif // C4_TUPLE_TO_CHARS
    181 
    182 } // namespace c4
    183 
    184 #endif /* _C4_STD_TUPLE_HPP_ */