From a6d46d4ffa4088a0b527a212a3ecdff605467812 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Fri, 15 Apr 2016 01:47:14 +0900 Subject: [PATCH] change begin, end traits --- sprout/container/begin.hpp | 4 +- sprout/container/container_range_traits.hpp | 269 +++++++++++++++++- sprout/container/end.hpp | 6 +- sprout/type_traits.hpp | 1 + sprout/type_traits/is_within_namespace.hpp | 15 + .../type_traits/is_within_namespace_boost.hpp | 60 ++++ .../is_within_namespace_sprout.hpp | 60 ++++ sprout/utility/as_non_const.hpp | 34 +++ sprout/utility/cast.hpp | 1 + 9 files changed, 445 insertions(+), 5 deletions(-) create mode 100644 sprout/type_traits/is_within_namespace.hpp create mode 100644 sprout/type_traits/is_within_namespace_boost.hpp create mode 100644 sprout/type_traits/is_within_namespace_sprout.hpp create mode 100644 sprout/utility/as_non_const.hpp diff --git a/sprout/container/begin.hpp b/sprout/container/begin.hpp index c33c792c..66d9083b 100644 --- a/sprout/container/begin.hpp +++ b/sprout/container/begin.hpp @@ -23,7 +23,9 @@ namespace sprout { // ADL callable range_begin(cont) -> range_begin(cont) // [default] // Container is T[N] -> iterator(cont) - // otherwise -> cont.begin() + // otherwise, ADL callable begin(cont) -> begin(cont) + // otherwise, callabe cont.begin() -> cont.begin() + // otherwise -> std::begin(cont) // template inline SPROUT_CONSTEXPR typename sprout::container_traits::iterator diff --git a/sprout/container/container_range_traits.hpp b/sprout/container/container_range_traits.hpp index 8fdf00fb..62698769 100644 --- a/sprout/container/container_range_traits.hpp +++ b/sprout/container/container_range_traits.hpp @@ -8,12 +8,14 @@ #ifndef SPROUT_CONTAINER_CONTAINER_RANGE_TRAITS_HPP #define SPROUT_CONTAINER_CONTAINER_RANGE_TRAITS_HPP +#include #include #include #include #include #include #include +#include #include #include #include @@ -21,6 +23,9 @@ #include namespace sprout_adl { + sprout::not_found_via_adl begin(...); + sprout::not_found_via_adl end(...); + sprout::not_found_via_adl range_begin(...); sprout::not_found_via_adl range_end(...); sprout::not_found_via_adl range_size(...); @@ -33,8 +38,266 @@ namespace sprout_adl { sprout::not_found_via_adl range_data(...); } // namespace sprout_adl + +namespace sprout_container_range_detail { + using sprout_adl::begin; + using sprout_adl::end; + + template + struct has_adl_begin_test { + public: + template< + typename U = T, + typename R = typename sprout::identity()))>::type + > + static sprout::is_found_via_adl test(int); + static sprout::false_type test(...); + }; + + template + inline SPROUT_CONSTEXPR typename sprout::container_traits::iterator + range_adl_begin(Container& cont) { + return begin(cont); + } + template + inline SPROUT_CONSTEXPR typename sprout::container_traits::iterator + range_adl_begin(Container const& cont) { + return begin(cont); + } + + template + struct has_adl_end_test { + public: + template< + typename U = T, + typename R = typename sprout::identity()))>::type + > + static sprout::is_found_via_adl test(int); + static sprout::false_type test(...); + }; + + template + inline SPROUT_CONSTEXPR typename sprout::container_traits::iterator + range_adl_end(Container& cont) { + return end(cont); + } + template + inline SPROUT_CONSTEXPR typename sprout::container_traits::iterator + range_adl_end(Container const& cont) { + return end(cont); + } +} // namespace sprout_container_range_detail + namespace sprout { namespace detail { +#if defined(_MSC_VER) && (_MSC_VER > 1900) + template::test(0))>::type> + struct has_adl_begin + : public Base_ + {}; +#else + template + struct has_adl_begin + : public sprout::identity::test(0))>::type + {}; +#endif + template::value> + struct has_adl_begin_without_sprout + : public sprout::false_type + {}; + template + struct has_adl_begin_without_sprout + : public sprout::detail::has_adl_begin + {}; + + template + struct has_mem_begin_test { + public: + template< + typename U = T, + typename = typename sprout::identity().begin())>::type + > + static sprout::true_type test(int); + static sprout::false_type test(...); + }; +#if defined(_MSC_VER) && (_MSC_VER > 1900) + template::test(0))>::type> + struct has_mem_begin + : public Base_ + {}; +#else + template + struct has_mem_begin + : public sprout::identity::test(0))>::type + {}; +#endif + + template + inline SPROUT_CONSTEXPR typename sprout::container_traits::iterator + range_adl_begin(Container& cont) { + using std::begin; + return begin(cont); + } + template + inline SPROUT_CONSTEXPR typename sprout::container_traits::iterator + range_adl_begin(Container const& cont) { + using std::begin; + return begin(cont); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::detail::has_adl_begin_without_sprout::value, + typename sprout::container_traits::iterator + >::type + range_begin_impl(Container& cont) { + return sprout_container_range_detail::range_adl_begin(cont); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::detail::has_adl_begin_without_sprout::value && sprout::detail::has_mem_begin::value, + typename sprout::container_traits::iterator + >::type + range_begin_impl(Container& cont) { + return cont.begin(); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::detail::has_adl_begin_without_sprout::value && !sprout::detail::has_mem_begin::value, + typename sprout::container_traits::iterator + >::type + range_begin_impl(Container& cont) { + return std::begin(cont); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::detail::has_adl_begin_without_sprout::value, + typename sprout::container_traits::iterator + >::type + range_begin_impl(Container const& cont) { + return sprout_container_range_detail::range_adl_begin(cont); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::detail::has_adl_begin_without_sprout::value && sprout::detail::has_mem_begin::value, + typename sprout::container_traits::iterator + >::type + range_begin_impl(Container const& cont) { + return cont.begin(); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::detail::has_adl_begin_without_sprout::value && !sprout::detail::has_mem_begin::value, + typename sprout::container_traits::iterator + >::type + range_begin_impl(Container const& cont) { + return std::begin(cont); + } + +#if defined(_MSC_VER) && (_MSC_VER > 1900) + template::test(0))>::type> + struct has_adl_end + : public Base_ + {}; +#else + template + struct has_adl_end + : public sprout::identity::test(0))>::type + {}; +#endif + template::value> + struct has_adl_end_without_sprout + : public sprout::false_type + {}; + template + struct has_adl_end_without_sprout + : public sprout::detail::has_adl_end + {}; + + template + struct has_mem_end_test { + public: + template< + typename U = T, + typename = typename sprout::identity().end())>::type + > + static sprout::true_type test(int); + static sprout::false_type test(...); + }; +#if defined(_MSC_VER) && (_MSC_VER > 1900) + template::test(0))>::type> + struct has_mem_end + : public Base_ + {}; +#else + template + struct has_mem_end + : public sprout::identity::test(0))>::type + {}; +#endif + + template + inline SPROUT_CONSTEXPR typename sprout::container_traits::iterator + range_adl_end(Container& cont) { + using std::end; + return end(cont); + } + template + inline SPROUT_CONSTEXPR typename sprout::container_traits::iterator + range_adl_end(Container const& cont) { + using std::end; + return end(cont); + } + + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::detail::has_adl_end_without_sprout::value, + typename sprout::container_traits::iterator + >::type + range_end_impl(Container& cont) { + return sprout_container_range_detail::range_adl_end(cont); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::detail::has_adl_end_without_sprout::value && sprout::detail::has_mem_end::value, + typename sprout::container_traits::iterator + >::type + range_end_impl(Container& cont) { + return cont.end(); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::detail::has_adl_end_without_sprout::value && !sprout::detail::has_mem_end::value, + typename sprout::container_traits::iterator + >::type + range_end_impl(Container& cont) { + return std::end(cont); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + sprout::detail::has_adl_end_without_sprout::value, + typename sprout::container_traits::iterator + >::type + range_end_impl(Container const& cont) { + return sprout_container_range_detail::range_adl_end(cont); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::detail::has_adl_end_without_sprout::value && sprout::detail::has_mem_end::value, + typename sprout::container_traits::iterator + >::type + range_end_impl(Container const& cont) { + return cont.end(); + } + template + inline SPROUT_CONSTEXPR typename std::enable_if< + !sprout::detail::has_adl_end_without_sprout::value && !sprout::detail::has_mem_end::value, + typename sprout::container_traits::iterator + >::type + range_end_impl(Container const& cont) { + return std::end(cont); + } + template struct has_mem_size_test { public: @@ -394,12 +657,14 @@ namespace sprout_container_range_detail { template inline SPROUT_CONSTEXPR typename sprout::container_traits::iterator range_begin(Container& cont) { - return cont.begin(); + return sprout::detail::range_begin_impl(cont); +// return cont.begin(); } template inline SPROUT_CONSTEXPR typename sprout::container_traits::iterator range_begin(Container const& cont) { - return cont.begin(); + return sprout::detail::range_begin_impl(cont); +// return cont.begin(); } template diff --git a/sprout/container/end.hpp b/sprout/container/end.hpp index 70de7ab8..13addd04 100644 --- a/sprout/container/end.hpp +++ b/sprout/container/end.hpp @@ -22,8 +22,10 @@ namespace sprout { // [default] // ADL callable range_end(cont) -> range_end(cont) // [default] - // Container is T[N] -> iterator(cont) + N - // otherwise -> cont.end() + // Container is T[N] -> iterator(cont) + // otherwise, ADL callable end(cont) -> end(cont) + // otherwise, callabe cont.end() -> cont.end() + // otherwise -> std::end(cont) // template inline SPROUT_CONSTEXPR typename sprout::container_traits::iterator diff --git a/sprout/type_traits.hpp b/sprout/type_traits.hpp index 7247a443..08e8fdd5 100644 --- a/sprout/type_traits.hpp +++ b/sprout/type_traits.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #endif // #ifndef SPROUT_TYPE_TRAITS_HPP diff --git a/sprout/type_traits/is_within_namespace.hpp b/sprout/type_traits/is_within_namespace.hpp new file mode 100644 index 00000000..a20de099 --- /dev/null +++ b/sprout/type_traits/is_within_namespace.hpp @@ -0,0 +1,15 @@ +/*============================================================================= + 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_TYPE_TRAITS_IS_WITHIN_NAMESPACE_HPP +#define SPROUT_TYPE_TRAITS_IS_WITHIN_NAMESPACE_HPP + +#include +#include +#include + +#endif // #ifndef SPROUT_TYPE_TRAITS_IS_WITHIN_NAMESPACE_HPP diff --git a/sprout/type_traits/is_within_namespace_boost.hpp b/sprout/type_traits/is_within_namespace_boost.hpp new file mode 100644 index 00000000..f7a6d27c --- /dev/null +++ b/sprout/type_traits/is_within_namespace_boost.hpp @@ -0,0 +1,60 @@ +/*============================================================================= + 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_TYPE_TRAITS_IS_WITHIN_NAMESPACE_BOOST_HPP +#define SPROUT_TYPE_TRAITS_IS_WITHIN_NAMESPACE_BOOST_HPP + +#include +#include +#include +#include +#include + +namespace sprout_adl { + sprout::not_found_via_adl sprout_adl_tester_namespace_boost(...); +} // namespace sprout_adl + +namespace boost { + template + void sprout_adl_tester_namespace_boost(T&&); +} // namespace boost + +namespace sprout_adl_tester_detail { + using sprout_adl::sprout_adl_tester_namespace_boost; + + template + struct is_within_namespace_boost_test { + public: + template< + typename U = T, + typename R = typename sprout::identity()))>::type + > + static sprout::is_found_via_adl test(int); + static sprout::false_type test(...); + }; +} // namespace sprout_adl_tester_detail + +namespace sprout { +#if defined(_MSC_VER) && (_MSC_VER > 1900) + template::test(0))>::type> + struct is_within_namespace_boost + : public Base_ + {}; +#else + template + struct is_within_namespace_boost + : public sprout::identity::test(0))>::type + {}; +#endif + +#if SPROUT_USE_VARIABLE_TEMPLATES + template + SPROUT_STATIC_CONSTEXPR bool is_within_namespace_boost_v = sprout::is_within_namespace_boost::value; +#endif // #if SPROUT_USE_VARIABLE_TEMPLATES +} // namespace sprout + +#endif // #ifndef SPROUT_TYPE_TRAITS_IS_WITHIN_NAMESPACE_BOOST_HPP diff --git a/sprout/type_traits/is_within_namespace_sprout.hpp b/sprout/type_traits/is_within_namespace_sprout.hpp new file mode 100644 index 00000000..3538c229 --- /dev/null +++ b/sprout/type_traits/is_within_namespace_sprout.hpp @@ -0,0 +1,60 @@ +/*============================================================================= + 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_TYPE_TRAITS_IS_WITHIN_NAMESPACE_SPROUT_HPP +#define SPROUT_TYPE_TRAITS_IS_WITHIN_NAMESPACE_SPROUT_HPP + +#include +#include +#include +#include +#include + +namespace sprout_adl { + sprout::not_found_via_adl sprout_adl_tester_namespace_sprout(...); +} // namespace sprout_adl + +namespace sprout { + template + void sprout_adl_tester_namespace_sprout(T&&); +} // namespace sprout + +namespace sprout_adl_tester_detail { + using sprout_adl::sprout_adl_tester_namespace_sprout; + + template + struct is_within_namespace_sprout_test { + public: + template< + typename U = T, + typename R = typename sprout::identity()))>::type + > + static sprout::is_found_via_adl test(int); + static sprout::false_type test(...); + }; +} // namespace sprout_adl_tester_detail + +namespace sprout { +#if defined(_MSC_VER) && (_MSC_VER > 1900) + template::test(0))>::type> + struct is_within_namespace_sprout + : public Base_ + {}; +#else + template + struct is_within_namespace_sprout + : public sprout::identity::test(0))>::type + {}; +#endif + +#if SPROUT_USE_VARIABLE_TEMPLATES + template + SPROUT_STATIC_CONSTEXPR bool is_within_namespace_sprout_v = sprout::is_within_namespace_sprout::value; +#endif // #if SPROUT_USE_VARIABLE_TEMPLATES +} // namespace sprout + +#endif // #ifndef SPROUT_TYPE_TRAITS_IS_WITHIN_NAMESPACE_SPROUT_HPP diff --git a/sprout/utility/as_non_const.hpp b/sprout/utility/as_non_const.hpp new file mode 100644 index 00000000..27df6eba --- /dev/null +++ b/sprout/utility/as_non_const.hpp @@ -0,0 +1,34 @@ +/*============================================================================= + 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_UTILITY_AS_NON_CONST_HPP +#define SPROUT_UTILITY_AS_NON_CONST_HPP + +#include +#include + +namespace sprout { + // + // as_non_const + // + template + inline SPROUT_CONSTEXPR typename std::conditional< + std::is_lvalue_reference::value, + typename std::remove_const::type>::type&, + typename std::remove_const::type>::type&& + >::type + as_non_const(T&& t) { + typedef typename std::conditional< + std::is_lvalue_reference::value, + typename std::remove_const::type>::type&, + typename std::remove_const::type>::type&& + >::type type; + return const_cast(t); + } +} // namespace sprout + +#endif // #ifndef SPROUT_UTILITY_AS_NON_CONST_HPP diff --git a/sprout/utility/cast.hpp b/sprout/utility/cast.hpp index 34e237e8..5147f44c 100644 --- a/sprout/utility/cast.hpp +++ b/sprout/utility/cast.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include