From 65e4672ea17edb4cb0494c390fdaed81db9c168c Mon Sep 17 00:00:00 2001 From: Sara Golemon Date: Tue, 9 Jul 2013 12:20:45 -0700 Subject: [PATCH] Update folly --- hphp/third_party/folly/folly/Range.h | 4 ++ hphp/third_party/folly/folly/Synchronized.h | 51 ++++++++++++++++++--- hphp/third_party/folly/folly/json.cpp | 6 +++ hphp/third_party/folly/folly/json.h | 4 ++ 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/hphp/third_party/folly/folly/Range.h b/hphp/third_party/folly/folly/Range.h index 2c26db075..85a554c59 100644 --- a/hphp/third_party/folly/folly/Range.h +++ b/hphp/third_party/folly/folly/Range.h @@ -705,12 +705,14 @@ inline size_t qfind(const Range& haystack, const char& needle) { return pos == nullptr ? std::string::npos : pos - haystack.data(); } +#ifdef _GNU_SOURCE // memrchr is a GNU extension template <> inline size_t rfind(const Range& haystack, const char& needle) { auto pos = static_cast( ::memrchr(haystack.data(), needle, haystack.size())); return pos == nullptr ? std::string::npos : pos - haystack.data(); } +#endif // specialization for ByteRange template <> @@ -721,6 +723,7 @@ inline size_t qfind(const Range& haystack, return pos == nullptr ? std::string::npos : pos - haystack.data(); } +#ifdef _GNU_SOURCE // memrchr is a GNU extension template <> inline size_t rfind(const Range& haystack, const unsigned char& needle) { @@ -728,6 +731,7 @@ inline size_t rfind(const Range& haystack, ::memrchr(haystack.data(), needle, haystack.size())); return pos == nullptr ? std::string::npos : pos - haystack.data(); } +#endif template size_t qfind_first_of(const Range& haystack, diff --git a/hphp/third_party/folly/folly/Synchronized.h b/hphp/third_party/folly/folly/Synchronized.h index ea1cb84d0..d632a772c 100644 --- a/hphp/third_party/folly/folly/Synchronized.h +++ b/hphp/third_party/folly/folly/Synchronized.h @@ -48,9 +48,11 @@ template struct HasLockUnlock { enum { value = IsOneOf::value }; }; @@ -95,6 +97,7 @@ acquireReadWrite(T& mutex) { mutex.lock(); } +#ifndef __APPLE__ // OSX doesn't have timed mutexes /** * Acquires a mutex for reading and writing with timeout by calling * .try_lock_for(). This applies to two of the std mutex classes as @@ -121,6 +124,7 @@ acquireReadWrite(T& mutex, unsigned int milliseconds) { return mutex.timed_lock(boost::posix_time::milliseconds(milliseconds)); } +#endif // __APPLE__ /** * Releases a mutex previously acquired for reading by calling @@ -186,8 +190,8 @@ struct Synchronized { * constructor. */ Synchronized() = default; - /** + /** * Copy constructor copies the data (with locking the source and * all) but does NOT copy the mutex. Doing so would result in * deadlocks. @@ -216,7 +220,7 @@ struct Synchronized { * Constructor taking a datum rvalue as argument moves it. Again, * there is no need to lock the constructing object. */ - explicit Synchronized(T && rhs) : datum_(std::move(rhs)) {} + explicit Synchronized(T&& rhs) : datum_(std::move(rhs)) {} /** * The canonical assignment operator only assigns the data, NOT the @@ -224,7 +228,9 @@ struct Synchronized { * addresses. */ Synchronized& operator=(const Synchronized& rhs) { - if (this < *rhs) { + if (this == &rhs) { + // Self-assignment, pass. + } else if (this < &rhs) { auto guard1 = operator->(); auto guard2 = rhs.operator->(); datum_ = rhs.datum_; @@ -236,6 +242,26 @@ struct Synchronized { return *this; } + /** + * Move assignment operator, only assigns the data, NOT the + * mutex. It locks the two objects in ascending order of their + * addresses. + */ + Synchronized& operator=(Synchronized&& rhs) { + if (this == &rhs) { + // Self-assignment, pass. + } else if (this < &rhs) { + auto guard1 = operator->(); + auto guard2 = rhs.operator->(); + datum_ = std::move(rhs.datum_); + } else { + auto guard1 = rhs.operator->(); + auto guard2 = operator->(); + datum_ = std::move(rhs.datum_); + } + return *this; + } + /** * Lock object, assign datum. */ @@ -245,6 +271,15 @@ struct Synchronized { return *this; } + /** + * Lock object, move-assign datum. + */ + Synchronized& operator=(T&& rhs) { + auto guard = operator->(); + datum_ = std::move(rhs); + return *this; + } + /** * A LockedPtr lp keeps a modifiable (i.e. non-const) * Synchronized object locked for the duration of lp's @@ -515,7 +550,9 @@ struct Synchronized { } auto guard1 = operator->(); auto guard2 = rhs.operator->(); - datum_.swap(rhs.datum_); + + using std::swap; + swap(datum_, rhs.datum_); } /** @@ -524,7 +561,9 @@ struct Synchronized { */ void swap(T& rhs) { LockedPtr guard = operator->(); - datum_.swap(rhs); + + using std::swap; + swap(datum_, rhs); } /** diff --git a/hphp/third_party/folly/folly/json.cpp b/hphp/third_party/folly/folly/json.cpp index 445b4b0ae..7711a2033 100644 --- a/hphp/third_party/folly/folly/json.cpp +++ b/hphp/third_party/folly/folly/json.cpp @@ -385,6 +385,9 @@ dynamic parseObject(Input& in) { } for (;;) { + if (in.getOpts().allow_trailing_comma && *in == '}') { + break; + } if (*in == '\"') { // string auto key = parseString(in); in.skipWhitespace(); @@ -426,6 +429,9 @@ dynamic parseArray(Input& in) { } for (;;) { + if (in.getOpts().allow_trailing_comma && *in == ']') { + break; + } ret.push_back(parseValue(in)); in.skipWhitespace(); if (*in != ',') { diff --git a/hphp/third_party/folly/folly/json.h b/hphp/third_party/folly/folly/json.h index 84a70661c..40f23f2a9 100644 --- a/hphp/third_party/folly/folly/json.h +++ b/hphp/third_party/folly/folly/json.h @@ -58,6 +58,7 @@ namespace json { , pretty_formatting(false) , encode_non_ascii(false) , validate_utf8(false) + , allow_trailing_comma(false) {} // If true, keys in an object can be non-strings. (In strict @@ -81,6 +82,9 @@ namespace json { // Check that strings are valid utf8 bool validate_utf8; + + // Allow trailing comma in lists of values / items + bool allow_trailing_comma; }; /*