diff --git a/sprout/container/at.hpp b/sprout/container/at.hpp index 951affcc..01983027 100644 --- a/sprout/container/at.hpp +++ b/sprout/container/at.hpp @@ -24,13 +24,13 @@ namespace sprout { // [default] // Container is T[N] -> cont[sprout::range_index_check(cont, i)] // otherwise, Container is not const - // && sprout::is_const_cast_convertible + // && sprout::is_const_reference_cast_convertible // && (callable sprout::as_const(cont).at(i) // || callable sprout::as_const(cont)[i] // || callable sprout::as_const(cont).begin() // || ADL(without sprout) callable begin(sprout::as_const(cont)) // ) - // -> const_cast(sprout::at(sprout::as_const(cont), i)) + // -> sprout::const_reference_cast(sprout::at(sprout::as_const(cont), i)) // otherwise, callable cont.at(i) -> cont.at(i) // otherwise, callable cont[i] -> cont[sprout::range_index_check(cont, i)] // otherwise -> *sprout::next(sprout::begin(cont), sprout::range_index_check(cont, i)) diff --git a/sprout/container/back.hpp b/sprout/container/back.hpp index 30fb9ab4..37c38ae2 100644 --- a/sprout/container/back.hpp +++ b/sprout/container/back.hpp @@ -24,12 +24,12 @@ namespace sprout { // [default] // Container is T[N] -> cont[N - 1] // otherwise, Container is not const - // && sprout::is_const_cast_convertible + // && sprout::is_const_reference_cast_convertible // && (callable sprout::as_const(cont).back() // || callable sprout::as_const(cont).begin() // || ADL(without sprout) callable begin(sprout::as_const(cont)) // ) - // -> const_cast(sprout::back(sprout::as_const(cont))) + // -> sprout::const_reference_cast(sprout::back(sprout::as_const(cont))) // otherwise, callable cont.back() -> cont.back() // otherwise -> *sprout::next(sprout::begin(cont), sprout::size(cont) - 1) // diff --git a/sprout/container/detail/range_at.hpp b/sprout/container/detail/range_at.hpp index 402ae5c3..c64be1d1 100644 --- a/sprout/container/detail/range_at.hpp +++ b/sprout/container/detail/range_at.hpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -54,7 +53,7 @@ namespace sprout { template struct is_substitutable_const_at : public sprout::bool_constant< - sprout::is_const_cast_convertible< + sprout::is_const_reference_cast_convertible< typename sprout::container_traits::reference, typename sprout::container_traits::reference >::value @@ -74,7 +73,7 @@ namespace sprout { >::type range_at_impl(Container& cont, typename sprout::container_traits::size_type i) { typedef typename sprout::container_traits::reference type; - return const_cast(sprout::at(sprout::as_const(cont), i)); + return sprout::const_reference_cast(sprout::at(sprout::as_const(cont), i)); } template inline SPROUT_CONSTEXPR typename std::enable_if< diff --git a/sprout/container/detail/range_back.hpp b/sprout/container/detail/range_back.hpp index 26df30ad..819c452a 100644 --- a/sprout/container/detail/range_back.hpp +++ b/sprout/container/detail/range_back.hpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -53,7 +52,7 @@ namespace sprout { template struct is_substitutable_const_back : public sprout::bool_constant< - sprout::is_const_cast_convertible< + sprout::is_const_reference_cast_convertible< typename sprout::container_traits::reference, typename sprout::container_traits::reference >::value @@ -72,7 +71,7 @@ namespace sprout { >::type range_back_impl(Container& cont) { typedef typename sprout::container_traits::reference type; - return const_cast(sprout::back(sprout::as_const(cont))); + return sprout::const_reference_cast(sprout::back(sprout::as_const(cont))); } template inline SPROUT_CONSTEXPR typename std::enable_if< diff --git a/sprout/container/detail/range_front.hpp b/sprout/container/detail/range_front.hpp index e3c05848..c2b28ecd 100644 --- a/sprout/container/detail/range_front.hpp +++ b/sprout/container/detail/range_front.hpp @@ -13,11 +13,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include @@ -52,7 +52,7 @@ namespace sprout { template struct is_substitutable_const_front : public sprout::bool_constant< - sprout::is_const_cast_convertible< + sprout::is_const_reference_cast_convertible< typename sprout::container_traits::reference, typename sprout::container_traits::reference >::value @@ -71,7 +71,7 @@ namespace sprout { >::type range_front_impl(Container& cont) { typedef typename sprout::container_traits::reference type; - return const_cast(sprout::front(sprout::as_const(cont))); + return sprout::const_reference_cast(sprout::front(sprout::as_const(cont))); } template inline SPROUT_CONSTEXPR typename std::enable_if< diff --git a/sprout/container/detail/range_subscript_at.hpp b/sprout/container/detail/range_subscript_at.hpp index 3ccc2001..0f2fd48e 100644 --- a/sprout/container/detail/range_subscript_at.hpp +++ b/sprout/container/detail/range_subscript_at.hpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -53,7 +52,7 @@ namespace sprout { template struct is_substitutable_const_subscript_at : public sprout::bool_constant< - sprout::is_const_cast_convertible< + sprout::is_const_reference_cast_convertible< typename sprout::container_traits::reference, typename sprout::container_traits::reference >::value @@ -72,7 +71,7 @@ namespace sprout { >::type range_subscript_at_impl(Container& cont, typename sprout::container_traits::size_type i) { typedef typename sprout::container_traits::reference type; - return const_cast(sprout::subscript_at(sprout::as_const(cont), i)); + return sprout::const_reference_cast(sprout::subscript_at(sprout::as_const(cont), i)); } template inline SPROUT_CONSTEXPR typename std::enable_if< diff --git a/sprout/container/front.hpp b/sprout/container/front.hpp index aba44046..aa7bebc1 100644 --- a/sprout/container/front.hpp +++ b/sprout/container/front.hpp @@ -24,12 +24,12 @@ namespace sprout { // [default] // Container is T[N] -> cont[0] // otherwise, Container is not const - // && sprout::is_const_cast_convertible + // && sprout::is_const_reference_cast_convertible // && (callable sprout::as_const(cont).front() // || callable sprout::as_const(cont).begin() // || ADL(without sprout) callable begin(sprout::as_const(cont)) // ) - // -> const_cast(sprout::front(sprout::as_const(cont))) + // -> sprout::const_reference_cast(sprout::front(sprout::as_const(cont))) // otherwise, callable cont.front() -> cont.front() // otherwise -> *sprout::begin(cont) // diff --git a/sprout/container/subscript_at.hpp b/sprout/container/subscript_at.hpp index 4a35d9eb..7b63e362 100644 --- a/sprout/container/subscript_at.hpp +++ b/sprout/container/subscript_at.hpp @@ -24,12 +24,12 @@ namespace sprout { // [default] // Container is T[N] -> cont[i] // otherwise, Container is not const - // && sprout::is_const_cast_convertible + // && sprout::is_const_reference_cast_convertible // && (callable sprout::as_const(cont)[i] // || callable sprout::as_const(cont).begin() // || ADL(without sprout) callable begin(sprout::as_const(cont)) // ) - // -> const_cast(sprout::subscript_at(sprout::as_const(cont), i)) + // -> sprout::const_reference_cast(sprout::subscript_at(sprout::as_const(cont), i)) // otherwise, callable cont[i] -> cont[i] // otherwise -> *sprout::next(sprout::begin(cont), i) // diff --git a/sprout/iterator/const_iterator_cast.hpp b/sprout/iterator/const_iterator_cast.hpp index 966738d2..e988dd65 100644 --- a/sprout/iterator/const_iterator_cast.hpp +++ b/sprout/iterator/const_iterator_cast.hpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include @@ -86,7 +85,7 @@ namespace sprout { {}; template struct is_const_iterator_cast_convertible - : public std::is_same::type, typename std::remove_const::type> + : public sprout::is_same::type, typename std::remove_const::type> {}; } // namespace sprout @@ -98,8 +97,7 @@ namespace sprout_adl { namespace sprout { namespace iterator_detail { template< - typename T, - typename U, + typename T, typename U, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR T @@ -117,7 +115,7 @@ namespace sprout { namespace sprout_iterator_detail { template inline SPROUT_CONSTEXPR To - const_iterator_cast(From const& it) { + call_const_iterator_conversion(From const& it) { using sprout::iterator_detail::const_iterator_conversion; using sprout_adl::const_iterator_conversion; return const_iterator_conversion(it); @@ -131,7 +129,7 @@ namespace sprout { template inline SPROUT_CONSTEXPR To const_iterator_cast(From const& it) { - return sprout_iterator_detail::const_iterator_cast(it); + return sprout_iterator_detail::call_const_iterator_conversion(it); } } // namespace sprout diff --git a/sprout/iterator/const_reference_cast.hpp b/sprout/iterator/const_reference_cast.hpp new file mode 100644 index 00000000..fc7d3eca --- /dev/null +++ b/sprout/iterator/const_reference_cast.hpp @@ -0,0 +1,192 @@ +/*============================================================================= + Copyright (c) 2011-2016 Bolero MURAKAMI + https://github.com/bolero-MURAKAMI/Sprout + + Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +=============================================================================*/ +#ifndef SPROUT_ITERATOR_CONST_REFERENCE_CAST_HPP +#define SPROUT_ITERATOR_CONST_REFERENCE_CAST_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // is_const_reference_cast_convertible + // + template + struct is_const_reference_cast_convertible + : public sprout::bool_constant< + sprout::is_const_cast_convertible::value + || std::is_same::type, typename std::remove_cv::type>::value + > + {}; + template + struct is_const_reference_cast_convertible + : public sprout::is_const_reference_cast_convertible + {}; + template + struct is_const_reference_cast_convertible + : public sprout::is_const_reference_cast_convertible + {}; + template + struct is_const_reference_cast_convertible + : public sprout::is_const_reference_cast_convertible + {}; + template + struct is_const_reference_cast_convertible + : public sprout::is_const_reference_cast_convertible + {}; + template + struct is_const_reference_cast_convertible + : public sprout::is_const_reference_cast_convertible + {}; + template + struct is_const_reference_cast_convertible + : public sprout::is_const_reference_cast_convertible + {}; + template + struct is_const_reference_cast_convertible + : public sprout::is_const_reference_cast_convertible + {}; + template + struct is_const_reference_cast_convertible + : public sprout::is_const_reference_cast_convertible + {}; + template + struct is_const_reference_cast_convertible + : public sprout::is_const_reference_cast_convertible + {}; + template + struct is_const_reference_cast_convertible + : public sprout::is_const_reference_cast_convertible + {}; + template + struct is_const_reference_cast_convertible + : public sprout::is_const_reference_cast_convertible + {}; + template + struct is_const_reference_cast_convertible + : public sprout::is_const_reference_cast_convertible + {}; + template + struct is_const_reference_cast_convertible + : public sprout::is_const_reference_cast_convertible + {}; + template + struct is_const_reference_cast_convertible + : public sprout::is_const_reference_cast_convertible + {}; + template + struct is_const_reference_cast_convertible + : public sprout::is_const_reference_cast_convertible + {}; +} // namespace sprout + +namespace sprout_adl { + template + sprout::not_found_via_adl const_reference_conversion(...); +} // namespace sprout_adl + +namespace sprout { + namespace iterator_detail { + template< + typename T, typename U, + typename sprout::enabler_if< + sprout::is_const_reference_cast_convertible::value + && std::is_reference::value + >::type = sprout::enabler + > + inline SPROUT_CONSTEXPR T + const_reference_conversion(U& t) { + return const_cast(t); + } + template< + typename T, typename U, + typename sprout::enabler_if< + sprout::is_const_reference_cast_convertible::value + && std::is_reference::value + >::type = sprout::enabler + > + inline SPROUT_CONSTEXPR T + const_reference_conversion(U const& t) { + return const_cast(t); + } + + template< + typename T, typename U, + typename sprout::enabler_if< + sprout::is_const_reference_cast_convertible::value + && std::is_pointer::value + >::type = sprout::enabler + > + inline SPROUT_CONSTEXPR T + const_reference_conversion(U& t) { + return const_cast(t); + } + template< + typename T, typename U, + typename sprout::enabler_if< + sprout::is_const_reference_cast_convertible::value + && std::is_pointer::value + >::type = sprout::enabler + > + inline SPROUT_CONSTEXPR T + const_reference_conversion(U const& t) { + return const_cast(t); + } + + template< + typename T, typename U, + typename sprout::enabler_if< + sprout::is_const_reference_cast_convertible::value + && !std::is_reference::value && !std::is_pointer::value + >::type = sprout::enabler + > + inline SPROUT_CONSTEXPR T + const_reference_conversion(U& t) { + return static_cast(t); + } + template< + typename T, typename U, + typename sprout::enabler_if< + sprout::is_const_reference_cast_convertible::value + && !std::is_reference::value && !std::is_pointer::value + >::type = sprout::enabler + > + inline SPROUT_CONSTEXPR T + const_reference_conversion(U const& t) { + return static_cast(t); + } + } // namespace iterator_detail +} // namespace sprout + +namespace sprout_iterator_detail { + template + inline SPROUT_CONSTEXPR To + call_const_reference_conversion(From&& t) { + using sprout::iterator_detail::const_reference_conversion; + using sprout_adl::const_reference_conversion; + return const_reference_conversion(SPROUT_FORWARD(From, t)); + } +} // namespace sprout_iterator_detail + +namespace sprout { + // + // const_reference_cast + // + template + inline SPROUT_CONSTEXPR To + const_reference_cast(From&& t) { + return sprout_iterator_detail::call_const_reference_conversion(SPROUT_FORWARD(From, t)); + } +} // namespace sprout + +#endif // #ifndef SPROUT_ITERATOR_CONST_REFERENCE_CAST_HPP diff --git a/sprout/iterator/operation.hpp b/sprout/iterator/operation.hpp index d0cf8e68..fd4d21c4 100644 --- a/sprout/iterator/operation.hpp +++ b/sprout/iterator/operation.hpp @@ -13,5 +13,7 @@ #include #include #include +#include +#include #endif // #ifndef SPROUT_ITERATOR_OPERATION_HPP