Skip to content

Commit

Permalink
C++ improvements to Fleece.hh
Browse files Browse the repository at this point in the history
- Make Value, Array, Dict trivially copyable: this allows instances
  to be passed in a register instead of on the stack in some ABIs,
  such as ARM64, which is more efficient. (The fix is to remove the
  custom operator= methods, which are unnecessary.)
- Made operator==, operator!= methods const.
- Made move constructors/assignment `noexcept`, which helps
  collections generate more optimal code.
- Don't pass `alloc_slice` or `string` by value.
  • Loading branch information
snej committed Aug 28, 2024
1 parent b794101 commit 75a30c8
Showing 1 changed file with 12 additions and 11 deletions.
23 changes: 12 additions & 11 deletions API/fleece/Fleece.hh
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ namespace fleece {

bool isEqual(Value v) const {return FLValue_IsEqual(_val, v);}

Value& operator= (Value v) & {_val = v._val; return *this;}
Value& operator= (std::nullptr_t) & {_val = nullptr; return *this;}

inline Value operator[] (const KeyPath &kp) const;
Expand Down Expand Up @@ -128,9 +127,8 @@ namespace fleece {
inline Value operator[] (int index) const {return get(index);}
inline Value operator[] (const KeyPath &kp) const {return Value::operator[](kp);}

Array& operator= (Array a) & {_val = a._val; return *this;}
Array& operator= (std::nullptr_t) & {_val = nullptr; return *this;}
Value& operator= (Value v) =delete;
Array& operator= (std::nullptr_t) & {_val = nullptr; return *this;}
Value& operator= (Value v) =delete;

[[nodiscard]] inline MutableArray asMutable() const;

Expand All @@ -148,7 +146,7 @@ namespace fleece {
inline Value operator * () const {return value();}
inline explicit operator bool() const {return (bool)value();}
inline iterator& operator++ () {next(); return *this;}
inline bool operator!= (const iterator&) {return value() != nullptr;}
inline bool operator!= (const iterator&) const {return value() != nullptr;}
inline Value operator[] (unsigned n) const {return FLArrayIterator_GetValueAt(this,n);}
private:
iterator() =default;
Expand Down Expand Up @@ -186,7 +184,6 @@ namespace fleece {
inline Value operator[] (const char *key) const {return get(key);}
inline Value operator[] (const KeyPath &kp) const {return Value::operator[](kp);}

Dict& operator= (Dict d) & {_val = d._val; return *this;}
Dict& operator= (std::nullptr_t) & {_val = nullptr; return *this;}
Value& operator= (Value v) =delete;

Expand Down Expand Up @@ -260,8 +257,8 @@ namespace fleece {
KeyPath(slice_NONNULL spec, FLError* FL_NULLABLE err) :_path(FLKeyPath_New(spec, err)) { }
~KeyPath() {FLKeyPath_Free(_path);}

KeyPath(KeyPath &&kp) :_path(kp._path) {kp._path = nullptr;}
KeyPath& operator=(KeyPath &&kp) & {FLKeyPath_Free(_path); _path = kp._path;
KeyPath(KeyPath &&kp) noexcept :_path(kp._path) {kp._path = nullptr;}
KeyPath& operator=(KeyPath &&kp) & noexcept {FLKeyPath_Free(_path); _path = kp._path;
kp._path = nullptr; return *this;}

KeyPath(const KeyPath &kp) :KeyPath(std::string(kp), nullptr) { }
Expand Down Expand Up @@ -333,7 +330,7 @@ namespace fleece {
external pointers to. */
class Doc {
public:
Doc(alloc_slice fleeceData,
Doc(const alloc_slice& fleeceData,
FLTrust trust =kFLUntrusted,
FLSharedKeys FL_NULLABLE sk =nullptr,
slice externDest =nullslice) noexcept
Expand Down Expand Up @@ -414,7 +411,7 @@ namespace fleece {
explicit Encoder(FLSharedKeys FL_NULLABLE sk) :Encoder() {setSharedKeys(sk);}

explicit Encoder(FLEncoder enc) :_enc(enc) { }
Encoder(Encoder&& enc) :_enc(enc._enc) {enc._enc = nullptr;}
Encoder(Encoder&& enc) noexcept :_enc(enc._enc) {enc._enc = nullptr;}

void detach() {_enc = nullptr;}

Expand All @@ -433,7 +430,7 @@ namespace fleece {
inline bool writeDouble(double);
inline bool writeString(slice);
inline bool writeString(const char *s) {return writeString(slice(s));}
inline bool writeString(std::string s) {return writeString(slice(s));}
inline bool writeString(const std::string& s) {return writeString(slice(s));}
inline bool writeDateString(FLTimestamp, bool asUTC =true);
inline bool writeData(slice);
inline bool writeValue(Value);
Expand Down Expand Up @@ -528,6 +525,10 @@ namespace fleece {

//====== IMPLEMENTATION GUNK:

static_assert(std::is_trivially_copyable_v<Value>);
static_assert(std::is_trivially_copyable_v<Array>);
static_assert(std::is_trivially_copyable_v<Dict>);

inline FLValueType Value::type() const {return FLValue_GetType(_val);}
inline bool Value::isInteger() const {return FLValue_IsInteger(_val);}
inline bool Value::isUnsigned() const {return FLValue_IsUnsigned(_val);}
Expand Down

0 comments on commit 75a30c8

Please sign in to comment.