support for C++14: memcmp, memchr

This commit is contained in:
bolero-MURAKAMI 2013-06-27 00:36:17 +09:00
parent 4182fb3fea
commit e0ccfedaaa
8 changed files with 80 additions and 9 deletions

View file

@ -14,7 +14,8 @@ namespace testspr {
{ {
SPROUT_STATIC_CONSTEXPR auto found = sprout::memchr(buf, b, 12); SPROUT_STATIC_CONSTEXPR auto found = sprout::memchr(buf, b, 12);
TESTSPR_BOTH_ASSERT(sprout::distance(buf, reinterpret_cast<unsigned char const*>(found)) == 8); TESTSPR_BOTH_ASSERT(buf + 8 == found);
// TESTSPR_BOTH_ASSERT(sprout::distance(buf, reinterpret_cast<unsigned char const*>(found)) == 8);
} }
} }
} }

View file

@ -6,6 +6,10 @@
#include <sprout/iterator/ptr_index_iterator.hpp> #include <sprout/iterator/ptr_index_iterator.hpp>
#include <sprout/algorithm/find.hpp> #include <sprout/algorithm/find.hpp>
#include <type_traits>
#include <utility>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
namespace detail { namespace detail {
inline SPROUT_CONSTEXPR unsigned char const* inline SPROUT_CONSTEXPR unsigned char const*
@ -20,6 +24,16 @@ namespace sprout {
: found : found
; ;
} }
template<typename T>
struct memchr_result {
private:
static void const* check(void const*);
static void* check(void*);
static void check(...);
public:
typedef decltype(check(std::declval<T>())) type;
};
} // namespace detail } // namespace detail
// 7.21.5.1 memchr ŠÖ<C5A0> // 7.21.5.1 memchr ŠÖ<C5A0>
@ -27,6 +41,7 @@ namespace sprout {
// recursion depth: // recursion depth:
// O(log N) // O(log N)
// //
#if 0
inline SPROUT_CONSTEXPR void const* inline SPROUT_CONSTEXPR void const*
memchr(void const* s, int c, std::size_t n) { memchr(void const* s, int c, std::size_t n) {
return sprout::detail::memchr_impl( return sprout::detail::memchr_impl(
@ -52,6 +67,40 @@ namespace sprout {
static_cast<unsigned char*>(s) + n static_cast<unsigned char*>(s) + n
); );
} }
#endif
template<
typename T,
typename sprout::enabler_if<std::is_same<typename sprout::detail::memchr_result<T>::type, void const*>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR void const*
memchr(T s, int c, std::size_t n) {
return sprout::detail::memchr_impl(
sprout::ptr_unindex(
sprout::find(
sprout::ptr_index(static_cast<unsigned char const*>(s)), sprout::ptr_index(static_cast<unsigned char const*>(s), n),
static_cast<unsigned char>(c)
)
),
static_cast<unsigned char const*>(s) + n
);
}
template<
typename T,
typename sprout::enabler_if<std::is_same<typename sprout::detail::memchr_result<T>::type, void*>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR void*
memchr(T s, int c, std::size_t n) {
return sprout::detail::memchr_impl(
sprout::ptr_unindex(
sprout::find(
sprout::ptr_index(static_cast<unsigned char*>(s)), sprout::ptr_index(static_cast<unsigned char*>(s), n),
static_cast<unsigned char>(c)
)
),
static_cast<unsigned char*>(s) + n
);
}
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_CSTRING_MEMCHR_HPP #endif // #ifndef SPROUT_CSTRING_MEMCHR_HPP

View file

@ -6,12 +6,16 @@
#include <sprout/iterator/ptr_index_iterator.hpp> #include <sprout/iterator/ptr_index_iterator.hpp>
#include <sprout/algorithm/tristate_lexicographical_compare.hpp> #include <sprout/algorithm/tristate_lexicographical_compare.hpp>
#include <type_traits>
#include <sprout/type_traits/enabler_if.hpp>
namespace sprout { namespace sprout {
// 7.21.4.1 memcmp ŠÖ<C5A0> // 7.21.4.1 memcmp ŠÖ<C5A0>
// //
// recursion depth: // recursion depth:
// O(log(N1+N2)) // O(log(N1+N2))
// //
#if 0
inline SPROUT_CONSTEXPR int inline SPROUT_CONSTEXPR int
memcmp(void const* s1, void const* s2, std::size_t n) { memcmp(void const* s1, void const* s2, std::size_t n) {
return sprout::tristate_lexicographical_compare( return sprout::tristate_lexicographical_compare(
@ -19,6 +23,18 @@ namespace sprout {
sprout::ptr_index(static_cast<unsigned char const*>(s2)), sprout::ptr_index(static_cast<unsigned char const*>(s2), n) sprout::ptr_index(static_cast<unsigned char const*>(s2)), sprout::ptr_index(static_cast<unsigned char const*>(s2), n)
); );
} }
#endif
template<
typename T,
typename sprout::enabler_if<std::is_convertible<T, void const*>::value>::type = sprout::enabler
>
inline SPROUT_CONSTEXPR int
memcmp(T s1, T s2, std::size_t n) {
return sprout::tristate_lexicographical_compare(
sprout::ptr_index(static_cast<unsigned char const*>(s1)), sprout::ptr_index(static_cast<unsigned char const*>(s1), n),
sprout::ptr_index(static_cast<unsigned char const*>(s2)), sprout::ptr_index(static_cast<unsigned char const*>(s2), n)
);
}
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_CSTRING_MEMCMP_HPP #endif // #ifndef SPROUT_CSTRING_MEMCMP_HPP

View file

@ -317,9 +317,7 @@ namespace sprout {
p = &(*p)->next; p = &(*p)->next;
} }
} }
SPROUT_CXX14_CONSTEXPR forward_clist(forward_clist&& x) SPROUT_CXX14_CONSTEXPR forward_clist(forward_clist&& x) = default;
: fst(sprout::move(x.fst))
{}
SPROUT_CXX14_CONSTEXPR forward_clist& operator=(forward_clist&& x) { SPROUT_CXX14_CONSTEXPR forward_clist& operator=(forward_clist&& x) {
fst = sprout::move(x.fst); fst = sprout::move(x.fst);
return *this; return *this;

View file

@ -1,7 +1,7 @@
#ifndef SPROUT_UTILITY_STRING_REF_CONVERSION_HPP #ifndef SPROUT_UTILITY_STRING_REF_CONVERSION_HPP
#define SPROUT_UTILITY_STRING_REF_CONVERSION_HPP #define SPROUT_UTILITY_STRING_REF_CONVERSION_HPP
#include <cstddef> #include <sprout/config.hpp>
#include <sprout/utility/string_ref/from_string.hpp> #include <sprout/utility/string_ref/from_string.hpp>
#endif // #ifndef SPROUT_UTILITY_STRING_REF_CONVERSION_HPP #endif // #ifndef SPROUT_UTILITY_STRING_REF_CONVERSION_HPP

View file

@ -0,0 +1,7 @@
#ifndef SPROUT_UTILITY_STRING_VIEW_HPP
#define SPROUT_UTILITY_STRING_VIEW_HPP
#include <sprout/config.hpp>
#include <sprout/utility/string_ref.hpp>
#endif // #ifndef SPROUT_UTILITY_STRING_VIEW_HPP

View file

@ -66,7 +66,7 @@ namespace sprout {
sprout::weed::detail::is_elem_and_container<T, U>::value sprout::weed::detail::is_elem_and_container<T, U>::value
>::type >::type
> >
: public sprout::fixed::result_of::push_front<T, U> : public sprout::fixed::result_of::push_front<U, T>
{}; {};
// tuple<Vs...> >> tuple<Ws...> -> tuple<Vs..., Ws...> // tuple<Vs...> >> tuple<Ws...> -> tuple<Vs..., Ws...>
template<typename T, typename U> template<typename T, typename U>
@ -99,7 +99,7 @@ namespace sprout {
sprout::weed::detail::is_elem_and_tuple<T, U>::value sprout::weed::detail::is_elem_and_tuple<T, U>::value
>::type >::type
> >
: public sprout::tuples::result_of::push_front<T, U> : public sprout::tuples::result_of::push_front<U, T>
{}; {};
// V >> V -> container<V, 2> // V >> V -> container<V, 2>
template<typename T, typename U> template<typename T, typename U>

View file

@ -51,7 +51,7 @@ namespace sprout {
sprout::weed::detail::is_elem_and_container<T, U>::value, sprout::weed::detail::is_elem_and_container<T, U>::value,
typename sprout::weed::attr_cnv::result_of::shift_left<T, U>::type typename sprout::weed::attr_cnv::result_of::shift_left<T, U>::type
>::type shift_left(T const& t, U const& u) { >::type shift_left(T const& t, U const& u) {
return sprout::fixed::push_front(t, u); return sprout::fixed::push_front(u, t);
} }
// tuple<Vs...> >> tuple<Ws...> -> tuple<Vs..., Ws...> // tuple<Vs...> >> tuple<Ws...> -> tuple<Vs..., Ws...>
template<typename T, typename U> template<typename T, typename U>
@ -75,7 +75,7 @@ namespace sprout {
sprout::weed::detail::is_elem_and_tuple<T, U>::value, sprout::weed::detail::is_elem_and_tuple<T, U>::value,
typename sprout::weed::attr_cnv::result_of::shift_left<T, U>::type typename sprout::weed::attr_cnv::result_of::shift_left<T, U>::type
>::type shift_left(T const& t, U const& u) { >::type shift_left(T const& t, U const& u) {
return sprout::tuples::push_front(t, u); return sprout::tuples::push_front(u, t);
} }
// V >> V -> container<V, 2> // V >> V -> container<V, 2>
template<typename T, typename U> template<typename T, typename U>