// ********************************************************************** // // Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. // // This copy of Ice is licensed to you under the terms described in the // ICE_LICENSE file included in this distribution. // // ********************************************************************** #ifndef ICE_UTIL_OPTIONAL_H #define ICE_UTIL_OPTIONAL_H #include namespace IceUtilInternal { struct NoneType { }; } namespace IceUtil { const IceUtilInternal::NoneType None = {}; template class Optional { public: typedef T element_type; Optional() : _isSet(false) { } Optional(IceUtilInternal::NoneType) : _isSet(false) { } template Optional(Y p) : _value(p), _isSet(true) { } template Optional(const Optional& r) : _value(r._value), _isSet(r._isSet) { } ~Optional() { } Optional& operator=(IceUtilInternal::NoneType) { _value = T(); _isSet = false; return *this; } template Optional& operator=(Y p) { _value = p; _isSet = true; return *this; } template Optional& operator=(const Optional& r) { _value = r._value; _isSet = r._isSet; return *this; } Optional& operator=(const Optional& r) { _value = r._value; _isSet = r._isSet; return *this; } const T& get() const { checkIsSet(); return _value; } T& get() { checkIsSet(); return _value; } const T* operator->() const { return &get(); } T* operator->() { return &get(); } const T& operator*() const { return get(); } T& operator*() { return get(); } operator bool() const { return _isSet; } bool operator!() const { return !_isSet; } void swap(Optional& other) { std::swap(_isSet, other._isSet); std::swap(_value, other._value); } void __setIsSet() { _isSet = true; } private: void checkIsSet() const { if(!_isSet) { throwOptionalNotSetException(__FILE__, __LINE__); } } void throwOptionalNotSetException(const char *, int) const; T _value; bool _isSet; }; template inline Optional makeOptional(const T& v) { return Optional(v); } template inline void Optional::throwOptionalNotSetException(const char* file, int line) const { throw OptionalNotSetException(file, line); } template inline bool operator==(const Optional& lhs, const Optional& rhs) { if(lhs && rhs) { return *lhs == *rhs; } else { return !lhs && !rhs; } } template inline bool operator!=(const Optional& lhs, const Optional& rhs) { return !operator==(lhs, rhs); } template inline bool operator<(const Optional& lhs, const Optional& rhs) { if(lhs && rhs) { return *lhs < *rhs; } else { return !lhs && rhs; } } template inline bool operator<=(const Optional& lhs, const Optional& rhs) { return lhs < rhs || lhs == rhs; } template inline bool operator>(const Optional& lhs, const Optional& rhs) { return !(lhs < rhs || lhs == rhs); } template inline bool operator>=(const Optional& lhs, const Optional& rhs) { return !(lhs < rhs); } // Optional vs Y template inline bool operator==(const Optional& lhs, const Y& rhs) { if(!lhs) { return false; } else { return *lhs == rhs; } } template inline bool operator!=(const Optional& lhs, const Y& rhs) { return !operator==(lhs, rhs); } template inline bool operator<(const Optional& lhs, const Y& rhs) { if(lhs) { return *lhs < rhs; } else { return true; } } template inline bool operator<=(const Optional& lhs, const Y& rhs) { return lhs < rhs || lhs == rhs; } template inline bool operator>(const Optional& lhs, const Y& rhs) { return !(lhs < rhs || lhs == rhs); } template inline bool operator>=(const Optional& lhs, const Y& rhs) { return !(lhs < rhs); } // Y vs Optional template inline bool operator==(const Y& lhs, const Optional& rhs) { if(!rhs) { return false; } else { return lhs == *rhs; } } template inline bool operator!=(const Y& lhs, const Optional& rhs) { return !operator==(lhs, rhs); } template inline bool operator<(const Y& lhs, const Optional& rhs) { if(rhs) { return lhs < *rhs; } else { return false; } } template inline bool operator<=(const Y& lhs, const Optional& rhs) { return lhs < rhs || lhs == rhs; } template inline bool operator>(const Y& lhs, const Optional& rhs) { return !(lhs < rhs || lhs == rhs); } template inline bool operator>=(const Y& lhs, const Optional& rhs) { return !(lhs < rhs); } } #endif