PageRenderTime 74ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/sprout/cstring/strlen.hpp

http://github.com/bolero-MURAKAMI/Sprout
C++ Header | 106 lines | 89 code | 5 blank | 12 comment | 1 complexity | 0821772409ae75b5e4d22db6d63b653c MD5 | raw file
  1. /*=============================================================================
  2. Copyright (c) 2011-2019 Bolero MURAKAMI
  3. https://github.com/bolero-MURAKAMI/Sprout
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. =============================================================================*/
  7. #ifndef SPROUT_CSTRING_STRLEN_HPP
  8. #define SPROUT_CSTRING_STRLEN_HPP
  9. #include <iterator>
  10. #include <type_traits>
  11. #include <sprout/config.hpp>
  12. #include <sprout/workaround/std/cstddef.hpp>
  13. #include <sprout/iterator/operation.hpp>
  14. #include <sprout/iterator/ptr_index_iterator.hpp>
  15. #include <sprout/utility/pair/pair.hpp>
  16. #include <sprout/type_traits/is_char_type.hpp>
  17. #include <sprout/algorithm/find.hpp>
  18. namespace sprout {
  19. namespace detail {
  20. template<typename InputIterator>
  21. inline SPROUT_CONSTEXPR sprout::pair<InputIterator, std::size_t>
  22. strlen_impl_1(
  23. sprout::pair<InputIterator, std::size_t> const& current,
  24. typename std::iterator_traits<InputIterator>::difference_type n
  25. )
  26. {
  27. typedef sprout::pair<InputIterator, std::size_t> type;
  28. return !*current.first ? current
  29. : n == 1 ? type(sprout::next(current.first), current.second + 1)
  30. : sprout::detail::strlen_impl_1(
  31. sprout::detail::strlen_impl_1(
  32. current,
  33. n / 2
  34. ),
  35. n - n / 2
  36. )
  37. ;
  38. }
  39. template<typename InputIterator>
  40. inline SPROUT_CONSTEXPR sprout::pair<InputIterator, std::size_t>
  41. strlen_impl(
  42. sprout::pair<InputIterator, std::size_t> const& current,
  43. typename std::iterator_traits<InputIterator>::difference_type n
  44. )
  45. {
  46. return !*current.first ? current
  47. : sprout::detail::strlen_impl(
  48. sprout::detail::strlen_impl_1(
  49. current,
  50. n
  51. ),
  52. n * 2
  53. )
  54. ;
  55. }
  56. template<typename InputIterator>
  57. inline SPROUT_CONSTEXPR std::size_t
  58. strlen(InputIterator first) {
  59. typedef sprout::pair<InputIterator, std::size_t> type;
  60. return sprout::detail::strlen_impl(type(first, 0), 1).second;
  61. }
  62. } // namespace detail
  63. // 7.21.6.3 strlen function
  64. //
  65. // recursion depth:
  66. // O(log N)
  67. //
  68. inline SPROUT_CONSTEXPR std::size_t
  69. strlen(char const* s) {
  70. return sprout::detail::strlen(s);
  71. }
  72. inline SPROUT_CONSTEXPR std::size_t
  73. strlen(char const* s, std::size_t n) {
  74. return sprout::distance(
  75. sprout::ptr_index(s),
  76. sprout::find(sprout::ptr_index(s), sprout::ptr_index(s, n), '\0')
  77. );
  78. }
  79. template<typename Elem>
  80. inline SPROUT_CONSTEXPR typename std::enable_if<
  81. sprout::is_char_type<Elem>::value,
  82. std::size_t
  83. >::type
  84. strlen(Elem* s) {
  85. return sprout::detail::strlen(s);
  86. }
  87. template<typename Elem>
  88. inline SPROUT_CONSTEXPR typename std::enable_if<
  89. sprout::is_char_type<Elem>::value,
  90. std::size_t
  91. >::type
  92. strlen(Elem* s, std::size_t n) {
  93. typedef typename std::decay<Elem>::type type;
  94. return sprout::distance(
  95. sprout::ptr_index(s),
  96. sprout::find(sprout::ptr_index(s), sprout::ptr_index(s, n), type())
  97. );
  98. }
  99. } // namespace sprout
  100. #endif // #ifndef SPROUT_CSTRING_STRLEN_HPP