diff --git a/sprout/optional.hpp b/sprout/optional.hpp index b4669d6a..3b548a5d 100644 --- a/sprout/optional.hpp +++ b/sprout/optional.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include diff --git a/sprout/optional/comparison.hpp b/sprout/optional/comparison.hpp index 5bff3974..e4efa827 100644 --- a/sprout/optional/comparison.hpp +++ b/sprout/optional/comparison.hpp @@ -2,8 +2,9 @@ #define SPROUT_OPTIONAL_COMPARISON_HPP #include -#include #include +#include +#include namespace sprout { // @@ -44,6 +45,75 @@ namespace sprout { operator>=(sprout::optional const& lhs, sprout::optional const& rhs) { return !(lhs < rhs); } + + // + // operator== + // operator!= + // operator< + // operator> + // operator<= + // operator>= + // + template + inline SPROUT_CONSTEXPR bool + operator==(sprout::optional const& lhs, sprout::nullopt_t) SPROUT_NOEXCEPT { + return !lhs; + } + template + inline SPROUT_CONSTEXPR bool + operator==(sprout::nullopt_t, sprout::optional const& rhs) SPROUT_NOEXCEPT { + return !rhs; + } + template + inline SPROUT_CONSTEXPR bool + operator!=(sprout::optional const& lhs, sprout::nullopt_t) SPROUT_NOEXCEPT { + return bool(lhs); + } + template + inline SPROUT_CONSTEXPR bool + operator!=(sprout::nullopt_t, sprout::optional const& rhs) SPROUT_NOEXCEPT { + return bool(rhs); + } + template + inline SPROUT_CONSTEXPR bool + operator<(sprout::optional const& lhs, sprout::nullopt_t) SPROUT_NOEXCEPT { + return false; + } + template + inline SPROUT_CONSTEXPR bool + operator<(sprout::nullopt_t, sprout::optional const& rhs) SPROUT_NOEXCEPT { + return bool(rhs); + } + template + inline SPROUT_CONSTEXPR bool + operator>(sprout::optional const& lhs, sprout::nullopt_t) SPROUT_NOEXCEPT { + return bool(lhs); + } + template + inline SPROUT_CONSTEXPR bool + operator>(sprout::nullopt_t, sprout::optional const& rhs) SPROUT_NOEXCEPT { + return false; + } + template + inline SPROUT_CONSTEXPR bool + operator<=(sprout::optional const& lhs, sprout::nullopt_t) SPROUT_NOEXCEPT { + return !lhs; + } + template + inline SPROUT_CONSTEXPR bool + operator<=(sprout::nullopt_t, sprout::optional const& rhs) SPROUT_NOEXCEPT { + return true; + } + template + inline SPROUT_CONSTEXPR bool + operator>=(sprout::optional const& lhs, sprout::nullopt_t) SPROUT_NOEXCEPT { + return true; + } + template + inline SPROUT_CONSTEXPR bool + operator>=(sprout::nullopt_t, sprout::optional const& rhs) SPROUT_NOEXCEPT { + return !rhs; + } } // namespace sprout #endif // #ifndef SPROUT_OPTIONAL_COMPARISON_HPP diff --git a/sprout/optional/nullopt.hpp b/sprout/optional/nullopt.hpp new file mode 100644 index 00000000..82dc2063 --- /dev/null +++ b/sprout/optional/nullopt.hpp @@ -0,0 +1,18 @@ +#ifndef SPROUT_OPTIONAL_NULLOPT_HPP +#define SPROUT_OPTIONAL_NULLOPT_HPP + +#include +#include + +namespace sprout { + // + // none_t + // none + // + typedef sprout::none_t nullopt_t; + namespace { + SPROUT_STATIC_CONSTEXPR nullopt_t nullopt{}; + } // anonymous-namespace +} // namespace sprout + +#endif // #ifndef SPROUT_OPTIONAL_NULLOPT_HPP diff --git a/sprout/optional/optional.hpp b/sprout/optional/optional.hpp index 4b6af3d6..952c60ac 100644 --- a/sprout/optional/optional.hpp +++ b/sprout/optional/optional.hpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace sprout { // @@ -29,38 +30,38 @@ namespace sprout { typedef typename holder_type::pointer_const_type pointer_const_type; typedef typename holder_type::argument_type argument_type; private: - bool initialized_; - holder_type storage_; + bool init; + holder_type val; private: - void destroy() { - initialized_ = false; + void destroy() SPROUT_NOEXCEPT { + init = false; } public: - SPROUT_CONSTEXPR optional() - : initialized_(false) + SPROUT_CONSTEXPR optional() SPROUT_NOEXCEPT + : init(false) {} - SPROUT_CONSTEXPR optional(sprout::none_t) - : initialized_(false) + SPROUT_CONSTEXPR optional(sprout::nullopt_t) SPROUT_NOEXCEPT + : init(false) {} SPROUT_CONSTEXPR optional(argument_type v) - : initialized_(true) - , storage_(v) + : init(true) + , val(v) {} SPROUT_CONSTEXPR optional(bool cond, argument_type v) - : initialized_(cond) - , storage_(cond ? holder_type(v) : holder_type()) + : init(cond) + , val(cond ? holder_type(v) : holder_type()) {} SPROUT_CONSTEXPR optional(optional const& v) - : initialized_(v.initialized_) - , storage_(v.storage_) + : init(v.init) + , val(v.val) {} template explicit SPROUT_CONSTEXPR optional(optional const& v) - : initialized_(v.initialized_) - , storage_(v.storage_.get()) + : init(v.init) + , val(v.val.get()) {} - optional& operator=(sprout::none_t v) { + optional& operator=(sprout::nullopt_t v) SPROUT_NOEXCEPT { assign(v); return *this; } @@ -78,7 +79,7 @@ namespace sprout { return *this; } - void assign(sprout::none_t) { + void assign(sprout::nullopt_t) SPROUT_NOEXCEPT { destroy(); } void assign(argument_type v) { @@ -95,10 +96,10 @@ namespace sprout { temp.swap(v); } - void reset() { + void reset() SPROUT_NOEXCEPT { destroy(); } - void reset(sprout::none_t v) { + void reset(sprout::nullopt_t v) SPROUT_NOEXCEPT { assign(v); } void reset(argument_type v) { @@ -106,50 +107,50 @@ namespace sprout { } void swap(optional& other) - SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::swap(storage_, other.storage_))) + SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::swap(val, other.val))) { - sprout::swap(initialized_, other.initialized_); - sprout::swap(storage_, other.storage_); + sprout::swap(init, other.init); + sprout::swap(val, other.val); } SPROUT_CONSTEXPR reference_const_type get() const { - return is_initialized() ? storage_.get() + return is_initialized() ? val.get() : throw std::domain_error("optional: value not initialized") ; } reference_type get() { - return is_initialized() ? storage_.get() + return is_initialized() ? val.get() : throw std::domain_error("optional: value not initialized") ; } SPROUT_CONSTEXPR reference_const_type get_value_or(reference_const_type& v) const { - return is_initialized() ? storage_.get() + return is_initialized() ? val.get() : v ; } reference_type get_value_or(reference_type& v) { - return is_initialized() ? storage_.get() + return is_initialized() ? val.get() : v ; } SPROUT_CONSTEXPR pointer_const_type operator->() const { - return is_initialized() ? storage_.get_pointer() + return is_initialized() ? val.get_pointer() : throw std::domain_error("optional: value not initialized") ; } pointer_type operator->() { - return is_initialized() ? storage_.get_pointer() + return is_initialized() ? val.get_pointer() : throw std::domain_error("optional: value not initialized") ; } SPROUT_CONSTEXPR pointer_const_type get_pointer() const { - return is_initialized() ? storage_.get_pointer() + return is_initialized() ? val.get_pointer() : throw std::domain_error("optional: value not initialized") ; } pointer_type get_pointer() { - return is_initialized() ? storage_.get_pointer() + return is_initialized() ? val.get_pointer() : throw std::domain_error("optional: value not initialized") ; } @@ -160,14 +161,14 @@ namespace sprout { return get_pointer(); } - SPROUT_CONSTEXPR operator bool() const { + SPROUT_CONSTEXPR operator bool() const SPROUT_NOEXCEPT { return is_initialized(); } - SPROUT_CONSTEXPR bool operator!() const { + SPROUT_CONSTEXPR bool operator!() const SPROUT_NOEXCEPT { return !is_initialized(); } - SPROUT_CONSTEXPR bool is_initialized() const { - return initialized_; + SPROUT_CONSTEXPR bool is_initialized() const SPROUT_NOEXCEPT { + return init; } }; @@ -184,4 +185,3 @@ namespace sprout { } // namespace sprout #endif // #ifndef SPROUT_OPTIONAL_OPTIONAL_HPP -#include \ No newline at end of file diff --git a/sprout/utility/value_holder/value_holder.hpp b/sprout/utility/value_holder/value_holder.hpp index d9b9cdd0..3efb3ab7 100644 --- a/sprout/utility/value_holder/value_holder.hpp +++ b/sprout/utility/value_holder/value_holder.hpp @@ -19,7 +19,7 @@ namespace sprout { typedef T const& param_type; typedef T holder_type; public: - static SPROUT_CONSTEXPR holder_type const& hold(param_type p) { + static SPROUT_CONSTEXPR holder_type const& hold(param_type p) SPROUT_NOEXCEPT { return p; } static SPROUT_CONSTEXPR reference ref(holder_type& r) { @@ -28,10 +28,10 @@ namespace sprout { static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) { return r; } - static SPROUT_CONSTEXPR pointer ptr(holder_type& r) { + static SPROUT_CONSTEXPR pointer ptr(holder_type& r) SPROUT_NOEXCEPT { return &r; } - static SPROUT_CONSTEXPR const_pointer ptr(holder_type const& r) { + static SPROUT_CONSTEXPR const_pointer ptr(holder_type const& r) SPROUT_NOEXCEPT { return &r; } }; @@ -48,7 +48,7 @@ namespace sprout { typedef T const& param_type; typedef T holder_type; public: - static SPROUT_CONSTEXPR holder_type const& hold(param_type p) { + static SPROUT_CONSTEXPR holder_type const& hold(param_type p) SPROUT_NOEXCEPT { return &p; } static SPROUT_CONSTEXPR reference ref(holder_type& r) { @@ -57,10 +57,10 @@ namespace sprout { static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) { return *r; } - static SPROUT_CONSTEXPR pointer ptr(holder_type& r) { + static SPROUT_CONSTEXPR pointer ptr(holder_type& r) SPROUT_NOEXCEPT { return &r; } - static SPROUT_CONSTEXPR const_pointer ptr(holder_type const& r) { + static SPROUT_CONSTEXPR const_pointer ptr(holder_type const& r) SPROUT_NOEXCEPT { return &r; } }; @@ -77,13 +77,13 @@ namespace sprout { typedef T& param_type; typedef T* holder_type; public: - static SPROUT_CONSTEXPR holder_type hold(param_type p) { + static SPROUT_CONSTEXPR holder_type hold(param_type p) SPROUT_NOEXCEPT { return &p; } static SPROUT_CONSTEXPR reference ref(holder_type r) { return *r; } - static SPROUT_CONSTEXPR pointer ptr(holder_type r) { + static SPROUT_CONSTEXPR pointer ptr(holder_type r) SPROUT_NOEXCEPT { return r; } }; @@ -100,13 +100,13 @@ namespace sprout { typedef T const& param_type; typedef T const* holder_type; public: - static SPROUT_CONSTEXPR holder_type hold(param_type p) { + static SPROUT_CONSTEXPR holder_type hold(param_type p) SPROUT_NOEXCEPT { return &p; } static SPROUT_CONSTEXPR reference ref(holder_type r) { return *r; } - static SPROUT_CONSTEXPR pointer ptr(holder_type r) { + static SPROUT_CONSTEXPR pointer ptr(holder_type r) SPROUT_NOEXCEPT { return r; } }; @@ -176,22 +176,22 @@ namespace sprout { return helper_type::ref(holder_); } - pointer operator->() { + pointer operator->() SPROUT_NOEXCEPT { return helper_type::ptr(holder_); } - SPROUT_CONSTEXPR mutable_or_const_pointer operator->() const { + SPROUT_CONSTEXPR mutable_or_const_pointer operator->() const SPROUT_NOEXCEPT { return helper_type::ptr(holder_); } - pointer get_pointer() { + pointer get_pointer() SPROUT_NOEXCEPT { return helper_type::ptr(holder_); } - SPROUT_CONSTEXPR mutable_or_const_pointer get_pointer() const { + SPROUT_CONSTEXPR mutable_or_const_pointer get_pointer() const SPROUT_NOEXCEPT { return helper_type::ptr(holder_); } - pointer get_ptr() { + pointer get_ptr() SPROUT_NOEXCEPT { return get_pointer(); } - SPROUT_CONSTEXPR mutable_or_const_pointer get_ptr() const { + SPROUT_CONSTEXPR mutable_or_const_pointer get_ptr() const SPROUT_NOEXCEPT { return get_pointer(); } };