/*============================================================================= Copyright (c) 2011-2017 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_ITERATOR_CAST_HPP #define SPROUT_ITERATOR_CONST_ITERATOR_CAST_HPP #include #include #include #include #include #include namespace sprout { // // is_const_iterator_cast_convertible // template struct is_const_iterator_cast_convertible : public sprout::is_same::type, typename std::remove_cv::type> {}; template struct is_const_iterator_cast_convertible : public sprout::is_const_iterator_cast_convertible {}; template struct is_const_iterator_cast_convertible : public sprout::is_const_iterator_cast_convertible {}; template struct is_const_iterator_cast_convertible : public sprout::is_const_iterator_cast_convertible {}; template struct is_const_iterator_cast_convertible : public sprout::is_const_iterator_cast_convertible {}; template struct is_const_iterator_cast_convertible : public sprout::is_const_iterator_cast_convertible {}; template struct is_const_iterator_cast_convertible : public sprout::is_const_iterator_cast_convertible {}; template struct is_const_iterator_cast_convertible : public sprout::is_const_iterator_cast_convertible {}; template struct is_const_iterator_cast_convertible : public sprout::is_const_iterator_cast_convertible {}; template struct is_const_iterator_cast_convertible : public sprout::is_const_iterator_cast_convertible {}; template struct is_const_iterator_cast_convertible : public sprout::is_const_iterator_cast_convertible {}; template struct is_const_iterator_cast_convertible : public sprout::is_const_iterator_cast_convertible {}; template struct is_const_iterator_cast_convertible : public sprout::is_const_iterator_cast_convertible {}; template struct is_const_iterator_cast_convertible : public sprout::is_const_iterator_cast_convertible {}; template struct is_const_iterator_cast_convertible : public sprout::is_const_iterator_cast_convertible {}; template struct is_const_iterator_cast_convertible : public sprout::is_const_iterator_cast_convertible {}; template struct is_const_iterator_cast_convertible : public sprout::is_same::type, typename std::remove_cv::type> {}; } // namespace sprout namespace sprout_adl { template sprout::not_found_via_adl const_iterator_conversion(...); } // namespace sprout_adl namespace sprout { namespace iterator_detail { template< typename T, typename U, typename sprout::enabler_if::value>::type = sprout::enabler > inline SPROUT_CONSTEXPR T const_iterator_conversion(U* it) { return const_cast(it); } template inline SPROUT_CONSTEXPR T const_iterator_conversion(T const& it) { return it; } } // namespace iterator_detail } // namespace sprout namespace sprout_iterator_detail { template inline SPROUT_CONSTEXPR To 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); } } // namespace sprout_iterator_detail namespace sprout { // // const_iterator_cast // template inline SPROUT_CONSTEXPR To const_iterator_cast(From const& it) { return sprout_iterator_detail::call_const_iterator_conversion(it); } } // namespace sprout // // note: // const_iterator_cast is an adaptable function for interconversion // with iterator and const_iterator. // If you want to adapt a user-defined iterator class to const_iterator_cast: // - Specialize sprout::is_const_iterator_cast_convertible. // - Overload const_iterator_conversion as to be lookup in the ADL. // // example: // #include // #include // #include // #include // /* Mylib::Iterator is an user-defined iterator class*/ // namespace Mylib { // template // struct Iterator { // T* p; // typedef T* pointer; // /* definition iterator interface... */ // }; // } // /* const_iterator_cast adapt for Mylib::Iterator */ // namespace sprout { // template // struct is_const_iterator_cast_convertible< // Mylib::Iterator, // Mylib::Iterator // > // : public sprout::is_same< // typename std::remove_cv::type, // typename std::remove_cv::type // > // {}; // } // namespace Mylib { // template // inline SPROUT_CONSTEXPR typename std::enable_if< // sprout::is_const_iterator_cast_convertible, To>::value, // To // >::type // const_iterator_conversion(Iterator const& it) { // return To{const_cast(it.p)}; // } // } // /* test const_iterator_cast with Mylib::Iterator */ // constexpr Mylib::Iterator it{0}; // static_assert(sprout::const_iterator_cast >(it).p == 0, ""); // #endif // #ifndef SPROUT_ITERATOR_CONST_ITERATOR_CAST_HPP