By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,406 Members | 888 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,406 IT Pros & Developers. It's quick & easy.

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

P: n/a
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.
Jul 22 '05 #1
Share this question for a faster answer!
Share on Google+

This discussion thread is closed

Replies have been disabled for this discussion.