need help with design issue...

A

aaragon

Hello everybody,
I appreciate your taking the time to take a look at this example. I
need some help to start the design of an application. To that purpose
I'm using policy-based design. The idea is to have a Class that stores
elements of Class2 in different ways (arrays in stack memory, arrays in
heap memory, using the std::vector and so on). I would like the user
to customize the creation of a class with Class2 and StoragePolicy like
this

typedef Class<Class2,HeapStorage> class_;

A way to accomplish this may be

template <
class T,
class Class2,
template <class> class StoragePolicy = Storage2 >
class Population : public StoragePolicy<Class2>
{
T* pointee_; // points to actual storage
...
};

However, in this way the user cannot customize in the way given before
but it has to introduce the type that pointee_ points to (and this is
not good because the design should know what pointee_ points to from
the StoragePolicy). Therefore, take 2 becomes:

template <class T>
class StoragePolicy
{
void create(size_t s);
};

template <class T>
struct Storage1
{
void create(size_t s) { storage_ = std::vector<T>(s);}
protected:
std::vector<T> storage_;
~StdVectorStorage() {}
};

<
class Class2,
template <class> class StoragePolicy = Storage1 >
class Class : public StoragePolicy<Class2>
{
// this->storage_ (the storage_ is inherited from one of the
StoragePolicy classes)
...
};

This is the way I thought it better to solve this problem. Now, the
questions I have are:
1. Is there a better solution for this? More elegant? Maybe with
better performance?
2. In this way, I can't declare the function create() static because I
have a variable in the PolicyClass, right? I tried but I have a
linkage error in the compilation.
3. Now the key issue. Once I have many of these storage policy
classes, I don't know what to do to traverse the containers. It would
be nice to have a random access iterator that traverses the container
as with the standard library. How do I accomplish this?

Once again, thanks for taking the time to read this. I appreciate it.
Best regards,

Alejandro A.
 
D

Daniel T.

aaragon said:
Hello everybody,
I appreciate your taking the time to take a look at this example. I
need some help to start the design of an application. To that purpose
I'm using policy-based design. The idea is to have a Class that stores
elements of Class2 in different ways (arrays in stack memory, arrays in
heap memory, using the std::vector and so on).

The simplest, I expect would be to write your class under the assumption
that it is holding a Sequence
(http://www.sgi.com/tech/stl/Sequence.html) 'vector', deque and list
already conform to the Sequence concept and it doesn't take much to
create a C array wrapper that does so as well.

template < typename Sequence >
class Population
{
Sequence sequence;
typedef typename Sequence::value_type value_type;
};

'value_type' is the type of the objects stored in the Sequence.
3. Now the key issue. Once I have many of these storage policy
classes, I don't know what to do to traverse the containers. It would
be nice to have a random access iterator that traverses the container
as with the standard library. How do I accomplish this?

All Sequence classes have 'begin' and 'end' which return iterators, but
you can't assume they are all random access because Sequence doesn't
make that guarantee.
 
A

aaragon

Daniel said:
The simplest, I expect would be to write your class under the assumption
that it is holding a Sequence
(http://www.sgi.com/tech/stl/Sequence.html) 'vector', deque and list
already conform to the Sequence concept and it doesn't take much to
create a C array wrapper that does so as well.

How do you create the wrapper?
template < typename Sequence >
class Population
{
Sequence sequence;
typedef typename Sequence::value_type value_type;
};

'value_type' is the type of the objects stored in the Sequence.

Well, but I want the user to specify the value_type, right? by defining
the class as

typedef Population<value_type,storage_type> pop_;

How do I accomplish this by using the sequence?
 
D

Daniel T.

aaragon said:
How do you create the wrapper?

There is one in The C++ Programming Language by Stroustrup. Below is
part of it...

template < typename T, int max >
struct c_array {
typedef T value_type;
typedef T* iterator;
typedef const T* const_iterator;
typedef T& reference;
typedef const T& const_reference;

T v[max];
operator T*() { return v; }

reference operator[](size_t i) { return v; }

iterator begin() { return v; }
iterator end() { return v + max; }

ptrdiff_t size() const { return max; }
};

Well, but I want the user to specify the value_type, right? by
defining the class as

typedef Population<value_type,storage_type> pop_;

How do I accomplish this by using the sequence?

Population< vector< int > > IntPopulationWithVector;
Population< list< double > > DoublePopulationWithList;
Population< c_array< char, 10 > > CharPopulationWithCArray;
 
A

aaragon

Daniel said:
aaragon said:
How do you create the wrapper?

There is one in The C++ Programming Language by Stroustrup. Below is
part of it...

template < typename T, int max >
struct c_array {
typedef T value_type;
typedef T* iterator;
typedef const T* const_iterator;
typedef T& reference;
typedef const T& const_reference;

T v[max];
operator T*() { return v; }

reference operator[](size_t i) { return v; }

iterator begin() { return v; }
iterator end() { return v + max; }

ptrdiff_t size() const { return max; }
};

Well, but I want the user to specify the value_type, right? by
defining the class as

typedef Population<value_type,storage_type> pop_;

How do I accomplish this by using the sequence?

Population< vector< int > > IntPopulationWithVector;
Population< list< double > > DoublePopulationWithList;
Population< c_array< char, 10 > > CharPopulationWithCArray;


GOT IT!!! =)
This is going to be quite helpful... I guess now I have to play with
the template template parameters to avoid including the type twice
(i.e., Population<double,vector<double>>). I have also to include the
header files for vector and list. I could define empty structures to
assign other names to it, right? I saw in the boost library something
like
struct StdVector {};
struct StdList {};

template <class Selector, class ValueType>
struct container_gen { };

template <class ValueType>
struct container_gen<vecS, ValueType>
{
typedef std::vector<ValueType> type;
};

template <class ValueType>
struct container_gen<listS, ValueType>
{
typedef std::list<ValueType> type;
};

Well, I think I have all I need now to start coding. Thanks Daniel for
the tips, I appreciate it... =)
 
D

Daniel T.

aaragon said:
Daniel T. wrote:
GOT IT!!! =)
This is going to be quite helpful... I guess now I have to play with
the template template parameters to avoid including the type twice
(i.e., Population<double,vector<double>>).

Apparently, you do not yet have it. I declared three different
Population objects above without ever including the type twice. No need
for template template parameters.
I have also to include the header files for vector and list.

Only if you actually use them and they shouldn't be included in the
population.h file; the client code would have to include them.
I could define empty structures to assign other names to it, right?

No need.
I saw in the boost library something
like
struct StdVector {};
struct StdList {};

template <class Selector, class ValueType>
struct container_gen { };

template <class ValueType>
struct container_gen<vecS, ValueType>
{
typedef std::vector<ValueType> type;
};

template <class ValueType>
struct container_gen<listS, ValueType>
{
typedef std::list<ValueType> type;
};

All the above is way more complex than it needs to be.
Well, I think I have all I need now to start coding. Thanks Daniel for
the tips, I appreciate it... =)

Again, check out the web page I posted (here it is again
http://www.sgi.com/tech/stl/Sequence.html) and do this:

template < typename Sequence >
class Population {
Sequence sequence;
//...

Now code the rest of your class as if 'sequence' contains all the
member-functions and typedefs defined on that page (and this page
http://www.sgi.com/tech/stl/Container.html because Sequences are also
Containers.) That's all you need to do. Forget about all that stuff you
have above.
 

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,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top