Designing a template class for memory access

J

James Brown

Hi all,

Having problems designing a template-class. I'll describe my scenario
first then show what I've come up with so far:

Need a class to provide pointer/array-like access to an area of physical
memory
located on a piece of custom hardware - this memory is only accessible
using machine specific i/o so I want to hide all this in a class. I'm
imagining
that the class will provide behaviour similar to a vector or string class -
that
is, provide operator[] access, maybe pointer-like behaviour using ++ and --
operators and the * dereference operator.

The class might be used like:

pmem<char> physmem;

physmem[0] = 'A'; // store 'A' at offset 0
physmem++;
physmem[0] = 'B'; // store 'B' at offset 1

char ch = *physmem;

and maybe even

cout << physmem;

i.e. physmem somehow "decays" to a char* pointer..

I'm having alot of difficulty deciding what kind of facility I should
provide,
really due to lack of experience with C++

my so far class looks like:

template <class type>
class pmem
{
public:
pmem() : index(0) {}

type & operator(size_t offset);
const type &operator(size_t offset) const;

private:
size_t index;
type *view;

// private members to map/unmap the physical memory
// into the "view" buffer
}

The class must map/unmap the physical memory in views - i.e. very similar
to a segmented memory architecture, so the [] operators need to handle this
and
provide a strictly controlled "linear" access to this segmented model.

Within the physical memory there are memory regions which would be
easily represented by normal C structures - what I want to avoid is code
like this:

struct mystruct
{
int member1;
int member2;
};

mystruct ms;
physmem.read(&ms , sizeof(mystruct));

cout << ms.member1 << endl;

and replace it with something similar to:

pmem<mystruct *> physmem;
cout << physmem->member1;

Hope I've provided a good enough example here..
Does anyone have any suggestions as to best practises for this type of
thing, good
books to read? I can code the thing up quite happily, its the design stage
which is
hindering me at the moment.

TIA
James
 
K

Kai-Uwe Bux

James Brown said:
Hi all,

Having problems designing a template-class. I'll describe my scenario
first then show what I've come up with so far:

Need a class to provide pointer/array-like access to an area of physical
memory
located on a piece of custom hardware - this memory is only accessible
using machine specific i/o so I want to hide all this in a class. I'm
imagining
that the class will provide behaviour similar to a vector or string class
- that
is, provide operator[] access, maybe pointer-like behaviour using ++ and
-- operators and the * dereference operator.

The class might be used like:

pmem<char> physmem;

physmem[0] = 'A'; // store 'A' at offset 0
physmem++;
physmem[0] = 'B'; // store 'B' at offset 1

char ch = *physmem;

and maybe even

cout << physmem;

i.e. physmem somehow "decays" to a char* pointer..

So far, this looks like you want to provide some sort of an iterator for an
anonymous container. In this case, I would suggest to mimick the interface
of random access iterators to some degree. If you do that, you will be able
to use the generic algorithms on those. Be sure to have a value that
represents the past-end position of the container.
I'm having alot of difficulty deciding what kind of facility I should
provide,
really due to lack of experience with C++

my so far class looks like:

template <class type>
class pmem
{
public:
pmem() : index(0) {}

type & operator(size_t offset);
const type &operator(size_t offset) const;

This does not match your descritption above. I was expecting to see
stuff like:

type& operator* ();
const type& operator* () const;

type& operator[] ( std::size_t );
const type& operator[] ( std::size_t ) const;

std::ptrdiff_t operator- ( pmem const & other ) const;

pmem& operator+=( std::ptrdiff_t );

pmem& operator++();
...

and I would suggest to include some typedefs like

typedef type value_type;
typedef type* pointer_type;
...


private:
size_t index;
type *view;

// private members to map/unmap the physical memory
// into the "view" buffer
}

The class must map/unmap the physical memory in views - i.e. very similar
to a segmented memory architecture, so the [] operators need to handle
this and
provide a strictly controlled "linear" access to this segmented model.

Within the physical memory there are memory regions which would be
easily represented by normal C structures - what I want to avoid is code
like this:

struct mystruct
{
int member1;
int member2;
};

mystruct ms;
physmem.read(&ms , sizeof(mystruct));

cout << ms.member1 << endl;

and replace it with something similar to:

pmem<mystruct *> physmem;

You are confusing me. Do you want

pmem<mystruct> physmem

instead?
cout << physmem->member1;

Hope I've provided a good enough example here..
Does anyone have any suggestions as to best practises for this type of
thing, good
books to read? I can code the thing up quite happily, its the design stage
which is hindering me at the moment.


Best

Kai-Uwe Bux
 
K

Karthik Kumar

James said:
Hi all,

Having problems designing a template-class. I'll describe my scenario
first then show what I've come up with so far:

Need a class to provide pointer/array-like access to an area of physical
memory
located on a piece of custom hardware - this memory is only accessible
using machine specific i/o so I want to hide all this in a class. I'm
imagining
that the class will provide behaviour similar to a vector or string class -
that
is, provide operator[] access, maybe pointer-like behaviour using ++ and --
operators and the * dereference operator.

The class might be used like:

pmem<char> physmem;

physmem[0] = 'A'; // store 'A' at offset 0
physmem++;
physmem[0] = 'B'; // store 'B' at offset 1

char ch = *physmem;

and maybe even

cout << physmem;

i.e. physmem somehow "decays" to a char* pointer..

In C++, you can think about 'string's instead of char * .
It is much cleaner . The STL 'string' and 'sstream' could really be
useful instead of dealing with raw char pointers.
I'm having alot of difficulty deciding what kind of facility I should
provide,
really due to lack of experience with C++

my so far class looks like:

template <class type>

You can use -

template <ctypename type> for better readability . It is a matter of
style, but nevertheless improves readability of the code.

Again as a metter of style, typenames more often than not, begin with
a capital letter.
class pmem
{
public:
pmem() : index(0) {}

type & operator(size_t offset);

Did u mean to support constructs like -
'
A' = physmem[0] ; // appearing on the R.H.S.

when you write this signature.

That hinders the readability of the code again.
const type &operator(size_t offset) const;


fine. but what happens if offset is outside the 'segment' .
How are you going to handle it.

Are you going to throw custom exceptions from your code ? That would
be natural. And in case, you are throwing some - it is a good idea to
mention them in the throw clause here , so that anyone who uses the API
would know what exceptions to catch and deal accordingly.



private:
size_t index;
type *view;

// private members to map/unmap the physical memory
// into the "view" buffer
}

The class must map/unmap the physical memory in views - i.e. very similar
to a segmented memory architecture, so the [] operators need to handle this
and
provide a strictly controlled "linear" access to this segmented model.

Within the physical memory there are memory regions which would be
easily represented by normal C structures - what I want to avoid is code
like this:

struct mystruct
{
int member1;
int member2;
};

mystruct ms;
physmem.read(&ms , sizeof(mystruct));

cout << ms.member1 << endl;

and replace it with something similar to:

pmem<mystruct *> physmem;
cout << physmem->member1;

Hope I've provided a good enough example here..
Does anyone have any suggestions as to best practises for this type of
thing, good
books to read?

http://accu.org/bookreviews/public/reviews/0sb/index.htm .

Look in the sections related to beginner C++ and advanced C++ .

I can code the thing up quite happily, its the design stage
which is
hindering me at the moment.

It is always a good thing to spend a lot of time in designing things
since coding can be wrapped up soon once you are clear about the
specifications of the class(es).
 
K

Karthik Kumar

Karthik said:
You can use -

template <ctypename type> for better readability . It is a matter of
style, but nevertheless improves readability of the code.

Oops ! I meant -

template <typename T> .
 
J

James Brown

Kai-Uwe Bux said:
James Brown said:
Hi all,

Having problems designing a template-class. I'll describe my scenario
first then show what I've come up with so far:

Need a class to provide pointer/array-like access to an area of physical
memory
located on a piece of custom hardware - this memory is only accessible
using machine specific i/o so I want to hide all this in a class. I'm
imagining
that the class will provide behaviour similar to a vector or string class
- that
is, provide operator[] access, maybe pointer-like behaviour using ++ and
-- operators and the * dereference operator.

The class might be used like:

pmem<char> physmem;

physmem[0] = 'A'; // store 'A' at offset 0
physmem++;
physmem[0] = 'B'; // store 'B' at offset 1

char ch = *physmem;

and maybe even

cout << physmem;

i.e. physmem somehow "decays" to a char* pointer..

So far, this looks like you want to provide some sort of an iterator for
an
anonymous container. In this case, I would suggest to mimick the interface
of random access iterators to some degree. If you do that, you will be
able
to use the generic algorithms on those. Be sure to have a value that
represents the past-end position of the container.
I'm having alot of difficulty deciding what kind of facility I should
provide,
really due to lack of experience with C++

my so far class looks like:

template <class type>
class pmem
{
public:
pmem() : index(0) {}

type & operator(size_t offset);
const type &operator(size_t offset) const;

This does not match your descritption above. I was expecting to see
stuff like:

type& operator* ();
const type& operator* () const;

type& operator[] ( std::size_t );
const type& operator[] ( std::size_t ) const;

std::ptrdiff_t operator- ( pmem const & other ) const;

pmem& operator+=( std::ptrdiff_t );

pmem& operator++();
...

and I would suggest to include some typedefs like

typedef type value_type;
typedef type* pointer_type;
...


private:
size_t index;
type *view;

// private members to map/unmap the physical memory
// into the "view" buffer
}

The class must map/unmap the physical memory in views - i.e. very similar
to a segmented memory architecture, so the [] operators need to handle
this and
provide a strictly controlled "linear" access to this segmented model.

Within the physical memory there are memory regions which would be
easily represented by normal C structures - what I want to avoid is code
like this:

struct mystruct
{
int member1;
int member2;
};

mystruct ms;
physmem.read(&ms , sizeof(mystruct));

cout << ms.member1 << endl;

and replace it with something similar to:

pmem<mystruct *> physmem;

You are confusing me. Do you want

pmem<mystruct> physmem

instead?
cout << physmem->member1;

Hope I've provided a good enough example here..
Does anyone have any suggestions as to best practises for this type of
thing, good
books to read? I can code the thing up quite happily, its the design
stage
which is hindering me at the moment.


Best

Kai-Uwe Bux

Hi,
thanks for the suggestions,
yes, I think an iterator-like class would be a good idea, especially one
that
can be used with algorithms...the trouble I have is because I have very
rarely used
this facility in C++ I don't know how to design something similar..but your
suggestion
is useful to me regardless..

My idea with the member-selection operator is probably incorrect - to be
honest
I'm not sure if I need pmem<mystruct> or pmem<mystruct *>, basically I'm a
C programmer who's very comfortable with array/pointer syntax, but unuse to
the
C++ way of achieving the same effect.

James
 
J

James Brown

Karthik Kumar said:
Oops ! I meant -

template <typename T> .

Yes, I thought you meant that - this is syntax that I'm not familiar with,
does template <typename X> an exact replacement for template <class X>
if so why do two constructs exist for the same result?

thks,
James
 
J

James Brown

Karthik Kumar said:
James said:
Hi all,

Having problems designing a template-class. I'll describe my scenario
first then show what I've come up with so far:

Need a class to provide pointer/array-like access to an area of physical
memory
located on a piece of custom hardware - this memory is only accessible
using machine specific i/o so I want to hide all this in a class. I'm
imagining
that the class will provide behaviour similar to a vector or string
class - that
is, provide operator[] access, maybe pointer-like behaviour using ++
and --
operators and the * dereference operator.

The class might be used like:

pmem<char> physmem;

physmem[0] = 'A'; // store 'A' at offset 0
physmem++;
physmem[0] = 'B'; // store 'B' at offset 1

char ch = *physmem;

and maybe even

cout << physmem;

i.e. physmem somehow "decays" to a char* pointer..

In C++, you can think about 'string's instead of char * .
It is much cleaner . The STL 'string' and 'sstream' could really be useful
instead of dealing with raw char pointers.
I'm having alot of difficulty deciding what kind of facility I should
provide,
really due to lack of experience with C++

my so far class looks like:

template <class type>

You can use -

template <ctypename type> for better readability . It is a matter of
style, but nevertheless improves readability of the code.

Again as a metter of style, typenames more often than not, begin with a
capital letter.
class pmem
{
public:
pmem() : index(0) {}

type & operator(size_t offset);

Did u mean to support constructs like -
'
A' = physmem[0] ; // appearing on the R.H.S.

when you write this signature.

Yes, I also want to achieve "normal" array subscripting.
That hinders the readability of the code again.



fine. but what happens if offset is outside the 'segment' .
How are you going to handle it.

To be honest I'm not sure - all instances of my class will share a
cache of currently mapped-in pages for performance reasons, but yes there
is a potential problem when accessing offsets outside the current segment -
to address this issue the [] operator would map/unmap segments as
required.

The one big worry I have is, what do I do when I try to access an
"element" of my class which straddles a segment boundary. Perhaps it is
not possible to represent a segmented view in the manner I desire..

Are you going to throw custom exceptions from your code ? That would be
natural. And in case, you are throwing some - it is a good idea to mention
them in the throw clause here , so that anyone who uses the API
would know what exceptions to catch and deal accordingly.

Yup exceptions sound like a good idea thanks :)
private:
size_t index;
type *view;

// private members to map/unmap the physical memory
// into the "view" buffer
}

The class must map/unmap the physical memory in views - i.e. very similar
to a segmented memory architecture, so the [] operators need to handle
this and
provide a strictly controlled "linear" access to this segmented model.

Within the physical memory there are memory regions which would be
easily represented by normal C structures - what I want to avoid is code
like this:

struct mystruct
{
int member1;
int member2;
};

mystruct ms;
physmem.read(&ms , sizeof(mystruct));

cout << ms.member1 << endl;

and replace it with something similar to:

pmem<mystruct *> physmem;
cout << physmem->member1;

Hope I've provided a good enough example here..
Does anyone have any suggestions as to best practises for this type of
thing, good
books to read?

http://accu.org/bookreviews/public/reviews/0sb/index.htm .

Look in the sections related to beginner C++ and advanced C++ .

I can code the thing up quite happily, its the design stage which is
hindering me at the moment.

It is always a good thing to spend a lot of time in designing things
since coding can be wrapped up soon once you are clear about the
specifications of the class(es).

Thanks,
James
 
J

John Harrison

My idea with the member-selection operator is probably incorrect - to be
honest
I'm not sure if I need pmem<mystruct> or pmem<mystruct *>, basically I'm a
C programmer who's very comfortable with array/pointer syntax, but unuse
to the
C++ way of achieving the same effect.

Your class is a container (of sorts). Do you see it containing pointers,
pmem<mystruct *>, or structs, pmem<mystruct>. My guess would be structs.

john
 
J

John Harrison

James Brown said:
Yes, I thought you meant that - this is syntax that I'm not familiar with,
does template <typename X> an exact replacement for template <class X>
if so why do two constructs exist for the same result?

thks,
James

It's an exact equivalent. class is traditional, but someone thought that T
in template <class T> doesn't have to be a class (it could be an int for
instance) so template <typename T> was added.

john
 
J

James Brown

John Harrison said:
Your class is a container (of sorts). Do you see it containing pointers,
pmem<mystruct *>, or structs, pmem<mystruct>. My guess would be structs.

john

Hi John,
thanks for your reply,

I see the underlying memory region containing a (primarily) structures
but also a few pointers as well, this is why I was trying to use the
template
syntax so that I could choose the most appropriate form when necessary..

but yes, a structured layout is my preferred way of accessing the memory.

thanks
james
 
J

Jeff Flinn

James Brown said:
....

yes, I think an iterator-like class would be a good idea, especially one
that
can be used with algorithms...the trouble I have is because I have very
rarely used
this facility in C++ I don't know how to design something similar..but your
suggestion
is useful to me regardless..

This is a perfect application for an iterator_facade from the boost library.
See http://www.boost.org/libs/iterator/doc/iterator_facade.html. You would
derive from an iterator_facade specialization and implement the methods:

dereference
equal
increment
decrement
advance
distance_to

The iterator_facade has all of the boiler plate necessary to create a proper
iterator. This is a header-only library, so you just need to include the
iterator_facade header file.

Jeff F
 
K

Kai-Uwe Bux

James Brown said:
yes, I think an iterator-like class would be a good idea, especially one
that
can be used with algorithms...the trouble I have is because I have very
rarely used
this facility in C++ I don't know how to design something similar..but
your suggestion
is useful to me regardless..

Basically, an iterator class provides the following interface (I may have
forgotten something):

#include <memory>

template < typename ValueType >
class iterator {
public:

// ================
// | formal stuff |
// ================
/*
actually, these are implementation defined. The references and pointers
could be realized by fancy proxy objects, etc.
*/
typedef ValueType value_type;
typedef ValueType& reference;
typedef const ValueType& const_reference;
typedef ValueType* pointer;
typedef const ValueType* const_pointer;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;


// =====================
// | booooooring stuff |
// =====================

// default constructor
iterator ( void );

// copy constructor
iterator ( const iterator & other );

// assignment operator
iterator& operator= ( const iterator & other );

// destructor
~iterator ( void );


// ==================
// | the real stuff |
// ==================

// dereferencing, makes our class look somewhat like ValueType*.
pointer operator* ( void );
const_pointer operator* ( void ) const;

// optional:
reference operator[] ( size_type );
const_reference operator[] ( size_type ) const;

// moving
iterator operator++ ( void );
iterator operator++ ( int );
iterator operator-- ( void );
iterator operator-- ( int );

iterator operator+= ( difference_type );
iterator operator-= ( difference_type );

iterator operator+ ( difference_type ) const;
iterator operator- ( difference_type ) const;

// measuring distances:
bool operator== ( const iterator & other ) const;
bool operator!= ( const iterator & other ) const;
bool operator< ( const iterator & other ) const;
bool operator<= ( const iterator & other ) const;
bool operator> ( const iterator & other ) const;
bool operator>= ( const iterator & other ) const;
difference_type operator- ( const iterator & other ) const;

}; // iterator<>

As you can see, it mimicks a ValueType* that traverses an array.

Note that there is a lot of redundancy, i.e., many of these methods can be
implemented in terms of others. My understanding is that Boost has a
library that provides that for you.

Of course, you will have to implement the most interesting stuff yourself:
the operator* that actually realizes access to the underlying data.

In addition, you will want to specialize the template iterator_traits<> for
your particular iterator. I think that boost also helps with that but I
have no first hand experience with that.

Finally, you need a method to get an iterator object to the beginning of
the range.

My idea with the member-selection operator is probably incorrect - to be
honest
I'm not sure if I need pmem<mystruct> or pmem<mystruct *>, basically I'm a
C programmer who's very comfortable with array/pointer syntax, but unuse
to the
C++ way of achieving the same effect.

I guess, you want iterator< mystruct >. From the callers perspective, it
behaves like mystruct*.



Best

Kai-Uwe Bux
 

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

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top