F
Frederick Gotham
Inspired by page 219 of Nicolai M. Josuttis's book, I set out to write a
class for an intrinsic array which would behave, to as far an extent as
possible, like a container. Also though, I wanted no overhead whatsoever.
The code I'm about to show below is not finished, it may contain the odd
oversight, bug or error (but at a quick glance it seems OK).
First of all though, I want to show you some macros I've written. The
purpose of the macros is to:
(1) Reduce repetitive typing.
(2) Reduce the possibility for error.
Before you use these macros though, you must a typedef to your class, e.g.:
class SmartPointerOrWhatever {
typedef SmartPointerOrWhatever ThisClass;
};
The first macro, "POST_IN_TERMS_OF", expands to a definition of a post-
operator which invokes the corresponding pre-operator. Here it is:
#define POST_IN_TERMS_OF(op) \
ThisClass operator op(int) \
{ \
ThisClass const temp(*this); \
op *this; \
return temp; \
}
The second macro, "OP_IN_TERMS_OF", expands to a definition of an operator
such as +, which works off +=. Here it is:
#define OP_IN_TERMS_OF(op,param_dec,obj) \
ThisClass operator op(param_dec) const \
{ \
ThisClass temp(*this); \
temp op##= obj; \
return temp; \
}
(I realise that this won't work if "param_dec" were to contain a comma.)
The third macro, "NON_CONST_IN_TERMS_OF", expands to a definition of a non-
const member function (or member function operator) which calls the const
version. Here it is:
#define NON_CONST_IN_TERMS_OF(ret,func_dec,call) \
ret func_dec \
{ \
return \
const_cast<ret>( \
const_cast<ThisClass const*>(this)-> call \
); \
}
(I realise that this won't work if "func_dec" were to contain a comma.)
First of all I'd like to ask, what do you think of these macros? Has anyone
ever done something similar? You can see them in action now below as I
implement "IntrinsicArray". Before that though, I'm going to implement a
reverse pointer for use as a reverse iterator:
#include <cstddef>
template<class T>
struct ReversePtr {
typedef ReversePtr ThisClass;
typedef std::size_t size_t;
T *p;
ReversePtr(T *const arg) : p(arg) {}
operator T*() { return p; }
operator T const *() const { return p; }
ReversePtr &operator++() { --p; return *this; }
ReversePtr &operator--() { ++p; return *this; }
POST_IN_TERMS_OF(++)
POST_IN_TERMS_OF(--)
ReversePtr &operator+=(size_t const i) { p -= i; return *this; }
ReversePtr &operator-=(size_t const i) { p += i; return *this; }
OP_IN_TERMS_OF(+,size_t const i,i)
OP_IN_TERMS_OF(-,size_t const i,i)
T const &operator[](size_t const i) const { return *(p-i); }
NON_CONST_IN_TERMS_OF(T&,operator[](size_t const i),operator[](i))
};
What do you think of ReversePtr? I appreciate any suggestions.
Now here's IntrinsicArray:
#include <cstddef>
#include <stdexcept>
template<class T,std::size_t len>
struct IntrinsicArray {
typedef IntrinsicArray ThisClass;
T arr[len];
typedef T value_type;
typedef T *iterator;
typedef T const *const_iterator;
typedef T &reference;
typedef T const &const_reference;
typedef std::size_t size_type;
typedef std:trdiff_t difference_type;
T const *begin() const { return arr; }
NON_CONST_IN_TERMS_OF(T*,begin(),begin())
T const *end() const { return arr+len; }
NON_CONST_IN_TERMS_OF(T*,end(),end())
ReversePtr<T const> rbegin() const { return arr+(len-1); }
NON_CONST_IN_TERMS_OF(ReversePtr<T>,rbegin(),rbegin())
ReversePtr<T const> rend() const { return arr-1; }
NON_CONST_IN_TERMS_OF(ReversePtr<T>,rend(),rend())
T const &operator[](size_type const i) const {return arr;}
NON_CONST_IN_TERMS_OF(T&,operator[](size_type const i),operator[](i))
T const &at(size_type const i) const
{
if (i >= len) throw std::range_error();
return arr;
}
NON_CONST_IN_TERMS_OF(T&,at(size_type const i),at(i))
T const &front() const { return *arr; }
NON_CONST_IN_TERMS_OF(T&,front(),front())
T const &back() const { return arr[len-1]; }
NON_CONST_IN_TERMS_OF(T&,back(),back())
size_type size() const { return len; }
bool empty() const { return false; }
size_type capacity() const { return len; }
size_type max_size() const { return len; }
};
Of course, the code isn't finished yet, but I welcome any comments,
questions, or suggestions.
class for an intrinsic array which would behave, to as far an extent as
possible, like a container. Also though, I wanted no overhead whatsoever.
The code I'm about to show below is not finished, it may contain the odd
oversight, bug or error (but at a quick glance it seems OK).
First of all though, I want to show you some macros I've written. The
purpose of the macros is to:
(1) Reduce repetitive typing.
(2) Reduce the possibility for error.
Before you use these macros though, you must a typedef to your class, e.g.:
class SmartPointerOrWhatever {
typedef SmartPointerOrWhatever ThisClass;
};
The first macro, "POST_IN_TERMS_OF", expands to a definition of a post-
operator which invokes the corresponding pre-operator. Here it is:
#define POST_IN_TERMS_OF(op) \
ThisClass operator op(int) \
{ \
ThisClass const temp(*this); \
op *this; \
return temp; \
}
The second macro, "OP_IN_TERMS_OF", expands to a definition of an operator
such as +, which works off +=. Here it is:
#define OP_IN_TERMS_OF(op,param_dec,obj) \
ThisClass operator op(param_dec) const \
{ \
ThisClass temp(*this); \
temp op##= obj; \
return temp; \
}
(I realise that this won't work if "param_dec" were to contain a comma.)
The third macro, "NON_CONST_IN_TERMS_OF", expands to a definition of a non-
const member function (or member function operator) which calls the const
version. Here it is:
#define NON_CONST_IN_TERMS_OF(ret,func_dec,call) \
ret func_dec \
{ \
return \
const_cast<ret>( \
const_cast<ThisClass const*>(this)-> call \
); \
}
(I realise that this won't work if "func_dec" were to contain a comma.)
First of all I'd like to ask, what do you think of these macros? Has anyone
ever done something similar? You can see them in action now below as I
implement "IntrinsicArray". Before that though, I'm going to implement a
reverse pointer for use as a reverse iterator:
#include <cstddef>
template<class T>
struct ReversePtr {
typedef ReversePtr ThisClass;
typedef std::size_t size_t;
T *p;
ReversePtr(T *const arg) : p(arg) {}
operator T*() { return p; }
operator T const *() const { return p; }
ReversePtr &operator++() { --p; return *this; }
ReversePtr &operator--() { ++p; return *this; }
POST_IN_TERMS_OF(++)
POST_IN_TERMS_OF(--)
ReversePtr &operator+=(size_t const i) { p -= i; return *this; }
ReversePtr &operator-=(size_t const i) { p += i; return *this; }
OP_IN_TERMS_OF(+,size_t const i,i)
OP_IN_TERMS_OF(-,size_t const i,i)
T const &operator[](size_t const i) const { return *(p-i); }
NON_CONST_IN_TERMS_OF(T&,operator[](size_t const i),operator[](i))
};
What do you think of ReversePtr? I appreciate any suggestions.
Now here's IntrinsicArray:
#include <cstddef>
#include <stdexcept>
template<class T,std::size_t len>
struct IntrinsicArray {
typedef IntrinsicArray ThisClass;
T arr[len];
typedef T value_type;
typedef T *iterator;
typedef T const *const_iterator;
typedef T &reference;
typedef T const &const_reference;
typedef std::size_t size_type;
typedef std:trdiff_t difference_type;
T const *begin() const { return arr; }
NON_CONST_IN_TERMS_OF(T*,begin(),begin())
T const *end() const { return arr+len; }
NON_CONST_IN_TERMS_OF(T*,end(),end())
ReversePtr<T const> rbegin() const { return arr+(len-1); }
NON_CONST_IN_TERMS_OF(ReversePtr<T>,rbegin(),rbegin())
ReversePtr<T const> rend() const { return arr-1; }
NON_CONST_IN_TERMS_OF(ReversePtr<T>,rend(),rend())
T const &operator[](size_type const i) const {return arr;}
NON_CONST_IN_TERMS_OF(T&,operator[](size_type const i),operator[](i))
T const &at(size_type const i) const
{
if (i >= len) throw std::range_error();
return arr;
}
NON_CONST_IN_TERMS_OF(T&,at(size_type const i),at(i))
T const &front() const { return *arr; }
NON_CONST_IN_TERMS_OF(T&,front(),front())
T const &back() const { return arr[len-1]; }
NON_CONST_IN_TERMS_OF(T&,back(),back())
size_type size() const { return len; }
bool empty() const { return false; }
size_type capacity() const { return len; }
size_type max_size() const { return len; }
};
Of course, the code isn't finished yet, but I welcome any comments,
questions, or suggestions.