diff --git a/hphp/third_party/folly/folly/Bits.h b/hphp/third_party/folly/folly/Bits.h index 0b45f84f3..2b5225243 100644 --- a/hphp/third_party/folly/folly/Bits.h +++ b/hphp/third_party/folly/folly/Bits.h @@ -57,10 +57,6 @@ #include "folly/Portability.h" -#ifndef _GNU_SOURCE -#define _GNU_SOURCE 1 -#endif - #ifndef __GNUC__ #error GCC required #endif diff --git a/hphp/third_party/folly/folly/FBString.h b/hphp/third_party/folly/folly/FBString.h index a410a1861..cc34fe668 100644 --- a/hphp/third_party/folly/folly/FBString.h +++ b/hphp/third_party/folly/folly/FBString.h @@ -985,7 +985,7 @@ private: } public: - // 21.3.1 construct/copy/destroy + // C++11 21.4.2 construct/copy/destroy explicit basic_fbstring(const A& a = A()) { } @@ -1047,6 +1047,11 @@ public: : store_(s, n, c, a) { } + // Construction from initialization list + basic_fbstring(std::initializer_list il) { + assign(il.begin(), il.end()); + } + ~basic_fbstring() { } @@ -1076,7 +1081,7 @@ public: basic_fbstring& operator=(basic_fbstring&& goner) { if (FBSTRING_UNLIKELY(&goner == this)) { // Compatibility with std::basic_string<>, - // 21.4.2 [string.cons] / 23 requires self-move-assignment support. + // C++11 21.4.2 [string.cons] / 23 requires self-move-assignment support. return *this; } // No need of this anymore @@ -1121,11 +1126,17 @@ public: return *this; } - // 21.3.2 iterators: + basic_fbstring& operator=(std::initializer_list il) { + return assign(il.begin(), il.end()); + } + + // C++11 21.4.3 iterators: iterator begin() { return store_.mutable_data(); } const_iterator begin() const { return store_.data(); } + const_iterator cbegin() const { return begin(); } + iterator end() { return store_.mutable_data() + store_.size(); } @@ -1134,6 +1145,8 @@ public: return store_.data() + store_.size(); } + const_iterator cend() const { return end(); } + reverse_iterator rbegin() { return reverse_iterator(end()); } @@ -1142,6 +1155,8 @@ public: return const_reverse_iterator(end()); } + const_reverse_iterator crbegin() const { return rbegin(); } + reverse_iterator rend() { return reverse_iterator(begin()); } @@ -1150,6 +1165,8 @@ public: return const_reverse_iterator(begin()); } + const_reverse_iterator crend() const { return rend(); } + // Added by C++11 // C++11 21.4.5, element access: const value_type& front() const { return *begin(); } @@ -1169,7 +1186,7 @@ public: store_.shrink(1); } - // 21.3.3 capacity: + // C++11 21.4.4 capacity: size_type size() const { return store_.size(); } size_type length() const { return size(); } @@ -1213,11 +1230,19 @@ public: store_.reserve(res_arg); } + void shrink_to_fit() { + // Shrink only if slack memory is sufficiently large + if (capacity() < size() * 3 / 2) { + return; + } + basic_fbstring(cbegin(), cend()).swap(*this); + } + void clear() { resize(0); } bool empty() const { return size() == 0; } - // 21.3.4 element access: + // C++11 21.4.5 element access: const_reference operator[](size_type pos) const { return *(c_str() + pos); } @@ -1240,7 +1265,7 @@ public: return (*this)[n]; } - // 21.3.5 modifiers: + // C++11 21.4.6 modifiers: basic_fbstring& operator+=(const basic_fbstring& str) { return append(str); } @@ -1254,6 +1279,11 @@ public: return *this; } + basic_fbstring& operator+=(std::initializer_list il) { + append(il); + return *this; + } + basic_fbstring& append(const basic_fbstring& str) { #ifndef NDEBUG auto desiredSize = size() + str.size(); @@ -1323,6 +1353,10 @@ public: return *this; } + basic_fbstring& append(std::initializer_list il) { + return append(il.begin(), il.end()); + } + void push_back(const value_type c) { // primitive store_.push_back(c); } @@ -1332,6 +1366,10 @@ public: return assign(str.data(), str.size()); } + basic_fbstring& assign(basic_fbstring&& str) { + return *this = std::move(str); + } + basic_fbstring& assign(const basic_fbstring& str, const size_type pos, size_type n) { const size_type sz = str.size(); @@ -1362,6 +1400,10 @@ public: return assign(s, traits_type::length(s)); } + basic_fbstring& assign(std::initializer_list il) { + return assign(il.begin(), il.end()); + } + template basic_fbstring& assign(ItOrLength first_or_n, ItOrChar last_or_c) { return replace(begin(), end(), first_or_n, last_or_c); @@ -1394,7 +1436,7 @@ public: return *this; } - iterator insert(const iterator p, const value_type c) { + iterator insert(const_iterator p, const value_type c) { const size_type pos = p - begin(); insert(p, 1, c); return begin() + pos; @@ -1403,10 +1445,11 @@ public: private: template class Selector {}; - basic_fbstring& insertImplDiscr(iterator p, - size_type n, value_type c, Selector<1>) { + iterator insertImplDiscr(const_iterator p, + size_type n, value_type c, Selector<1>) { Invariant checker(*this); (void) checker; + auto const pos = p - begin(); assert(p >= begin() && p <= end()); if (capacity() - size() < n) { const size_type sz = p - begin(); @@ -1414,33 +1457,33 @@ private: p = begin() + sz; } const iterator oldEnd = end(); - if( n < size_type(oldEnd - p)) { + if (n < size_type(oldEnd - p)) { append(oldEnd - n, oldEnd); //std::copy( // reverse_iterator(oldEnd - n), // reverse_iterator(p), // reverse_iterator(oldEnd)); - fbstring_detail::pod_move(&*p, &*oldEnd - n, &*p + n); - std::fill(p, p + n, c); + fbstring_detail::pod_move(&*p, &*oldEnd - n, + begin() + pos + n); + std::fill(begin() + pos, begin() + pos + n, c); } else { append(n - (end() - p), c); - append(p, oldEnd); - std::fill(p, oldEnd, c); + append(iterator(p), oldEnd); + std::fill(iterator(p), oldEnd, c); } store_.writeTerminator(); - return *this; + return begin() + pos; } template - basic_fbstring& insertImplDiscr(iterator i, - InputIter b, InputIter e, Selector<0>) { - insertImpl(i, b, e, + iterator insertImplDiscr(const_iterator i, + InputIter b, InputIter e, Selector<0>) { + return insertImpl(i, b, e, typename std::iterator_traits::iterator_category()); - return *this; } template - void insertImpl(iterator i, + iterator insertImpl(const_iterator i, FwdIterator s1, FwdIterator s2, std::forward_iterator_tag) { Invariant checker(*this); (void) checker; @@ -1462,9 +1505,9 @@ private: const iterator tailBegin = end() - n2; store_.expand_noinit(n2); fbstring_detail::pod_copy(tailBegin, tailBegin + n2, end() - n2); - std::copy(reverse_iterator(tailBegin), reverse_iterator(i), + std::copy(const_reverse_iterator(tailBegin), const_reverse_iterator(i), reverse_iterator(tailBegin + n2)); - std::copy(s1, s2, i); + std::copy(s1, s2, begin() + pos); } else { FwdIterator t = s1; const size_type old_size = size(); @@ -1474,27 +1517,35 @@ private: std::copy(t, s2, begin() + old_size); fbstring_detail::pod_copy(data() + pos, data() + old_size, begin() + old_size + newElems); - std::copy(s1, t, i); + std::copy(s1, t, begin() + pos); } store_.writeTerminator(); + return begin() + pos; } template - void insertImpl(iterator i, - InputIterator b, InputIterator e, std::input_iterator_tag) { + iterator insertImpl(const_iterator i, + InputIterator b, InputIterator e, + std::input_iterator_tag) { + const auto pos = i - begin(); basic_fbstring temp(begin(), i); for (; b != e; ++b) { temp.push_back(*b); } - temp.append(i, end()); + temp.append(i, cend()); swap(temp); + return begin() + pos; } public: template - void insert(iterator p, ItOrLength first_or_n, ItOrChar last_or_c) { + iterator insert(const_iterator p, ItOrLength first_or_n, ItOrChar last_or_c) { Selector::is_specialized> sel; - insertImplDiscr(p, first_or_n, last_or_c, sel); + return insertImplDiscr(p, first_or_n, last_or_c, sel); + } + + iterator insert(const_iterator p, std::initializer_list il) { + return insert(p, il.begin(), il.end()); } basic_fbstring& erase(size_type pos = 0, size_type n = npos) { @@ -1690,7 +1741,6 @@ public: store_.swap(rhs.store_); } - // 21.3.6 string operations: const value_type* c_str() const { return store_.c_str(); } @@ -2165,7 +2215,7 @@ bool operator>=(const typename basic_fbstring::value_type* lhs, return !(lhs < rhs); } -// subclause 21.3.7.8: +// C++11 21.4.8.8 template void swap(basic_fbstring& lhs, basic_fbstring& rhs) { lhs.swap(rhs); diff --git a/hphp/third_party/folly/folly/Hash.h b/hphp/third_party/folly/folly/Hash.h index 132ad846e..cbd07b56b 100644 --- a/hphp/third_party/folly/folly/Hash.h +++ b/hphp/third_party/folly/folly/Hash.h @@ -21,6 +21,7 @@ #include #include #include +#include #include "folly/SpookyHashV1.h" #include "folly/SpookyHashV2.h" @@ -348,6 +349,26 @@ template<> struct hasher { } }; +// recursion +template +struct TupleHasher { + size_t operator()(std::tuple const& key) const { + return hash::hash_combine( + TupleHasher()(key), + std::get(key)); + } +}; + +// base +template +struct TupleHasher<0, Ts...> { + size_t operator()(std::tuple const& key) const { + // we could do std::hash here directly, but hash_combine hides all the + // ugly templating implicitly + return hash::hash_combine(std::get<0>(key)); + } +}; + } // namespace folly // Custom hash functions. @@ -361,6 +382,18 @@ namespace std { return folly::hash::hash_combine(x.first, x.second); } }; + + // Hash function for tuples. Requires default hash functions for all types. + template + struct hash> { + size_t operator()(std::tuple const& key) const { + folly::TupleHasher< + std::tuple_size>::value - 1, // start index + Ts...> hasher; + + return hasher(key); + } + }; } // namespace std #endif diff --git a/hphp/third_party/folly/folly/String.h b/hphp/third_party/folly/folly/String.h index 93a4c6583..d706a0321 100644 --- a/hphp/third_party/folly/folly/String.h +++ b/hphp/third_party/folly/folly/String.h @@ -443,6 +443,13 @@ void join(const Delim& delimiter, join(delimiter, container.begin(), container.end(), output); } +template +void join(const Delim& delimiter, + const std::initializer_list& values, + String& output) { + join(delimiter, values.begin(), values.end(), output); +} + template std::string join(const Delim& delimiter, const Container& container) { @@ -451,6 +458,14 @@ std::string join(const Delim& delimiter, return output; } +template +std::string join(const Delim& delimiter, + const std::initializer_list& values) { + std::string output; + join(delimiter, values.begin(), values.end(), output); + return output; +} + } // namespace folly // Hash functions for string and fbstring usable with e.g. hash_map diff --git a/hphp/third_party/folly/folly/experimental/Gen-inl.h b/hphp/third_party/folly/folly/experimental/Gen-inl.h index 8b0c4dc74..f553cc869 100644 --- a/hphp/third_party/folly/folly/experimental/Gen-inl.h +++ b/hphp/third_party/folly/folly/experimental/Gen-inl.h @@ -1675,11 +1675,11 @@ class RangeConcat : public Operator { public: RangeConcat() { } - template::RefType> class Generator - : public GenImpl> { + : public GenImpl> { Source source_; public: explicit Generator(Source source) @@ -1709,19 +1709,91 @@ class RangeConcat : public Operator { template> + class Gen = Generator> Gen compose(GenImpl&& source) const { return Gen(std::move(source.self())); } template> + class Gen = Generator> Gen compose(const GenImpl& source) const { return Gen(source.self()); } }; + +/** + * GuardImpl - For handling exceptions from downstream computation. Requires the + * type of exception to catch, and handler function to invoke in the event of + * the exception. Note that the handler may: + * 1) return true to continue processing the sequence + * 2) return false to end the sequence immediately + * 3) throw, to pass the exception to the next catch + * The handler must match the signature 'bool(Exception&, Value)'. + * + * This type is used through the `guard` helper, like so: + * + * auto indexes + * = byLine(STDIN_FILENO) + * | guard([](std::runtime_error& e, + * StringPiece sp) { + * LOG(ERROR) << sp << ": " << e.str(); + * return true; // continue processing subsequent lines + * }) + * | eachTo() + * | as(); + * + * TODO(tjackson): Rename this back to Guard. + **/ +template +class GuardImpl : public Operator> { + ErrorHandler handler_; + public: + GuardImpl(ErrorHandler handler) + : handler_(std::move(handler)) {} + + template + class Generator : public GenImpl> { + Source source_; + ErrorHandler handler_; + public: + explicit Generator(Source source, + ErrorHandler handler) + : source_(std::move(source)), + handler_(std::move(handler)) {} + + template + bool apply(Handler&& handler) const { + return source_.apply([&](Value value) -> bool { + try { + handler(std::forward(value)); + return true; + } catch (Exception& e) { + return handler_(e, std::forward(value)); + } + }); + } + + static constexpr bool infinite = Source::infinite; + }; + + template> + Gen compose(GenImpl&& source) const { + return Gen(std::move(source.self()), handler_); + } + + template> + Gen compose(const GenImpl& source) const { + return Gen(source.self(), handler_); + } +}; } //::detail /** diff --git a/hphp/third_party/folly/folly/experimental/Gen.h b/hphp/third_party/folly/folly/experimental/Gen.h index 47fab1976..342968b02 100644 --- a/hphp/third_party/folly/folly/experimental/Gen.h +++ b/hphp/third_party/folly/folly/experimental/Gen.h @@ -343,6 +343,10 @@ struct GeneratorBuilder; template class Contains; +template +class GuardImpl; + } /** @@ -622,6 +626,16 @@ Contains contains(Needle&& needle) { return Contains(std::forward(needle)); } +template::type>> +GuardImpl guard(ErrorHandler&& handler) { + return GuardImpl(std::forward(handler)); +} + }} // folly::gen #include "folly/experimental/Gen-inl.h" diff --git a/hphp/third_party/folly/folly/io/RecordIO.cpp b/hphp/third_party/folly/folly/io/RecordIO.cpp index 566ce3656..a40750573 100644 --- a/hphp/third_party/folly/folly/io/RecordIO.cpp +++ b/hphp/third_party/folly/folly/io/RecordIO.cpp @@ -201,7 +201,6 @@ RecordInfo findRecord(ByteRange searchRange, static const uint32_t magic = Header::kMagic; static const ByteRange magicRange(reinterpret_cast(&magic), sizeof(magic)); - static constexpr size_t headerTail = sizeof(Header) - sizeof(magic); DCHECK_GE(searchRange.begin(), wholeRange.begin()); DCHECK_LE(searchRange.end(), wholeRange.end());