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}
|
\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.
|
||||||
|
|
|
||||||
|
|
@ -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; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue