
THOMAS JORDAN <tomjordan766 <at> gmail.com> writes:
From: Andrey Semashev <andrey.semashev <at> gmail.com>
Is this similar to Boost.Flyweight?
It is similar in that both provide a 'smart' handle which can be used pretty much as a drop in for the wrapped type.
However, Boost.Flyweight requires the wrapped type to be hashable.
Not necessarily; set_factory, for instance, requires values to be less-than comparable: http://boost.org/libs/flyweight/doc/tutorial/configuration.html#set_factory Also, see below.
Also, there is a level of indirection with Flyweight which can mean that unnecessary temps may need to be created to do the initial lookup (and addition) to the Flyweight store, unless you use the Flyweight key-map interface.
Boost.Flyweight uses move semantics and perfect fwd ction where available, I don't see how another solution can do better on this front.
ValueRef does not use 'flyweighting.' That is, if there are two ValueRefs created independently with the same value, e.g.,
ValueRef<std::vector<int> > v1(10,10), v2(10,10);
there will be two separate wrapped vector<int> objects - it is only when copying/assigning that sharing takes place. It is simpler than Flyweight and is essentially intended to be a more value-orientated option to shared-ptr-to-const.
The lib is extensible to the point that ValueRef can potentially be built on top of it: template<typename Entry,typename Key> struct ValueRefFactory { using handle_type=Entry*; template <typename E> handle_type insert(E&& x){return new Entry{std::forward<E>(x)};} void erase(handle_type h){delete h;} const Entry& entry(handle_type h){return *h;} }; template<typename T> using ValueRefImpl=flyweight< T,no_locking, factory<ValueRefFactory<boost::mpl::_1,boost::mpl::_2>>>; template<typename T> struct ValueRef:ValueRefImpl<T> { using impl_type=ValueRefImpl<T>; const impl_type& impl()const{return *this;} using impl_type::impl_type; ValueRef(const ValueRef&x):impl_type(x.impl()){} ValueRef(ValueRef&x):impl_type(x.impl()){} ValueRef(const ValueRef&&x):impl_type(x.impl()){} ValueRef(ValueRef&&x):impl_type(x.impl()){} using impl_type::operator=; const T& operator*()const{return this->get();} const T* operator->()const{return &this->get();} bool identity(const ValueRef& x)const{return &**this==&*x;} }; See complete example at: http://coliru.stacked-crooked.com/a/c33389766fac6ecb (except the unique_instance bit, which can be done, but admittedly with more effort).
Another (less significant) difference is that ValueRef currently has no dependency on MPL, which I believe Flyweight does, though that could well change if needed.
Boost.Flyweight is indeed heavier on the include side than some people might be comfortable with. Joaquín M López Muñoz Telefónica