|
Boost : |
Subject: Re: [boost] Formal Review Request: TypeErasure
From: Thomas Petit (thomas.petit33_at_[hidden])
Date: 2012-05-30 09:06:30
2012/5/30 Steven Watanabe <watanabesj_at_[hidden]>
>
> template<class T = _self>
> struct printable {
> static void apply(const T& t,
> std::ostream& os,
> const std::vector<int>& v)
> { t.print(os, v); }
> };
>
> namespace boost { namespace type_erasure {
> template<class T, class Base>
> struct concept_interface< ::printable<T>, Base, T> : Base
> {
> void print(std::ostream& os, const std::vector<int>& v) const
> {
> call(printable<T>(), *this, os, v);
> }
> };
> }}
>
> The two differences in usage are that you have
> to use printable<> and printer.print(std::cout, test).
>
>
>
Amazing !!
That's a lot less code that I would have imagine. It maybe even could be
generate with some macro ?
Just a note, with MSVC11 beta I also had to add the concept
copy_constructible<> to be
able to put my any<mpl::vector<printable<>, copy_constructible<>>> in a
std::vector.
If others are interested, here is the complete, working code :
-------------------------------------
#include <iostream>
#include <vector>
#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/iterator.hpp>
#include <boost/type_erasure/operators.hpp>
#include <boost/type_erasure/tuple.hpp>
#include <boost/type_erasure/same_type.hpp>
#include <boost/mpl/vector.hpp>
namespace mpl = boost::mpl;
using namespace boost::type_erasure;
template<class T = _self>
struct printable {
static void apply(const T& t, std::ostream& os, const std::vector<int>& v)
{
t.print(os, v); }
};
namespace boost {
namespace type_erasure {
template<class T, class Base>
struct concept_interface< ::printable<T>, Base, T> : Base
{
void print(std::ostream& os, const std::vector<int>& v) const
{
call(printable<T>(), *this, os, v);
}
};
}}
class abstract_printer {
public:
void print(std::ostream& os, const std::vector<int>& v) const {
do_print(os, v);
}
virtual ~abstract_printer()
{
std::cout << "~abstract_printer()" << std::endl;
}
protected:
virtual void do_print(std::ostream& os, const std::vector<int>&
elements) const = 0;
};
class separator_printer : public abstract_printer {
public:
explicit separator_printer(const std::string& sep) : separator(sep) {}
protected:
virtual void do_print(std::ostream& os, const std::vector<int>& v)
const {
for(int i : v){
os << separator.c_str() << i;
}
}
private:
std::string separator;
};
class column_separator_printer : public abstract_printer {
public:
column_separator_printer(const std::string& sep, std::size_t
num_columns)
: separator(sep),
cols(num_columns)
{}
protected:
virtual void do_print(std::ostream& os, const std::vector<int>& v)
const {
std::size_t count = 0;
for(int i : v){
os << i;
int temp = i;
++temp;
os << separator.c_str();
if(++count % cols == 0) {
os << "\n";
}
}
}
private:
std::string separator;
std::size_t cols;
};
void print()
{
int test[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::vector<int> vtest(test, test + 10);
typedef any<mpl::vector<printable<>, copy_constructible<>>>
polyprintable;
std::vector<polyprintable> printers;
printers.push_back(polyprintable(separator_printer(",")));
printers.push_back(polyprintable(column_separator_printer(",", 4)));
for(polyprintable& printer : printers)
{
printer.print(std::cout, vtest);
std::cout << std::endl;
}
}
int main()
{
print();
}
-----------------------------------
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk