/*============================================================================= 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_CSTRING_STRLEN_HPP #define SPROUT_CSTRING_STRLEN_HPP #include #include #include #include #include #include #include #include #include namespace sprout { namespace detail { template inline SPROUT_CONSTEXPR sprout::pair strlen_impl_1( sprout::pair const& current, typename std::iterator_traits::difference_type n ) { typedef sprout::pair type; return !*current.first ? current : n == 1 ? type(sprout::next(current.first), current.second + 1) : sprout::detail::strlen_impl_1( sprout::detail::strlen_impl_1( current, n / 2 ), n - n / 2 ) ; } template inline SPROUT_CONSTEXPR sprout::pair strlen_impl( sprout::pair const& current, typename std::iterator_traits::difference_type n ) { return !*current.first ? current : sprout::detail::strlen_impl( sprout::detail::strlen_impl_1( current, n ), n * 2 ) ; } template inline SPROUT_CONSTEXPR std::size_t strlen(InputIterator first) { typedef sprout::pair type; return sprout::detail::strlen_impl(type(first, 0), 1).second; } } // namespace detail // 7.21.6.3 strlen function // // recursion depth: // O(log N) // inline SPROUT_CONSTEXPR std::size_t strlen(char const* s) { return sprout::detail::strlen(s); } inline SPROUT_CONSTEXPR std::size_t strlen(char const* s, std::size_t n) { return sprout::distance( sprout::ptr_index(s), sprout::find(sprout::ptr_index(s), sprout::ptr_index(s, n), '\0') ); } template inline SPROUT_CONSTEXPR typename std::enable_if< sprout::is_char_type::value, std::size_t >::type strlen(Elem* s) { return sprout::detail::strlen(s); } template inline SPROUT_CONSTEXPR typename std::enable_if< sprout::is_char_type::value, std::size_t >::type strlen(Elem* s, std::size_t n) { typedef typename std::decay::type type; return sprout::distance( sprout::ptr_index(s), sprout::find(sprout::ptr_index(s), sprout::ptr_index(s, n), type()) ); } } // namespace sprout #endif // #ifndef SPROUT_CSTRING_STRLEN_HPP