From 659d2295d017ffbd534eaef925166b532a78ebd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20M=C3=B6ller?= Date: Tue, 13 Dec 2011 15:13:07 +0000 Subject: [PATCH] Added tests to verify the types returned by boost::result_of match the real tests and ajusted the type of Construct_vertex_3 for Iso_cuboid_3 --- .gitattributes | 2 + Kernel_23/include/CGAL/Iso_cuboid_3.h | 4 +- .../include/CGAL/Kernel/function_objects.h | 24 +-- Kernel_23/include/CGAL/Point_3.h | 1 - .../include/CGAL/_Result_of_kernel.h | 145 ++++++++++++++++++ Kernel_23/test/Kernel_23/test_result_of.cpp | 40 +++++ 6 files changed, 201 insertions(+), 15 deletions(-) create mode 100644 Kernel_23/test/Kernel_23/include/CGAL/_Result_of_kernel.h create mode 100644 Kernel_23/test/Kernel_23/test_result_of.cpp diff --git a/.gitattributes b/.gitattributes index 3d2ed5d0659..b0fe689894b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1853,7 +1853,9 @@ Kernel_23/examples/Kernel_23/MyPointC2_iostream.h -text Kernel_23/examples/Kernel_23/cartesian_converter.cpp -text Kernel_23/include/CGAL/functions_on_enums.h -text Kernel_23/include/CGAL/internal/Projection_traits_3.h -text +Kernel_23/test/Kernel_23/include/CGAL/_Result_of_kernel.h -text Kernel_23/test/Kernel_23/overload_bug.cpp -text +Kernel_23/test/Kernel_23/test_result_of.cpp -text Kernel_d/doc_tex/Kernel_d/hypercube.png -text Kernel_d/doc_tex/Kernel_d_ref/Kernel_Compute_coordinate_d.tex -text Kernel_d/doc_tex/Kernel_d_ref/Kernel_Less_coordinate_d.tex -text diff --git a/Kernel_23/include/CGAL/Iso_cuboid_3.h b/Kernel_23/include/CGAL/Iso_cuboid_3.h index 5b5c2f74385..56e57b5b8e4 100644 --- a/Kernel_23/include/CGAL/Iso_cuboid_3.h +++ b/Kernel_23/include/CGAL/Iso_cuboid_3.h @@ -102,13 +102,13 @@ public: return R().construct_max_vertex_3_object()(*this); } - typename boost::result_of::type + typename boost::result_of::type vertex(int i) const { return R().construct_vertex_3_object()(*this,i); } - typename boost::result_of::type + typename boost::result_of::type operator[](int i) const { return R().construct_vertex_3_object()(*this,i); diff --git a/Kernel_23/include/CGAL/Kernel/function_objects.h b/Kernel_23/include/CGAL/Kernel/function_objects.h index 51e0040a4aa..730095e96be 100644 --- a/Kernel_23/include/CGAL/Kernel/function_objects.h +++ b/Kernel_23/include/CGAL/Kernel/function_objects.h @@ -1109,13 +1109,13 @@ namespace CommonKernelFunctors { typedef typename K::Segment_3 Segment_3; typedef typename K::Iso_cuboid_3 Iso_cuboid_3; public: - typedef Point_3 result_type; + typedef const Point_3& result_type; - Point_3 + result_type operator()(const Iso_cuboid_3& r) const { return (r.rep().max)(); } - const Point_3& + result_type operator()(const Segment_3& s) const { return (s.rep().max)(); } }; @@ -1127,13 +1127,13 @@ namespace CommonKernelFunctors { typedef typename K::Segment_3 Segment_3; typedef typename K::Iso_cuboid_3 Iso_cuboid_3; public: - typedef Point_3 result_type; + typedef const Point_3& result_type; - Point_3 + result_type operator()(const Iso_cuboid_3& r) const { return (r.rep().min)(); } - const Point_3& + result_type operator()(const Segment_3& s) const { return (s.rep().min)(); } }; @@ -1895,23 +1895,23 @@ namespace CommonKernelFunctors { }; template - struct result { + struct result { typedef Point_3 type; }; - typename result< Construct_vertex_3(Segment_3) >::type + const Point_3& operator()( const Segment_3& s, int i) const { return s.rep().vertex(i); } - typename result< Construct_vertex_3(Triangle_3) >::type + const Point_3& operator()( const Triangle_3& t, int i) const { return t.rep().vertex(i); } - typename result< Construct_vertex_3(Iso_cuboid_3) >::type + Point_3 operator()( const Iso_cuboid_3& r, int i) const - { typename result< Construct_vertex_3(Iso_cuboid_3) >::type asdf; return r.rep().vertex(i); } + { return r.rep().vertex(i); } - typename result< Construct_vertex_3(Tetrahedron_3) >::type + const Point_3& operator()( const Tetrahedron_3& t, int i) const { return t.rep().vertex(i); } }; diff --git a/Kernel_23/include/CGAL/Point_3.h b/Kernel_23/include/CGAL/Point_3.h index 8f838f4c95a..07f71422534 100644 --- a/Kernel_23/include/CGAL/Point_3.h +++ b/Kernel_23/include/CGAL/Point_3.h @@ -31,7 +31,6 @@ #include #include #include -#include #include namespace CGAL { diff --git a/Kernel_23/test/Kernel_23/include/CGAL/_Result_of_kernel.h b/Kernel_23/test/Kernel_23/include/CGAL/_Result_of_kernel.h new file mode 100644 index 00000000000..892fa3f7082 --- /dev/null +++ b/Kernel_23/test/Kernel_23/include/CGAL/_Result_of_kernel.h @@ -0,0 +1,145 @@ +#ifndef CGAL_RESULT_OF_KERNEL_H +#define CGAL_RESULT_OF_KERNEL_H + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +template +struct printer; + +namespace CGAL { + // avoid crashes with what we already have in namespace internal + namespace result_of_kernel { + // required for smooth wrapping of the functors + BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) + BOOST_MPL_HAS_XXX_TRAIT_DEF(Rep) + + template + struct Lazy_is_same { + typedef boost::is_same type; + }; + + // trickery to get rid of the inequality that appears with the + // return_base_tag versions of construct calls + template, + typename + boost::mpl::eval_if< has_Rep, + Lazy_is_same, + boost::false_type >::type + >::value > + struct Rep_equal; + + template + struct Rep_equal : boost::true_type {}; + template + struct Rep_equal : boost::false_type {}; + } + + // This functor can wrap any DefaultConstructible functor. Iff there + // is a result_type typedef it needs to be forwarded. In all other + // cases boost::result_of is necessary to determine the return type. + template::value > + struct AnyFunctor; + + template + struct AnyFunctor { + typedef typename F::result_type result_type; + + template + auto operator()(Args&&... args) const -> typename std::result_of::type { + F f; + // check the equality of a c++03 boost::result_of and a c++11 result_of + typedef typename std::result_of::type c11_return_type; + typedef typename F::result_type c03_return_type; + + static_assert((result_of_kernel::Rep_equal::value), + "Type difference between actual return type and boost::result_of<>::type"); + + return f(std::forward(args)...); + } + }; + + template + struct AnyFunctor { + template + struct result; + + template + struct result { + typedef typename boost::result_of::type type; + }; + + // same as above + template + auto operator()(Args&&... args) const -> typename std::result_of::type { + F f; + typedef typename std::result_of::type c11_return_type; + typedef typename boost::result_of::type + >::type ... + )>::type c03_return_type; + + static_assert((result_of_kernel::Rep_equal::value), + "Type difference between actual return type and boost::result_of<>::type"); + + return f(std::forward(args)...); + } + }; + + template < typename FT_, typename Kernel_ > + struct Result_of_base + : public Cartesian_base< Kernel_, FT_ > + { + typedef FT_ RT; + typedef FT_ FT; + + // The mechanism that allows to specify reference-counting or not. + template < typename T > + struct Handle { typedef T type; }; + + template < typename Kernel2 > + struct Base { typedef Result_of_base Type; }; + + typedef Kernel_ K; + #define CGAL_Kernel_pred(Y,Z) typedef CartesianKernelFunctors::Y Y; \ + Y Z() const { return Y(); } + #define CGAL_Kernel_cons(Y,Z) CGAL_Kernel_pred(Y,Z) + + #include + }; + + template < typename FT_ > + struct Result_of_cartesian + : public Type_equality_wrapper< + Result_of_base >, + Result_of_cartesian > + { + // this has to be delayed until here as AnyFunctor will + // instantiate its arguments and only here lookup for all the + // typedefs inside the functor will be possible + typedef Result_of_cartesian K; + #define CGAL_Kernel_pred(Y,Z) typedef AnyFunctor< CartesianKernelFunctors::Y > Y; \ + Y Z() const { return Y(); } + #define CGAL_Kernel_cons(Y,Z) CGAL_Kernel_pred(Y,Z) + + #include + }; +} + +#endif /* CGAL_RESULT_OF_KERNEL_H */ diff --git a/Kernel_23/test/Kernel_23/test_result_of.cpp b/Kernel_23/test/Kernel_23/test_result_of.cpp new file mode 100644 index 00000000000..8af1027cf7f --- /dev/null +++ b/Kernel_23/test/Kernel_23/test_result_of.cpp @@ -0,0 +1,40 @@ +// Copyright (c) 2011 GeometryFactory (France). All rights reserved. +// All rights reserved. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL distributed with CGAL. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Philipp Moeller + +#include +#include +#include + +#include + + +template +bool test(const K& k) { + return _test_2(k) || _test_3(k); +} + +int main() +{ + typedef CGAL::Result_of_cartesian< double > A; + A a; + + assert( test( a ) ); + return 0; +}