mirror of https://github.com/CGAL/cgal
Interoperability for Dispatch_output_iterator with variants, documentation and tests
This commit is contained in:
parent
203e5e6f02
commit
353241ec7d
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue