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} \ccCreationVariable{i}
\ccDefinition The class \ccClassTemplateName\ defines an \ccDefinition The class \ccClassTemplateName\ defines an
\ccc{OutputIterator} that contains a tuple of output iterators, and dispatches \ccc{OutputIterator} that contains a tuple of output iterators, and
among those based on the type of the value type which is put in it. 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. It also inherits from \ccc{O}, which makes it easy to treat like a tuple.
\ccParameters \ccParameters
@ -249,10 +255,17 @@
\ccCreationVariable{i} \ccCreationVariable{i}
\ccDefinition The class \ccClassTemplateName\ defines an \ccDefinition The class \ccClassTemplateName\ defines an
\ccc{OutputIterator} that contains a tuple of output iterators, and dispatches \ccc{OutputIterator} that contains a tuple of output iterators, and
among those based on the type of the value type which is put in it. dispatches among those based on the type of the value type which is
Other types are also accepted, and the object is simply discarded in this case. put in it. Other types are also accepted, and the object is simply
It also inherits from \ccc{O}, which makes it easy to treat like a tuple. 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 \ccParameters
\ccc{V} must be a \ccc{CGAL::cpp0x::tuple<...>} of the types of values to be accepted and dispatched. \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 <map>
#include <boost/type_traits.hpp> #include <boost/type_traits.hpp>
#include <CGAL/tuple.h> #include <CGAL/tuple.h>
#include <boost/variant.hpp>
#include <boost/optional.hpp>
#if defined(BOOST_MSVC) #if defined(BOOST_MSVC)
# pragma warning(push) # pragma warning(push)
@ -1182,6 +1184,22 @@ inline Filter_output_iterator< I, P >
filter_output_iterator(I e, const P& p) filter_output_iterator(I e, const P& p)
{ return Filter_output_iterator< I, P >(e, 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 #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); return static_cast<D&>(*this);
} }
}; };
};
} // internal } // internal
@ -1265,6 +1284,20 @@ public:
return *this; 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++() { return *this; }
Self& operator++(int) { return *this; } Self& operator++(int) { return *this; }
Self& operator*() { return *this; } Self& operator*() { return *this; }
@ -1366,6 +1399,20 @@ public:
return *this; 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 const Iterator_tuple& get_iterator_tuple() const
{ return *this; } { return *this; }
@ -1467,6 +1514,20 @@ public:
return *this; 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 const Iterator_tuple& get_iterator_tuple() const
{ return *this; } { return *this; }
@ -1578,6 +1639,20 @@ public:
return *this; 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 const Iterator_tuple& get_iterator_tuple() const
{ return *this; } { return *this; }
@ -1702,6 +1777,20 @@ public:
return *this; 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 const Iterator_tuple& get_iterator_tuple() const
{ return *this; } { return *this; }
@ -1836,6 +1925,21 @@ public:
return *this; 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 const Iterator_tuple& get_iterator_tuple() const
{ return *this; } { return *this; }
@ -1980,6 +2084,20 @@ public:
return *this; 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 const Iterator_tuple& get_iterator_tuple() const
{ return *this; } { return *this; }
@ -2134,6 +2252,20 @@ public:
return *this; 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 const Iterator_tuple& get_iterator_tuple() const
{ return *this; } { return *this; }

View File

@ -6,6 +6,9 @@
#include <CGAL/iterator.h> #include <CGAL/iterator.h>
#include <boost/variant.hpp>
#include <boost/optional.hpp>
struct A{}; struct A{};
struct B{}; struct B{};
@ -76,6 +79,47 @@ void complete_test(std::vector<T1> data1,std::list<T2> data2){
CGAL::cpp0x::tie(d, bck_ins) = drop; 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(){ int main(){
std::list<int> list1; std::list<int> list1;
@ -93,5 +137,7 @@ int main(){
complete_test(vect2,list1); complete_test(vect2,list1);
complete_test(vect2,list2); complete_test(vect2,list2);
variant_test();
return 0; return 0;
} }