|
Boost : |
From: Matthew Vogt (mvogt_at_[hidden])
Date: 2004-04-23 00:11:06
Like the following:
I guess it depends on how much you're willing to pay for syntactic sugar...
//-----------------------------------------------------------------------------
#include <iostream>
#include <vector>
#include <deque>
#include <list>
#include <utility>
#include "each.hpp"
template<typename T1, typename T2>
std::ostream& operator<< (std::ostream& os, const std::pair<T1, T2>& p)
{
return os << "{" << p.first << "," << p.second << "}";
}
int main(int, char**)
{
std::vector<int> int_vector;
int_vector.push_back(5);
int_vector.push_back(10);
for (each<int> in(int_vector); in; ++in)
std::cout << *in << std::endl;
std::deque<double> double_deque;
double_deque.push_back(3.14);
double_deque.push_front(99.999);
for (each<double> in(double_deque); in; ++in)
std::cout << *in << std::endl;
std::list<std::pair<unsigned, char> > pair_list;
pair_list.push_back(std::make_pair(10, 'a'+13));
pair_list.push_back(std::make_pair(11, 'a'+14));
for (each<std::pair<unsigned, char> > in(pair_list); in; ++in)
std::cout << *in << std::endl;
std::list<int> int_list(3);
for (each<int> in(int_list); in; ++in)
*in = 5;
for (each<const int> in(int_list); in; ++in)
std::cout << *in << std::endl;
return 0;
}
//-- each.hpp -----------------------------------------------------------------
#include <boost/function.hpp>
#include <boost/bind.hpp>
template<typename T>
struct each
{
typedef T value_type;
template<typename ContainerType>
each(ContainerType& c) : iter(c.begin(), c.end()) {}
operator bool(void) const { return iter.at_end() == false; }
void operator++(void) { iter.increment(); }
value_type& operator*(void) const { return iter.dereference(); }
private:
struct iterator_wrapper
{
struct iterator_storage
{
// Allocate a memory buffer sized to hold a real iterator, and copy it
template<typename BaseIteratorType>
iterator_storage(const BaseIteratorType& t) :
address(operator new(sizeof t))
{
BaseIteratorType* typed_address =
reinterpret_cast<BaseIteratorType*>(address);
*typed_address = t;
}
~iterator_storage() { operator delete(address); }
void* address;
};
template<typename IteratorType>
iterator_wrapper(IteratorType begin, IteratorType end) :
current_storage(begin),
end_storage(end)
{
// Make bound references to the operations we need, on the iterator copy
IteratorType* saved_begin =
reinterpret_cast<IteratorType*>(current_storage.address);
increment = boost::bind(&IteratorType::operator++, saved_begin);
dereference = boost::bind(&IteratorType::operator*, saved_begin);
IteratorType* saved_end =
reinterpret_cast<IteratorType*>(end_storage.address);
at_end = boost::bind(&iterator_wrapper::is_equal<IteratorType>,
saved_begin,
saved_end);
}
template<typename IteratorType>
static bool is_equal(const IteratorType* first, const IteratorType* second)
{
return (*first == *second);
}
boost::function<void (void)> increment;
boost::function<value_type& (void)> dereference;
boost::function<bool (void)> at_end;
iterator_storage current_storage;
iterator_storage end_storage;
};
iterator_wrapper iter;
};
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk