mirror of https://github.com/CGAL/cgal
add a way to extract references from named parameters
This commit is contained in:
parent
e38ab3b19a
commit
aaa3947e40
|
|
@ -66,6 +66,7 @@ template< typename T, typename Tag, typename Query_tag>
|
|||
struct Get_param< Named_params_impl<T, Tag, No_property>, Query_tag >
|
||||
{
|
||||
typedef Param_not_found type;
|
||||
typedef Param_not_found reference;
|
||||
};
|
||||
|
||||
template< typename T, typename Tag, typename Base>
|
||||
|
|
@ -73,6 +74,8 @@ struct Get_param< Named_params_impl<T, Tag, Base>, Tag >
|
|||
{
|
||||
typedef typename std::conditional<std::is_copy_constructible<T>::value,
|
||||
T, std::reference_wrapper<const T> >::type type;
|
||||
typedef typename std::conditional<std::is_copy_constructible<T>::value,
|
||||
T&, const T&>::type reference;
|
||||
};
|
||||
|
||||
template< typename T, typename Tag>
|
||||
|
|
@ -80,6 +83,22 @@ struct Get_param< Named_params_impl<T, Tag, No_property>, Tag >
|
|||
{
|
||||
typedef typename std::conditional<std::is_copy_constructible<T>::value,
|
||||
T, std::reference_wrapper<const T> >::type type;
|
||||
typedef typename std::conditional<std::is_copy_constructible<T>::value,
|
||||
T&, const T&>::type reference;
|
||||
};
|
||||
|
||||
template< typename T, typename Tag, typename Base>
|
||||
struct Get_param< Named_params_impl<std::reference_wrapper<T>, Tag, Base>, Tag >
|
||||
{
|
||||
typedef std::reference_wrapper<T> type;
|
||||
typedef T& reference;
|
||||
};
|
||||
|
||||
template< typename T, typename Tag>
|
||||
struct Get_param< Named_params_impl<std::reference_wrapper<T>, Tag, No_property>, Tag >
|
||||
{
|
||||
typedef std::reference_wrapper<T> type;
|
||||
typedef T& reference;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -87,6 +106,7 @@ template< typename T, typename Tag, typename Base, typename Query_tag>
|
|||
struct Get_param< Named_params_impl<T,Tag,Base>, Query_tag>
|
||||
{
|
||||
typedef typename Get_param<typename Base::base, Query_tag>::type type;
|
||||
typedef typename Get_param<typename Base::base, Query_tag>::reference reference;
|
||||
};
|
||||
|
||||
// helper to choose the default
|
||||
|
|
@ -94,11 +114,17 @@ template <typename Query_tag, typename NP, typename D>
|
|||
struct Lookup_named_param_def
|
||||
{
|
||||
typedef typename internal_np::Get_param<typename NP::base, Query_tag>::type NP_type;
|
||||
typedef typename internal_np::Get_param<typename NP::base, Query_tag>::reference NP_reference;
|
||||
|
||||
typedef typename boost::mpl::if_<
|
||||
boost::is_same<NP_type, internal_np::Param_not_found>,
|
||||
D, NP_type>::type
|
||||
type;
|
||||
|
||||
typedef typename boost::mpl::if_<
|
||||
boost::is_same<NP_reference, internal_np::Param_not_found>,
|
||||
D&, NP_reference>::type
|
||||
reference;
|
||||
};
|
||||
|
||||
// helper function to extract the value from a named parameter pack given a query tag
|
||||
|
|
@ -132,6 +158,68 @@ get_parameter_impl(const Named_params_impl<T, Tag, Base>& np, Query_tag tag)
|
|||
return get_parameter_impl(static_cast<const typename Base::base&>(np), tag);
|
||||
}
|
||||
|
||||
|
||||
// helper for getting references
|
||||
template <class T>
|
||||
T& get_reference(T& t)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T& get_reference(const std::reference_wrapper<T>& r)
|
||||
{
|
||||
return r.get();
|
||||
}
|
||||
|
||||
// helper function to extract the reference from a named parameter pack given a query tag
|
||||
template <typename T, typename Tag, typename Base>
|
||||
typename std::conditional<std::is_copy_constructible<T>::value,
|
||||
T&, const T& >::type
|
||||
get_parameter_reference_impl(Named_params_impl<T, Tag, Base>& np, Tag)
|
||||
{
|
||||
return get_reference(np.v);
|
||||
}
|
||||
|
||||
template< typename T, typename Tag, typename Query_tag>
|
||||
Param_not_found
|
||||
get_parameter_reference_impl(Named_params_impl<T, Tag, No_property>&, Query_tag)
|
||||
{
|
||||
return Param_not_found();
|
||||
}
|
||||
|
||||
template< typename T, typename Tag>
|
||||
typename std::conditional<std::is_copy_constructible<T>::value,
|
||||
T&, const T& >::type
|
||||
get_parameter_reference_impl(Named_params_impl<T, Tag, No_property>& np, Tag)
|
||||
{
|
||||
return get_reference(np.v);
|
||||
};
|
||||
|
||||
template <typename T, typename Tag, typename Base>
|
||||
T&
|
||||
get_parameter_reference_impl(Named_params_impl<std::reference_wrapper<T>, Tag, Base>& np, Tag)
|
||||
{
|
||||
return np.v.get();
|
||||
}
|
||||
|
||||
template< typename T, typename Tag>
|
||||
T&
|
||||
get_parameter_reference_impl(Named_params_impl<std::reference_wrapper<T>, Tag, No_property>& np, Tag)
|
||||
{
|
||||
return np.v.get();
|
||||
};
|
||||
|
||||
|
||||
template <typename T, typename Tag, typename Base, typename Query_tag>
|
||||
typename Get_param<Named_params_impl<T, Tag, Base>, Query_tag>::type
|
||||
get_parameter_reference_impl(Named_params_impl<T, Tag, Base>& np, Query_tag tag)
|
||||
{
|
||||
CGAL_static_assertion( (!boost::is_same<Query_tag, Tag>::value) );
|
||||
return get_parameter_reference_impl(static_cast<typename Base::base&>(np), tag);
|
||||
}
|
||||
|
||||
|
||||
} // end of internal_np namespace
|
||||
|
||||
|
||||
|
|
@ -204,15 +292,24 @@ get_parameter(const Named_function_parameters<T, Tag, Base>& np, Query_tag tag)
|
|||
return internal_np::get_parameter_impl(static_cast<const internal_np::Named_params_impl<T, Tag, Base>&>(np), tag);
|
||||
}
|
||||
|
||||
template <typename T, typename Tag, typename Base, typename Query_tag>
|
||||
typename internal_np::Get_param<internal_np::Named_params_impl<T, Tag, Base>, Query_tag>::reference
|
||||
get_parameter_reference(const Named_function_parameters<T, Tag, Base>& np, Query_tag tag)
|
||||
{
|
||||
return internal_np::get_parameter_reference_impl(
|
||||
static_cast<internal_np::Named_params_impl<T, Tag, Base>&>(const_cast<Named_function_parameters<T, Tag, Base>&>(np)),
|
||||
tag);
|
||||
}
|
||||
|
||||
// Two parameters, non-trivial default value
|
||||
template <typename D>
|
||||
D choose_parameter(const internal_np::Param_not_found&, const D& d)
|
||||
D& choose_parameter(const internal_np::Param_not_found&, D& d)
|
||||
{
|
||||
return d;
|
||||
}
|
||||
|
||||
template <typename T, typename D>
|
||||
const T& choose_parameter(const T& t, const D&)
|
||||
T& choose_parameter(T& t, D&)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@
|
|||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace inp = CGAL::internal_np;
|
||||
namespace params = CGAL::parameters;
|
||||
|
||||
template <int i>
|
||||
struct A
|
||||
{
|
||||
|
|
@ -28,29 +31,58 @@ void check_same_type(T)
|
|||
template<class NamedParameters>
|
||||
void test_values_and_types(const NamedParameters& np)
|
||||
{
|
||||
using CGAL::parameters::get_parameter;
|
||||
using params::get_parameter;
|
||||
|
||||
// test values
|
||||
assert(get_parameter(np, CGAL::internal_np::vertex_index).v == 0);
|
||||
assert(get_parameter(np, CGAL::internal_np::visitor).v == 1);
|
||||
assert(get_parameter(np, inp::vertex_index).v == 0);
|
||||
assert(get_parameter(np, inp::visitor).v == 1);
|
||||
|
||||
// test types
|
||||
check_same_type<0>(get_parameter(np, CGAL::internal_np::vertex_index));
|
||||
check_same_type<1>(get_parameter(np, CGAL::internal_np::visitor));
|
||||
check_same_type<0>(get_parameter(np, inp::vertex_index));
|
||||
check_same_type<1>(get_parameter(np, inp::visitor));
|
||||
}
|
||||
|
||||
template<class NamedParameters>
|
||||
void test_no_copyable(const NamedParameters&)
|
||||
{
|
||||
typedef typename CGAL::internal_np::Get_param<typename NamedParameters::base,CGAL::internal_np::visitor_t>::type NP_type;
|
||||
typedef typename inp::Get_param<typename NamedParameters::base,inp::visitor_t>::type NP_type;
|
||||
static_assert( boost::is_same<NP_type,std::reference_wrapper<const B> > ::value );
|
||||
}
|
||||
|
||||
template <class NamedParameters>
|
||||
void test_references(const NamedParameters& np)
|
||||
{
|
||||
typedef A<2> Default_type;
|
||||
Default_type default_value(2);
|
||||
|
||||
// std::reference_wrapper
|
||||
typedef typename inp::Lookup_named_param_def<inp::visitor_t, NamedParameters, Default_type>::reference Visitor_reference_type;
|
||||
static_assert(std::is_same<B&, Visitor_reference_type>::value);
|
||||
Visitor_reference_type vis_ref = params::choose_parameter(params::get_parameter_reference(np, inp::visitor), default_value);
|
||||
CGAL_USE(vis_ref);
|
||||
|
||||
// non-copyable
|
||||
typedef typename inp::Lookup_named_param_def<inp::vertex_point_t, NamedParameters, Default_type>::reference VPM_reference_type;
|
||||
static_assert(std::is_same<const B&, VPM_reference_type>::value);
|
||||
VPM_reference_type vpm_ref = params::choose_parameter(params::get_parameter_reference(np, inp::vertex_point), default_value);
|
||||
CGAL_USE(vpm_ref);
|
||||
|
||||
// passed by copy
|
||||
typedef typename inp::Lookup_named_param_def<inp::vertex_index_t, NamedParameters, Default_type>::reference VIM_reference_type;
|
||||
static_assert(std::is_same<A<0>&, VIM_reference_type>::value);
|
||||
VIM_reference_type vim_ref = params::choose_parameter(params::get_parameter_reference(np, inp::vertex_index), default_value);
|
||||
CGAL_USE(vim_ref);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_values_and_types(CGAL::parameters::vertex_index_map(A<0>(0)).visitor(A<1>(1)));
|
||||
test_values_and_types(params::vertex_index_map(A<0>(0)).visitor(A<1>(1)));
|
||||
|
||||
B b;
|
||||
test_no_copyable(CGAL::parameters::visitor(b));
|
||||
test_no_copyable(params::visitor(b));
|
||||
|
||||
test_references(params::visitor(std::ref(b))
|
||||
.vertex_point_map(b)
|
||||
.vertex_index_map(A<0>(0)));
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue