Topic: typed_index_wrapper
Author: derek@antiquark.com
Date: Thu, 14 Sep 2006 16:34:46 CST Raw View
Dave Harris wrote:
> Ideally there would only be one wrapper, not a set of them. As with
> std::stack.
Here's an attempt at a wrapper. I think that to be done properly,
various wrappers would be needed for the various containers, mainly due
to difference in constructors.
The wrapper class takes two parameters: the container type, and the
indexing type.
EG, typed_index_wrapper < vector<int>, EFoo > myvec.
The code below shows how this adapter can be used for std::vector,
std::deque and boost::array. The boost::array causes a compiler error
for aggregate initialization though.
Other containers, such as bitset, valarray, stack and string, are
problematic for reasons mentioned near the bottom.
Derek
=====
#include <iostream>
#include <vector>
#include <deque>
#include <string>
#include <deque>
#include <boost/array.hpp>
template<typename Container, typename IndexType>
class typed_index_wrapper : public Container
{
public:
typedef typename Container::reference reference;
typedef typename Container::const_reference const_reference;
typedef IndexType index_type;
typedef typename Container::size_type size_type;
typedef typename Container::value_type value_type;
typedef Container base_type;
reference operator[](const index_type& index)
{
return Container::operator[](size_type(index));
}
const_reference operator[](const index_type& index) const
{
return Container::operator[](size_type(index));
}
reference at(const index_type& index)
{
return Container::at(size_type(index));
}
const_reference at(const index_type& index) const
{
return Container::at(size_type(index));
}
typed_index_wrapper()
:Container()
{}
typed_index_wrapper(size_t n)
:Container(n)
{}
typed_index_wrapper(size_t n, value_type v)
:Container(n, v)
{}
template<class InIt>
typed_index_wrapper(InIt _begin, InIt _end)
:Container(_begin, _end)
{}
};
enum EFoo { a = 0, b, c };
enum EBar { x = 0, y, z };
#define PRINT(a) std::cout << #a << ": " << (a) << std::endl
int main()
{
std::string s("hello");
// The following containers are demonstrated below:
// std::vector
// boost::array
// std::deque
typed_index_wrapper < std::vector<int>, EFoo > v1(11);
typed_index_wrapper < std::vector<int>, EFoo > v2(22, 33);
typed_index_wrapper < std::vector<int>, EFoo > v3(v1);
typed_index_wrapper < std::vector<int>, EFoo > v4(s.begin(), s.end());
PRINT(v1.size());
PRINT(v2.size());
PRINT(v3.size());
std::cout << std::endl;
PRINT(v1.at(a));
PRINT(v2[a]);
PRINT(v3[a]);
PRINT(v4.at(a));
std::cout << std::endl;
PRINT( v1 == v2 );
PRINT( v1 == v3 );
v1 = v4;
std::cout << std::endl;
typed_index_wrapper< boost::array<int, 25>, EBar > a1;
// a1[0] = 111; // compiler error
// a1[a] = 111; // compiler error
a1[x] = 111;
a1.at(x) = 111;
PRINT(a1.size());
PRINT(a1.at(EBar(0)));
PRINT(a1.at(x));
// Aggregate initialize won't work for boost::array. Message is
// error: `a2' must be initialized by constructor, not by `{...}
//typed_index_wrapper< boost::array<int, 25>, EFoo > a2 =
{444,555,666};
typed_index_wrapper< std::deque<int>, unsigned char> d1(1000, 0);
d1.clear();
for(int i = 0 ; i < 1000 ; i ++ )d1.push_back(i);
PRINT(d1.at(257)); // index will roll over because it's uchar, should
print '1'
// std::bitset will cause problems due to different ctors, and member
functions
// returning a bitset<Bits>.
//
// std::valarray will cause problems due to different ctors, and
indexing functions
// that take a slice or gslice.
//
// std::stack doesn't provide indexed access functions.
//
// std::string has different ctors, and just doesn't seem applicable
to typed indexing.
}
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]