capnp_list_proxy.hpp (3092B)
1 #ifndef GUARD_GREATLY_TELEMETRICAL_BIG_LABOUR_MUSICALIZES_2642 2 #define GUARD_GREATLY_TELEMETRICAL_BIG_LABOUR_MUSICALIZES_2642 3 #pragma once 4 5 #include "scraps/game/proxy_helper.hpp" // IWYU pragma: keep 6 #include "scraps/game/state_container.hpp" 7 8 #include <libshit/assert.hpp> 9 #include <libshit/except.hpp> 10 11 #include <capnp/common.h> 12 13 #include <cstddef> 14 #include <cstdint> 15 #include <stdexcept> 16 #include <tuple> 17 #include <utility> 18 19 // you can't forward declare a template with default parameters, retard 20 // IWYU pragma: no_forward_declare Scraps::Game::ConvertToImpl 21 // IWYU pragma: no_forward_declare Scraps::Game::ProxyInit 22 // IWYU pragma: no_forward_declare capnp::List 23 24 namespace Scraps::Game 25 { 26 27 template <typename ConstProxy, typename ProxyInits, typename ProxySequence> 28 class ConstCapnpListProxyImpl2; 29 30 template <typename ConstProxy, typename... ProxyInits, std::size_t... I> 31 class ConstCapnpListProxyImpl2<ConstProxy, ProxyInit<ProxyInits...>, 32 std::index_sequence<I...>> 33 : private std::tuple<ProxyInits...> // empty base optimization 34 { 35 public: 36 using ElementType = typename ConstProxy::CapnpType; 37 using CapnpType = capnp::List<ElementType>; 38 using SizeType = std::uint32_t; 39 using DifferenceType = std::int32_t; 40 41 using ProxyIterator = FatIterator< 42 ConstCapnpListProxyImpl2, ProxyInit<ProxyInits...>, 43 std::make_index_sequence<sizeof...(ProxyInits)>>; 44 45 template <typename... Args> 46 ConstCapnpListProxyImpl2(typename CapnpType::Reader lst, Args&&... args) 47 : std::tuple<ProxyInits...>{std::forward<Args>(args)...}, lst{lst} {} 48 49 ProxyIterator ProxyBegin() const 50 { return {this, 0, std::get<I>(*this)...}; } 51 ProxyIterator ProxyEnd() const 52 { return {this, lst.size(), std::get<I>(*this)...}; } 53 54 auto Proxies() const 55 { return boost::make_iterator_range(ProxyBegin(), ProxyEnd()); } 56 57 58 // todo: capnp already throws inside on invalid index, do we need these? 59 ConstProxy Get(SizeType pos) const 60 { 61 LIBSHIT_ASSERT(pos < Size()); 62 return ConstProxy{lst[pos], std::get<I>(*this)...}; 63 } 64 65 ConstProxy At(SizeType pos) const 66 { 67 if (pos >= lst.size()) 68 LIBSHIT_THROW(std::out_of_range, "ConstCapnpListProxy::At out of range", 69 "Pos", pos, "Size", lst.size()); 70 return ConstProxy{lst[pos], std::get<I>(*this)...}; 71 } 72 73 bool Empty() const noexcept { return !lst.size(); } 74 SizeType Size() const noexcept { return lst.size(); } 75 76 private: 77 typename CapnpType::Reader lst; 78 }; 79 80 template <typename ConstProxy, typename ProxyInits> 81 struct ConstCapnpListProxyImpl; 82 template <typename ConstProxy, typename... ProxyInits> 83 struct ConstCapnpListProxyImpl<ConstProxy, ProxyInit<ProxyInits...>> 84 { 85 using Type = ConstCapnpListProxyImpl2< 86 ConstProxy, ProxyInit<ProxyInits...>, 87 std::make_index_sequence<sizeof...(ProxyInits)>>; 88 }; 89 90 template <typename ConstProxy, typename ProxyInits> 91 using ConstCapnpListProxy = 92 typename ConstCapnpListProxyImpl<ConstProxy, ProxyInits>::Type; 93 94 } 95 96 #endif