Interoperability for Dispatch_output_iterator with variants, documentation and tests

This commit is contained in:
Philipp Möller 2011-07-22 01:22:32 +00:00
parent 203e5e6f02
commit 353241ec7d
3 changed files with 198 additions and 7 deletions

View File

@ -203,8 +203,14 @@
\ccCreationVariable{i}
\ccDefinition The class \ccClassTemplateName\ defines an
\ccc{OutputIterator} that contains a tuple of output iterators, and dispatches
among those based on the type of the value type which is put in it.
\ccc{OutputIterator} that contains a tuple of output iterators, and
dispatches among those based on the type of the value type which is
put in it. Besides defining assignment for all parameters of V it is
also defined for the types \ccStyle{boost::variant<T\ldots>} and
\ccStyle{boost::optional<boost::variant<T\ldots>>}, where T\ldots\
must be a subset of the parameters of \ccc{V}. Should the
\ccStyle{boost::optional} be empty, it will be discarded.
It also inherits from \ccc{O}, which makes it easy to treat like a tuple.
\ccParameters
@ -249,10 +255,17 @@
\ccCreationVariable{i}
\ccDefinition The class \ccClassTemplateName\ defines an
\ccc{OutputIterator} that contains a tuple of output iterators, and dispatches
among those based on the type of the value type which is put in it.
Other types are also accepted, and the object is simply discarded in this case.
It also inherits from \ccc{O}, which makes it easy to treat like a tuple.
\ccc{OutputIterator} that contains a tuple of output iterators, and
dispatches among those based on the type of the value type which is
put in it. Other types are also accepted, and the object is simply
discarded in this case. Besides defining assignment for all
parameters of V it is also defined for the types
\ccStyle{boost::variant<T\ldots>} and
\ccStyle{boost::optional<boost::variant<T\ldots>>}, where T\ldots\
can be a list of arbitrary types.
It also inherits from \ccc{O}, which makes it easy to treat like a
tuple.
\ccParameters
\ccc{V} must be a \ccc{CGAL::cpp0x::tuple<...>} of the types of values to be accepted and dispatched.

View File

@ -31,6 +31,8 @@
#include <map>
#include <boost/type_traits.hpp>
#include <CGAL/tuple.h>
#include <boost/variant.hpp>
#include <boost/optional.hpp>
#if defined(BOOST_MSVC)
# pragma warning(push)
@ -1182,6 +1184,22 @@ inline Filter_output_iterator< I, P >
filter_output_iterator(I e, const P& p)
{ return Filter_output_iterator< I, P >(e, p); }
namespace internal {
template<typename OutputIterator>
struct Output_visitor : boost::static_visitor<OutputIterator&> {
Output_visitor(OutputIterator* it) : out(it) {}
OutputIterator* out;
template<typename T>
OutputIterator& operator()(const T& t) {
*(*out)++ = t;
return *out;
}
};
} // internal
#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
@ -1215,6 +1233,7 @@ struct Derivator<D, cpp0x::tuple<V1, V...>, cpp0x::tuple<O1, O...> >
return static_cast<D&>(*this);
}
};
};
} // internal
@ -1265,6 +1284,20 @@ public:
return *this;
}
template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
Self& operator=(const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T) >& t) {
internal::Output_visitor<Self> visitor(this);
boost::apply_visitor(visitor, t);
return *this;
}
template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
Self& operator=(const boost::optional< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T) > >& t) {
internal::Output_visitor<Self> visitor(this);
if(t) boost::apply_visitor(visitor, *t);
return *this;
}
Self& operator++() { return *this; }
Self& operator++(int) { return *this; }
Self& operator*() { return *this; }
@ -1366,6 +1399,20 @@ public:
return *this;
}
template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
Self& operator=(const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T) >& t) {
internal::Output_visitor<Self> visitor(this);
boost::apply_visitor(visitor, t);
return *this;
}
template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
Self& operator=(const boost::optional< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T) > >& t) {
internal::Output_visitor<Self> visitor(this);
if(t) boost::apply_visitor(visitor, *t);
return *this;
}
const Iterator_tuple& get_iterator_tuple() const
{ return *this; }
@ -1467,6 +1514,20 @@ public:
return *this;
}
template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
Self& operator=(const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T) >& t) {
internal::Output_visitor<Self> visitor(this);
boost::apply_visitor(visitor, t);
return *this;
}
template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
Self& operator=(const boost::optional< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T) > >& t) {
internal::Output_visitor<Self> visitor(this);
if(t) boost::apply_visitor(visitor, *t);
return *this;
}
const Iterator_tuple& get_iterator_tuple() const
{ return *this; }
@ -1578,6 +1639,20 @@ public:
return *this;
}
template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
Self& operator=(const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T) >& t) {
internal::Output_visitor<Self> visitor(this);
boost::apply_visitor(visitor, t);
return *this;
}
template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
Self& operator=(const boost::optional< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T) > >& t) {
internal::Output_visitor<Self> visitor(this);
if(t) boost::apply_visitor(visitor, *t);
return *this;
}
const Iterator_tuple& get_iterator_tuple() const
{ return *this; }
@ -1702,6 +1777,20 @@ public:
return *this;
}
template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
Self& operator=(const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T) >& t) {
internal::Output_visitor<Self> visitor(this);
boost::apply_visitor(visitor, t);
return *this;
}
template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
Self& operator=(const boost::optional< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T) > >& t) {
internal::Output_visitor<Self> visitor(this);
if(t) boost::apply_visitor(visitor, *t);
return *this;
}
const Iterator_tuple& get_iterator_tuple() const
{ return *this; }
@ -1836,6 +1925,21 @@ public:
return *this;
}
template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
Self& operator=(const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T) >& t) {
internal::Output_visitor<Self> visitor(this);
boost::apply_visitor(visitor, t);
return *this;
}
template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
Self& operator=(const boost::optional< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T) > >& t) {
internal::Output_visitor<Self> visitor(this);
if(t) boost::apply_visitor(visitor, *t);
return *this;
}
const Iterator_tuple& get_iterator_tuple() const
{ return *this; }
@ -1980,6 +2084,20 @@ public:
return *this;
}
template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
Self& operator=(const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T) >& t) {
internal::Output_visitor<Self> visitor(this);
boost::apply_visitor(visitor, t);
return *this;
}
template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
Self& operator=(const boost::optional< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T) > >& t) {
internal::Output_visitor<Self> visitor(this);
if(t) boost::apply_visitor(visitor, *t);
return *this;
}
const Iterator_tuple& get_iterator_tuple() const
{ return *this; }
@ -2134,6 +2252,20 @@ public:
return *this;
}
template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
Self& operator=(const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T) >& t) {
internal::Output_visitor<Self> visitor(this);
boost::apply_visitor(visitor, t);
return *this;
}
template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
Self& operator=(const boost::optional< boost::variant<BOOST_VARIANT_ENUM_PARAMS(T) > >& t) {
internal::Output_visitor<Self> visitor(this);
if(t) boost::apply_visitor(visitor, *t);
return *this;
}
const Iterator_tuple& get_iterator_tuple() const
{ return *this; }

View File

@ -6,6 +6,9 @@
#include <CGAL/iterator.h>
#include <boost/variant.hpp>
#include <boost/optional.hpp>
struct A{};
struct B{};
@ -76,6 +79,47 @@ void complete_test(std::vector<T1> data1,std::list<T2> data2){
CGAL::cpp0x::tie(d, bck_ins) = drop;
}
void variant_test() {
typedef boost::variant<int, char, double> var;
typedef boost::optional< var > ovar;
std::vector<int> a;
std::vector<double> b;
std::vector<char> c;
typedef CGAL::Dispatch_output_iterator<
CGAL::cpp0x::tuple<int, double, char>,
CGAL::cpp0x::tuple<std::back_insert_iterator< std::vector<int> >,
std::back_insert_iterator< std::vector<double> >,
std::back_insert_iterator< std::vector<char> >
> > Dispatch;
Dispatch disp = CGAL::dispatch_output<int, double, char>(std::back_inserter(a),
std::back_inserter(b),
std::back_inserter(c));
{
var va = 23; var vb = 4.2; var vc = 'x';
*disp++ = va; *disp++ = vb; *disp++ = vc; *disp++ = 42;
}
assert(a.size() == 2);
assert(a.front() == 23);
assert(a.back() == 42);
assert(b.size() == 1);
assert(b.front() == 4.2);
assert(c.size() == 1);
assert(c.front() == 'x');
a.clear(); b.clear(); c.clear();
{
ovar va = var(23); ovar vb = var(4.2); ovar vc = var('x');
*disp++ = va; *disp++ = vb; *disp++ = vc; *disp++ = 42; *disp++ = ovar();
}
assert(a.size() == 2);
assert(a.front() == 23);
assert(a.back() == 42);
assert(b.size() == 1);
assert(b.front() == 4.2);
assert(c.size() == 1);
assert(c.front() == 'x');
}
int main(){
std::list<int> list1;
@ -93,5 +137,7 @@ int main(){
complete_test(vect2,list1);
complete_test(vect2,list2);
variant_test();
return 0;
}