Path: blob/master/dep/rapidyaml/include/c4/std/tuple.hpp
4265 views
#ifndef _C4_STD_TUPLE_HPP_1#define _C4_STD_TUPLE_HPP_23/** @file tuple.hpp */45#ifndef C4CORE_SINGLE_HEADER6#include "c4/format.hpp"7#endif89#include <tuple>1011/** this is a work in progress */12#undef C4_TUPLE_TO_CHARS1314namespace c4 {1516#ifdef C4_TUPLE_TO_CHARS17namespace detail {1819template< size_t Curr, class... Types >20struct tuple_helper21{22static size_t do_cat(substr buf, std::tuple< Types... > const& tp)23{24size_t num = to_chars(buf, std::get<Curr>(tp));25buf = buf.len >= num ? buf.sub(num) : substr{};26num += tuple_helper< Curr+1, Types... >::do_cat(buf, tp);27return num;28}2930static size_t do_uncat(csubstr buf, std::tuple< Types... > & tp)31{32size_t num = from_str_trim(buf, &std::get<Curr>(tp));33if(num == csubstr::npos) return csubstr::npos;34buf = buf.len >= num ? buf.sub(num) : substr{};35num += tuple_helper< Curr+1, Types... >::do_uncat(buf, tp);36return num;37}3839template< class Sep >40static size_t do_catsep_more(substr buf, Sep const& sep, std::tuple< Types... > const& tp)41{42size_t ret = to_chars(buf, sep), num = ret;43buf = buf.len >= ret ? buf.sub(ret) : substr{};44ret = to_chars(buf, std::get<Curr>(tp));45num += ret;46buf = buf.len >= ret ? buf.sub(ret) : substr{};47ret = tuple_helper< Curr+1, Types... >::do_catsep_more(buf, sep, tp);48num += ret;49return num;50}5152template< class Sep >53static size_t do_uncatsep_more(csubstr buf, Sep & sep, std::tuple< Types... > & tp)54{55size_t ret = from_str_trim(buf, &sep), num = ret;56if(ret == csubstr::npos) return csubstr::npos;57buf = buf.len >= ret ? buf.sub(ret) : substr{};58ret = from_str_trim(buf, &std::get<Curr>(tp));59if(ret == csubstr::npos) return csubstr::npos;60num += ret;61buf = buf.len >= ret ? buf.sub(ret) : substr{};62ret = tuple_helper< Curr+1, Types... >::do_uncatsep_more(buf, sep, tp);63if(ret == csubstr::npos) return csubstr::npos;64num += ret;65return num;66}6768static size_t do_format(substr buf, csubstr fmt, std::tuple< Types... > const& tp)69{70auto pos = fmt.find("{}");71if(pos != csubstr::npos)72{73size_t num = to_chars(buf, fmt.sub(0, pos));74size_t out = num;75buf = buf.len >= num ? buf.sub(num) : substr{};76num = to_chars(buf, std::get<Curr>(tp));77out += num;78buf = buf.len >= num ? buf.sub(num) : substr{};79num = tuple_helper< Curr+1, Types... >::do_format(buf, fmt.sub(pos + 2), tp);80out += num;81return out;82}83else84{85return format(buf, fmt);86}87}8889static size_t do_unformat(csubstr buf, csubstr fmt, std::tuple< Types... > & tp)90{91auto pos = fmt.find("{}");92if(pos != csubstr::npos)93{94size_t num = pos;95size_t out = num;96buf = buf.len >= num ? buf.sub(num) : substr{};97num = from_str_trim(buf, &std::get<Curr>(tp));98out += num;99buf = buf.len >= num ? buf.sub(num) : substr{};100num = tuple_helper< Curr+1, Types... >::do_unformat(buf, fmt.sub(pos + 2), tp);101out += num;102return out;103}104else105{106return tuple_helper< sizeof...(Types), Types... >::do_unformat(buf, fmt, tp);107}108}109110};111112/** @todo VS compilation fails for this class */113template< class... Types >114struct tuple_helper< sizeof...(Types), Types... >115{116static size_t do_cat(substr /*buf*/, std::tuple<Types...> const& /*tp*/) { return 0; }117static size_t do_uncat(csubstr /*buf*/, std::tuple<Types...> & /*tp*/) { return 0; }118119template< class Sep > static size_t do_catsep_more(substr /*buf*/, Sep const& /*sep*/, std::tuple<Types...> const& /*tp*/) { return 0; }120template< class Sep > static size_t do_uncatsep_more(csubstr /*buf*/, Sep & /*sep*/, std::tuple<Types...> & /*tp*/) { return 0; }121122static size_t do_format(substr buf, csubstr fmt, std::tuple<Types...> const& /*tp*/)123{124return to_chars(buf, fmt);125}126127static size_t do_unformat(csubstr buf, csubstr fmt, std::tuple<Types...> const& /*tp*/)128{129return 0;130}131};132133} // namespace detail134135template< class... Types >136inline size_t cat(substr buf, std::tuple< Types... > const& tp)137{138return detail::tuple_helper< 0, Types... >::do_cat(buf, tp);139}140141template< class... Types >142inline size_t uncat(csubstr buf, std::tuple< Types... > & tp)143{144return detail::tuple_helper< 0, Types... >::do_uncat(buf, tp);145}146147template< class Sep, class... Types >148inline size_t catsep(substr buf, Sep const& sep, std::tuple< Types... > const& tp)149{150size_t num = to_chars(buf, std::cref(std::get<0>(tp)));151buf = buf.len >= num ? buf.sub(num) : substr{};152num += detail::tuple_helper< 1, Types... >::do_catsep_more(buf, sep, tp);153return num;154}155156template< class Sep, class... Types >157inline size_t uncatsep(csubstr buf, Sep & sep, std::tuple< Types... > & tp)158{159size_t ret = from_str_trim(buf, &std::get<0>(tp)), num = ret;160if(ret == csubstr::npos) return csubstr::npos;161buf = buf.len >= ret ? buf.sub(ret) : substr{};162ret = detail::tuple_helper< 1, Types... >::do_uncatsep_more(buf, sep, tp);163if(ret == csubstr::npos) return csubstr::npos;164num += ret;165return num;166}167168template< class... Types >169inline size_t format(substr buf, csubstr fmt, std::tuple< Types... > const& tp)170{171return detail::tuple_helper< 0, Types... >::do_format(buf, fmt, tp);172}173174template< class... Types >175inline size_t unformat(csubstr buf, csubstr fmt, std::tuple< Types... > & tp)176{177return detail::tuple_helper< 0, Types... >::do_unformat(buf, fmt, tp);178}179#endif // C4_TUPLE_TO_CHARS180181} // namespace c4182183#endif /* _C4_STD_TUPLE_HPP_ */184185186