Making a shared container that behaves like std::vector.

J

Jason Heyes

I wrote a previous post that asked whether there was a reference-counted
implementation of std::vector. Apparantly there wasn't. So my next question
is, is it possible to write your own shared container that behaves like
std::vector?

Here is me trying to answer that question:

class FooReference;


// user class
class Foo
{
int a;
public:
Foo() : a(3) { }
int get() const { return a; }
void set(int a_) { a = a_; }

// reference support
Foo(const FooReference &ref) : a(ref.access().a) { }
Foo &operator=(const FooReference &ref) { a = ref.access().a; }
};

// common to all references
template <class T>
class ReferenceBase
{
SharedPtr<std::vector<T> > &cont;
typename std::vector<T>::size_type pos;

protected:
T access() { cont.unshare(); return (*cont)[pos]; }
const T &access() const { return (*cont)[pos]; }

public:
typedef std::vector<T> container_type;
typedef typename container_type::size_type size_type;

ReferenceBase(size_type pos_, SharedPtr<container_type> &cont_) :
pos(pos_), cont(cont_) { }

ReferenceBase &operator=(const ReferenceBase &ref)
{ access() = ref.access(); return *this; }
};

// custom user-made reference
class FooReference : public ReferenceBase<Foo>
{
friend class Foo;

public:
FooReference(ReferenceBase<Foo>::size_type pos,
SharedPtr<ReferenceBase<Foo>::container_type> &cont) :
ReferenceBase<Foo>(pos, cont) { }

// public methods of Foo
void set(int a) { access().set(a); }
int get() const { return access().get(); }
FooReference &operator=(const Foo &rvalue)
{ access() = rvalue; return *this; }
};

// reference for basic types like int,char,etc
template <typename T>
class BasicReference : public ReferenceBase<T>
{
public:
BasicReference(ReferenceBase<T>::size_type pos,
SharedPtr<ReferenceBase<T>::container_type> &cont) :
ReferenceBase<T>(pos, cont) { }

BasicReference &operator=(const T &rvalue)
{ access() = rvalue; return *this; }
friend T &operator=(T &lvalue, const BasicReference &ref)
{ lvalue = ref.access(); return lvalue; }
};

// note the special template parameter
template <class T, class R = BasicReference<T> >
class SharedVector
{
SharedPtr<std::vector<T> > ptr;
public:
// typedefs same as std::vector except for these two
typedef R reference;
typedef const R const_reference;

// public interface same as std::vector, forwarding to ptr
// except for copy constructor, operator= and destructor
// which are compiler-generated ones

// only explicit mutator methods unshare ptr
};


// for convenience
typedef SharedVector<Foo, FooReference> FooVector;


As you can see, my shared container class will return reference objects that
act like normal C++ references (only that operator& is not defined). I have
yet to write an iterator for my shared container because I don't know how to
do it yet. But what do you guys think of what I have done so far? Thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top