Adobe.Poly — Holder
#include <cassert>
#include <adobe/poly.hpp>
#include <boost/concept_check.hpp>
template <typename H>
struct HolderConcept : boost::Assignable<H>
, boost::CopyConstructible<H>
{
BOOST_CONCEPT_USAGE(HolderConcept)
{
h.store(i);
i = load(h);
}
private:
H h;
int i;
};
struct SomeHolder
{
int val = 0;
void store(int i) { val = i; }
};
int load(SomeHolder & h) { return h.val; }
BOOST_CONCEPT_ASSERT((HolderConcept<SomeHolder>));
// Type erased interface
struct HolderIface : adobe::poly_copyable_interface
{
virtual void store(int) = 0;
virtual int free_load() = 0;
};
template <typename T>
struct HolderImpl
: adobe::optimized_storage_type<T, HolderIface>::type
{
using base_t = typename
adobe::optimized_storage_type<T, HolderIface>::type;
BOOST_CONCEPT_ASSERT((HolderConcept<T>));
HolderImpl(T x) : base_t(x) {}
HolderImpl(adobe::move_from<HolderImpl> x)
: base_t(adobe::move_from<base_t>(x.source)) {}
void store(int i) override { this->get().store(i); }
int free_load() override { return load(this->get()); }
};
struct Holder : adobe::poly_base<HolderIface, HolderImpl>
{
using base_t = adobe::poly_base<HolderIface, HolderImpl> ;
using base_t::base_t;
Holder(adobe::move_from<Holder> x)
: base_t(adobe::move_from<base_t>(x.source)) {}
void store(int i)
{ interface_ref().store(i); }
friend int load(Holder & h)
{ return h.interface_ref().free_load(); }
};
typedef adobe::poly<Holder> AnyHolder;
BOOST_CONCEPT_ASSERT((HolderConcept<AnyHolder>));
int main()
{
AnyHolder h {SomeHolder{}};
h.store(2);
int i = load(h);
assert (i == 2);
}
Like this:
Like Loading...