#ifndef FILEZILLA_OPTIONAL_HEADER #define FILEZILLA_OPTIONAL_HEADER #include template class CSparseOptional final { // This class does what std::optional would do, if we had it. // Note that we do not perform "small object optimization" under the assumption // that in most cases the optional is not set. public: CSparseOptional(); explicit CSparseOptional(T const& v); CSparseOptional(CSparseOptional const& v); CSparseOptional(CSparseOptional && v) noexcept; ~CSparseOptional(); void clear(); explicit operator bool() const { return v_ != 0; }; T& operator*() { return *v_; } T const& operator*() const { return *v_; } T* operator->() { return v_; } T const* operator->() const { return v_; } bool operator==(CSparseOptional const& cmp) const; inline bool operator!=(CSparseOptional const& cmp) const { return !(*this == cmp); } bool operator<(CSparseOptional const& cmp) const; CSparseOptional& operator=(CSparseOptional const& v); CSparseOptional& operator=(CSparseOptional && v) noexcept; protected: T* v_; }; template CSparseOptional::CSparseOptional() : v_() { } template CSparseOptional::CSparseOptional(T const& v) : v_(new T(v)) { } template CSparseOptional::CSparseOptional(CSparseOptional const& v) { if( v ) { v_ = new T(*v); } else { v_ = 0; } } template CSparseOptional::CSparseOptional(CSparseOptional && v) noexcept { v_ = v.v_; v.v_ = 0; } template CSparseOptional::~CSparseOptional() { delete v_; } template void CSparseOptional::clear() { delete v_; v_ = 0; } template CSparseOptional& CSparseOptional::operator=(CSparseOptional const& v) { if( this != &v ) { delete v_; if( v.v_ ) { v_ = new T(*v.v_); } else { v_ = 0; } } return *this; } template CSparseOptional& CSparseOptional::operator=(CSparseOptional && v) noexcept { if( this != &v ) { delete v_; v_ = v.v_; v.v_ = 0; } return *this; } template bool CSparseOptional::operator==(CSparseOptional const& cmp) const { if( !v_ && !cmp.v_ ) { return true; } if( !v_ || !cmp.v_ ) { return false; } return *v_ == *cmp.v_; } template bool CSparseOptional::operator<(CSparseOptional const& cmp) const { if( !v_ || !cmp.v_ ) { return cmp.operator bool(); } return *v_ < *cmp.v_; } #endif