Object: Made implicit conversion from optional<variant> safer

Overload: Added generalised overloads and tests
This commit is contained in:
Philipp Möller 2011-06-23 13:09:49 +00:00
parent b4c1504975
commit d98d1d057f
4 changed files with 96 additions and 3 deletions

2
.gitattributes vendored
View File

@ -3187,7 +3187,9 @@ Ridges_3/examples/Ridges_3/skip_vcproj_auto_generation -text
Ridges_3/test/Ridges_3/data/ellipsoid.off -text svneol=unset#application/octet-stream
Robustness/demo/Robustness/help/index.html svneol=native#text/html
STL_Extension/doc_tex/STL_Extension/plusplus.png -text
STL_Extension/include/CGAL/Overload.h -text
STL_Extension/test/STL_Extension/test_Object.cpp -text
STL_Extension/test/STL_Extension/test_Overload.cpp -text
STL_Extension/test/STL_Extension/test_Uncertain.cpp -text
STL_Extension/test/STL_Extension/test_type_traits.cpp -text
Scripts/developer_scripts/autotest_cgal -text

View File

@ -107,9 +107,9 @@ class Object
}
#endif
// implicit constructor from boost::variant
template<typename T>
Object(const T& t) {
// implicit constructor from optionals containing variants
template<typename Variant>
Object(const boost::optional<Variant>& t) {
// we cannot invoke another ctor from here, so we have to behave
// like the copy ctor of our base
if(t) {

View File

@ -0,0 +1,48 @@
#ifndef _COMPOSITE_VISITOR_H_
#define _COMPOSITE_VISITOR_H_
#include <CGAL/compiler_config.h>
#if !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) && !defined(CGAL_CFG_NO_CPP0X_TUPLE)
#include <tuple>
namespace CGAL {
template<typename T, std::size_t i, class U >
struct overload_helper : public overload_helper<T, i - 1, U> {
typedef typename std::tuple_element<i - 1, T>::type inner_type;
typename inner_type::result_type operator()(typename inner_type::argument_type x) {
return std::get<i - 1>(static_cast<U*>(this)->t)(x); }
using overload_helper<T, i - 1, U>::operator();
};
template<typename T, class U>
struct overload_helper<T, 1, U> {
typedef typename std::tuple_element<0 ,T>::type inner_type;
typename inner_type::result_type operator()(typename inner_type::argument_type x) {
return std::get<0>(static_cast<U*>(this)->t)(x); }
};
template<typename T>
struct overload : public overload_helper<T, std::tuple_size<T>::value, overload<T> >
{
//
typedef typename std::tuple_element<0, T>::type::result_type result_type;
T t;
overload(T&& t) : t(t) {}
overload(const T& t) : t(t) {}
};
template<typename T>
overload<T> make_overload(T&& t) { return overload<T>(t); }
} // namespace CGAL
#endif // !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) && !defined(CGAL_CFG_NO_CPP0X_TUPLE)
#endif /* _COMPOSITE_VISITOR_H_ */

View File

@ -0,0 +1,43 @@
#include <CGAL/compiler_config.h>
#if !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) && !defined(CGAL_CFG_NO_CPP0X_TUPLE)
#include <iostream>
#include <tuple>
#include <functional>
#include <CGAL/Overload.h>
#include <CGAL/assertions.h>
#include <boost/variant.hpp>
void test_overload() {
using namespace CGAL;
using std::function;
// basic overload checking
auto o = make_overload(std::make_tuple(
function<int(int)>([](int) { return 1; }),
function<int(char)>([](char) { return 2; }),
function<int(double)>([](double) { return 3; })));
CGAL_assertion(o(1) == 1);
CGAL_assertion(o('a') == 2);
CGAL_assertion(o(2.0) == 3);
// check for variants
boost::variant<int, char, double> v1 = 1;
boost::variant<int, char, double> v2 = 'a';
boost::variant<int, char, double> v3 = 2.0;
CGAL_assertion(boost::apply_visitor(o, v1) == 1);
CGAL_assertion(boost::apply_visitor(o, v2) == 2);
CGAL_assertion(boost::apply_visitor(o, v3) == 3);
}
#endif
int main() {
#if !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) && !defined(CGAL_CFG_NO_CPP0X_TUPLE)
test_overload();
#endif
}