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                      ]