Boost logo

Boost :

Subject: [boost] [ValueRef] Interest in a new library for immutable values with internal sharing?
From: THOMAS JORDAN (tomjordan766_at_[hidden])
Date: 2015-04-20 06:04:22


Hi,
I'd like to gauge whether there might be any interest in a new Boost
library comprising a generic, non-intrusive, wrapper class for creating
immutable/const values with sharing of the underlying object via internal
reference counting.
This new class would be called ValueRef (or possibly just Value), and it
would effectively provide an assignable/swappable 'reference'/handle to
shared, const values. It can be considered an effective alternative to the
commonly used shared-pointer-to-const idiom, providing cleaner and more
explicit value semantics, whilst also hiding calls to 'new' as an internal
implementation detail.

In a nutshell, ValueRef adapts a regular type T to give a new type
ValueRef<T> with const T value semantics and uses reference counting of an
underlying object on the heap internally to reduce copying overhead.
ValueRef will spawn off a new copy of the wrapped object (if necessary) if
the ValueRef is assigned another ValueRef or another object of type T.
Const functions of T do not incur any overhead of counter access or copy
and are invoked by either * or -> syntax.
Forwarding constructors are provided which permit the wrapped value to be
constructed in place, and conversion operator allows inter-operation with
values of the unwrapped type. ValueRef also provides the common relational
operators.
I have so far implemented a rough (C++03-only so far) version of this
(based on a stripped down version of Adobe::copy_on_write library) and a
test suite and it seems to work okay.

Example usage:

/* type of ValueRef wrapped std::vector<int> */
typedef ValueRef<std::vector<int> > ValueRefVecType;

/* create vector of 10 elements via forwarding constructor */
ValueRefVecType valueRefVector1(10,1);

/* non-mutating/const op */
assert( valueRefVector1->size() == 10 );

/* non-mutating/const op */
assert( (*valueRefVector1)[0] == 1 );

/* error - compilation failure occurs calling a non-const op */
(*valueRefVector)[0] = 2;

/* copy ctor */
ValueRefVecType valueRefVector2(valueRefVector1);

/* test for equality */
assert( valueRefVector1 == valueRefVector2 );

/* test for equality (implicit conversion) */
assert( valueRefVector2 == std::vector<int>(10,1) );

/* valueRefVector1 and valueRefVector2 share same std::vector */
assert( valueRefVector1.identity(valueRefVector2) );

/* ref count is no longer one */
assert( !valueRefVector1.unique_instance() );

/* new value */
valueRefVector1 = std::vector<int>(5);

/* non-mutating/const */
assert( valueRefVector1->size() == 5 );

/* test for equality - value semantics */
assert( !(valueRefVector1 == valueRefVector2) );

/* valueRefVector1 and valueRefVector2 do not share same std::vector */
assert( !valueRefVector1.identity(valueRefVector2) );

I am not aware of anything else current that provides this functionality.

Regards,
Tom


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk