X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2FRange.h;h=228a8d5535c213194b579ccda1e1144b16e7e45b;hp=8ae96ce6cbe66fa2127e63824d38233ca02b4272;hb=b5750c50fc8348d61cd43d4fda623f6e64ddadb0;hpb=d44f36ab667239d020b0746d8da279b41997d869 diff --git a/folly/Range.h b/folly/Range.h index 8ae96ce6..228a8d55 100644 --- a/folly/Range.h +++ b/folly/Range.h @@ -19,7 +19,6 @@ #pragma once -#include #include #include #include @@ -30,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -38,17 +38,6 @@ #include #include -// libc++ doesn't provide this header, nor does msvc -#ifdef FOLLY_HAVE_BITS_CXXCONFIG_H -// This file appears in two locations: inside fbcode and in the -// libstdc++ source code (when embedding fbstring as std::string). -// To aid in this schizophrenic use, two macros are defined in -// c++config.h: -// _LIBSTDCXX_FBSTRING - Set inside libstdc++. This is useful to -// gate use inside fbcode v. libstdc++ -#include -#endif - #include #include #include @@ -61,6 +50,15 @@ FOLLY_GCC_DISABLE_WARNING("-Wshadow") namespace folly { +/** + * Ubiquitous helper template for knowing what's a string. + */ +template +struct IsSomeString : std::false_type {}; + +template <> +struct IsSomeString : std::true_type {}; + template class Range; @@ -212,9 +210,12 @@ class Range : private boost::totally_ordered> { /* implicit */ Range(std::nullptr_t) = delete; #endif - template ::type = 0> constexpr /* implicit */ Range(Iter str) - : b_(str), e_(str + constexpr_strlen(str)) {} + : b_(str), e_(str + constexpr_strlen(str)) { + static_assert( + std::is_same::type>::value, + "This constructor is only available for character ranges"); + } template ::const_type = 0> /* implicit */ Range(const std::string& str) @@ -248,30 +249,58 @@ class Range : private boost::totally_ordered> { Range(const Range& other, size_type first, size_type length = npos) : Range(other.subpiece(first, length)) {} - template ::const_type = 0> - /* implicit */ Range(const fbstring& str) - : b_(str.data()), e_(b_ + str.size()) {} + template < + class Container, + class = typename std::enable_if< + std::is_same::value>::type, + class = decltype( + Iter(std::declval().data()), + Iter( + std::declval().data() + + std::declval().size()))> + /* implicit */ constexpr Range(Container const& container) + : b_(container.data()), e_(b_ + container.size()) {} - template ::const_type = 0> - Range(const fbstring& str, fbstring::size_type startFrom) { - if (UNLIKELY(startFrom > str.size())) { + template < + class Container, + class = typename std::enable_if< + std::is_same::value>::type, + class = decltype( + Iter(std::declval().data()), + Iter( + std::declval().data() + + std::declval().size()))> + Range(Container const& container, typename Container::size_type startFrom) { + auto const cdata = container.data(); + auto const csize = container.size(); + if (UNLIKELY(startFrom > csize)) { std::__throw_out_of_range("index out of range"); } - b_ = str.data() + startFrom; - e_ = str.data() + str.size(); + b_ = cdata + startFrom; + e_ = cdata + csize; } - template ::const_type = 0> + template < + class Container, + class = typename std::enable_if< + std::is_same::value>::type, + class = decltype( + Iter(std::declval().data()), + Iter( + std::declval().data() + + std::declval().size()))> Range( - const fbstring& str, - fbstring::size_type startFrom, - fbstring::size_type size) { - if (UNLIKELY(startFrom > str.size())) { + Container const& container, + typename Container::size_type startFrom, + typename Container::size_type size) { + auto const cdata = container.data(); + auto const csize = container.size(); + if (UNLIKELY(startFrom > csize)) { std::__throw_out_of_range("index out of range"); } - b_ = str.data() + startFrom; - if (str.size() - startFrom < size) { - e_ = str.data() + str.size(); + b_ = cdata + startFrom; + if (csize - startFrom < size) { + e_ = cdata + csize; } else { e_ = b_ + size; } @@ -445,19 +474,18 @@ class Range : private boost::totally_ordered> { assert(b_ < e_); return detail::value_before(e_); } + + template + auto to() const + -> decltype(Tgt(std::declval(), std::declval())) { + return Tgt(b_, size()); + } // Works only for Range and Range std::string str() const { - return std::string(b_, size()); + return to(); } std::string toString() const { - return str(); - } - // Works only for Range and Range - fbstring fbstr() const { - return fbstring(b_, size()); - } - fbstring toFbstring() const { - return fbstr(); + return to(); } const_range_type castToConst() const { @@ -984,22 +1012,43 @@ constexpr Range range(Iter first, Iter last) { * Creates a range to reference the contents of a contiguous-storage container. */ // Use pointers for types with '.data()' member -template < - class Collection, - class T = typename std::remove_pointer< - decltype(std::declval().data())>::type> -constexpr Range range(Collection&& v) { - return Range(v.data(), v.data() + v.size()); +template +constexpr auto range(Collection& v) -> Range { + return Range(v.data(), v.data() + v.size()); +} +template +constexpr auto range(Collection const& v) -> Range { + return Range(v.data(), v.data() + v.size()); +} +template +constexpr auto crange(Collection const& v) -> Range { + return Range(v.data(), v.data() + v.size()); } template constexpr Range range(T (&array)[n]) { return Range(array, array + n); } +template +constexpr Range range(T const (&array)[n]) { + return Range(array, array + n); +} +template +constexpr Range crange(T const (&array)[n]) { + return Range(array, array + n); +} template -constexpr Range range(const std::array& array) { - return Range{array}; +constexpr Range range(std::array& array) { + return Range{array}; +} +template +constexpr Range range(std::array const& array) { + return Range{array}; +} +template +constexpr Range crange(std::array const& array) { + return Range{array}; } typedef Range StringPiece; @@ -1311,17 +1360,6 @@ struct hasher< } }; -/** - * Ubiquitous helper template for knowing what's a string - */ -template -struct IsSomeString { - enum { - value = - std::is_same::value || std::is_same::value - }; -}; - /** * _sp is a user-defined literal suffix to make an appropriate Range * specialization from a literal string. @@ -1353,8 +1391,8 @@ constexpr Range operator"" _sp( size_t len) noexcept { return Range(str, len); } -} // inline namespace string_piece_literals -} // inline namespace literals +} // namespace string_piece_literals +} // namespace literals } // namespace folly