1
0
Fork 0
mirror of https://github.com/bolero-MURAKAMI/Sprout synced 2025-08-03 12:49:50 +00:00

fix optional

This commit is contained in:
bolero-MURAKAMI 2012-10-26 17:38:48 +09:00
parent c8e2514d36
commit f9d8908f95
5 changed files with 142 additions and 53 deletions

View file

@ -5,6 +5,7 @@
#include <sprout/optional/optional.hpp> #include <sprout/optional/optional.hpp>
#include <sprout/optional/comparison.hpp> #include <sprout/optional/comparison.hpp>
#include <sprout/optional/io.hpp> #include <sprout/optional/io.hpp>
#include <sprout/optional/nullopt.hpp>
#include <sprout/optional/make_optional.hpp> #include <sprout/optional/make_optional.hpp>
#include <sprout/optional/get.hpp> #include <sprout/optional/get.hpp>

View file

@ -2,8 +2,9 @@
#define SPROUT_OPTIONAL_COMPARISON_HPP #define SPROUT_OPTIONAL_COMPARISON_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/optional/optional.hpp>
#include <sprout/utility/compare_pointees.hpp> #include <sprout/utility/compare_pointees.hpp>
#include <sprout/optional/optional.hpp>
#include <sprout/optional/nullopt.hpp>
namespace sprout { namespace sprout {
// //
@ -44,6 +45,75 @@ namespace sprout {
operator>=(sprout::optional<T> const& lhs, sprout::optional<T> const& rhs) { operator>=(sprout::optional<T> const& lhs, sprout::optional<T> const& rhs) {
return !(lhs < rhs); return !(lhs < rhs);
} }
//
// operator==
// operator!=
// operator<
// operator>
// operator<=
// operator>=
//
template<typename T>
inline SPROUT_CONSTEXPR bool
operator==(sprout::optional<T> const& lhs, sprout::nullopt_t) SPROUT_NOEXCEPT {
return !lhs;
}
template<typename T>
inline SPROUT_CONSTEXPR bool
operator==(sprout::nullopt_t, sprout::optional<T> const& rhs) SPROUT_NOEXCEPT {
return !rhs;
}
template<typename T>
inline SPROUT_CONSTEXPR bool
operator!=(sprout::optional<T> const& lhs, sprout::nullopt_t) SPROUT_NOEXCEPT {
return bool(lhs);
}
template<typename T>
inline SPROUT_CONSTEXPR bool
operator!=(sprout::nullopt_t, sprout::optional<T> const& rhs) SPROUT_NOEXCEPT {
return bool(rhs);
}
template<typename T>
inline SPROUT_CONSTEXPR bool
operator<(sprout::optional<T> const& lhs, sprout::nullopt_t) SPROUT_NOEXCEPT {
return false;
}
template<typename T>
inline SPROUT_CONSTEXPR bool
operator<(sprout::nullopt_t, sprout::optional<T> const& rhs) SPROUT_NOEXCEPT {
return bool(rhs);
}
template<typename T>
inline SPROUT_CONSTEXPR bool
operator>(sprout::optional<T> const& lhs, sprout::nullopt_t) SPROUT_NOEXCEPT {
return bool(lhs);
}
template<typename T>
inline SPROUT_CONSTEXPR bool
operator>(sprout::nullopt_t, sprout::optional<T> const& rhs) SPROUT_NOEXCEPT {
return false;
}
template<typename T>
inline SPROUT_CONSTEXPR bool
operator<=(sprout::optional<T> const& lhs, sprout::nullopt_t) SPROUT_NOEXCEPT {
return !lhs;
}
template<typename T>
inline SPROUT_CONSTEXPR bool
operator<=(sprout::nullopt_t, sprout::optional<T> const& rhs) SPROUT_NOEXCEPT {
return true;
}
template<typename T>
inline SPROUT_CONSTEXPR bool
operator>=(sprout::optional<T> const& lhs, sprout::nullopt_t) SPROUT_NOEXCEPT {
return true;
}
template<typename T>
inline SPROUT_CONSTEXPR bool
operator>=(sprout::nullopt_t, sprout::optional<T> const& rhs) SPROUT_NOEXCEPT {
return !rhs;
}
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_OPTIONAL_COMPARISON_HPP #endif // #ifndef SPROUT_OPTIONAL_COMPARISON_HPP

View file

@ -0,0 +1,18 @@
#ifndef SPROUT_OPTIONAL_NULLOPT_HPP
#define SPROUT_OPTIONAL_NULLOPT_HPP
#include <sprout/config.hpp>
#include <sprout/none.hpp>
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

View file

@ -6,6 +6,7 @@
#include <sprout/utility/value_holder.hpp> #include <sprout/utility/value_holder.hpp>
#include <sprout/utility/swap.hpp> #include <sprout/utility/swap.hpp>
#include <sprout/none.hpp> #include <sprout/none.hpp>
#include <sprout/optional/nullopt.hpp>
namespace sprout { namespace sprout {
// //
@ -29,38 +30,38 @@ namespace sprout {
typedef typename holder_type::pointer_const_type pointer_const_type; typedef typename holder_type::pointer_const_type pointer_const_type;
typedef typename holder_type::argument_type argument_type; typedef typename holder_type::argument_type argument_type;
private: private:
bool initialized_; bool init;
holder_type storage_; holder_type val;
private: private:
void destroy() { void destroy() SPROUT_NOEXCEPT {
initialized_ = false; init = false;
} }
public: public:
SPROUT_CONSTEXPR optional() SPROUT_CONSTEXPR optional() SPROUT_NOEXCEPT
: initialized_(false) : init(false)
{} {}
SPROUT_CONSTEXPR optional(sprout::none_t) SPROUT_CONSTEXPR optional(sprout::nullopt_t) SPROUT_NOEXCEPT
: initialized_(false) : init(false)
{} {}
SPROUT_CONSTEXPR optional(argument_type v) SPROUT_CONSTEXPR optional(argument_type v)
: initialized_(true) : init(true)
, storage_(v) , val(v)
{} {}
SPROUT_CONSTEXPR optional(bool cond, argument_type v) SPROUT_CONSTEXPR optional(bool cond, argument_type v)
: initialized_(cond) : init(cond)
, storage_(cond ? holder_type(v) : holder_type()) , val(cond ? holder_type(v) : holder_type())
{} {}
SPROUT_CONSTEXPR optional(optional const& v) SPROUT_CONSTEXPR optional(optional const& v)
: initialized_(v.initialized_) : init(v.init)
, storage_(v.storage_) , val(v.val)
{} {}
template<class U> template<class U>
explicit SPROUT_CONSTEXPR optional(optional<U> const& v) explicit SPROUT_CONSTEXPR optional(optional<U> const& v)
: initialized_(v.initialized_) : init(v.init)
, storage_(v.storage_.get()) , val(v.val.get())
{} {}
optional& operator=(sprout::none_t v) { optional& operator=(sprout::nullopt_t v) SPROUT_NOEXCEPT {
assign(v); assign(v);
return *this; return *this;
} }
@ -78,7 +79,7 @@ namespace sprout {
return *this; return *this;
} }
void assign(sprout::none_t) { void assign(sprout::nullopt_t) SPROUT_NOEXCEPT {
destroy(); destroy();
} }
void assign(argument_type v) { void assign(argument_type v) {
@ -95,10 +96,10 @@ namespace sprout {
temp.swap(v); temp.swap(v);
} }
void reset() { void reset() SPROUT_NOEXCEPT {
destroy(); destroy();
} }
void reset(sprout::none_t v) { void reset(sprout::nullopt_t v) SPROUT_NOEXCEPT {
assign(v); assign(v);
} }
void reset(argument_type v) { void reset(argument_type v) {
@ -106,50 +107,50 @@ namespace sprout {
} }
void swap(optional& other) 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(init, other.init);
sprout::swap(storage_, other.storage_); sprout::swap(val, other.val);
} }
SPROUT_CONSTEXPR reference_const_type get() const { 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") : throw std::domain_error("optional: value not initialized")
; ;
} }
reference_type get() { reference_type get() {
return is_initialized() ? storage_.get() return is_initialized() ? val.get()
: throw std::domain_error("optional: value not initialized") : throw std::domain_error("optional: value not initialized")
; ;
} }
SPROUT_CONSTEXPR reference_const_type get_value_or(reference_const_type& v) const { SPROUT_CONSTEXPR reference_const_type get_value_or(reference_const_type& v) const {
return is_initialized() ? storage_.get() return is_initialized() ? val.get()
: v : v
; ;
} }
reference_type get_value_or(reference_type& v) { reference_type get_value_or(reference_type& v) {
return is_initialized() ? storage_.get() return is_initialized() ? val.get()
: v : v
; ;
} }
SPROUT_CONSTEXPR pointer_const_type operator->() const { 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") : throw std::domain_error("optional: value not initialized")
; ;
} }
pointer_type operator->() { pointer_type operator->() {
return is_initialized() ? storage_.get_pointer() return is_initialized() ? val.get_pointer()
: throw std::domain_error("optional: value not initialized") : throw std::domain_error("optional: value not initialized")
; ;
} }
SPROUT_CONSTEXPR pointer_const_type get_pointer() const { 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") : throw std::domain_error("optional: value not initialized")
; ;
} }
pointer_type get_pointer() { pointer_type get_pointer() {
return is_initialized() ? storage_.get_pointer() return is_initialized() ? val.get_pointer()
: throw std::domain_error("optional: value not initialized") : throw std::domain_error("optional: value not initialized")
; ;
} }
@ -160,14 +161,14 @@ namespace sprout {
return get_pointer(); return get_pointer();
} }
SPROUT_CONSTEXPR operator bool() const { SPROUT_CONSTEXPR operator bool() const SPROUT_NOEXCEPT {
return is_initialized(); return is_initialized();
} }
SPROUT_CONSTEXPR bool operator!() const { SPROUT_CONSTEXPR bool operator!() const SPROUT_NOEXCEPT {
return !is_initialized(); return !is_initialized();
} }
SPROUT_CONSTEXPR bool is_initialized() const { SPROUT_CONSTEXPR bool is_initialized() const SPROUT_NOEXCEPT {
return initialized_; return init;
} }
}; };
@ -184,4 +185,3 @@ namespace sprout {
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_OPTIONAL_OPTIONAL_HPP #endif // #ifndef SPROUT_OPTIONAL_OPTIONAL_HPP
#include <boost/none.hpp>

View file

@ -19,7 +19,7 @@ namespace sprout {
typedef T const& param_type; typedef T const& param_type;
typedef T holder_type; typedef T holder_type;
public: 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; return p;
} }
static SPROUT_CONSTEXPR reference ref(holder_type& r) { static SPROUT_CONSTEXPR reference ref(holder_type& r) {
@ -28,10 +28,10 @@ namespace sprout {
static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) { static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) {
return r; return r;
} }
static SPROUT_CONSTEXPR pointer ptr(holder_type& r) { static SPROUT_CONSTEXPR pointer ptr(holder_type& r) SPROUT_NOEXCEPT {
return &r; 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; return &r;
} }
}; };
@ -48,7 +48,7 @@ namespace sprout {
typedef T const& param_type; typedef T const& param_type;
typedef T holder_type; typedef T holder_type;
public: 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; return &p;
} }
static SPROUT_CONSTEXPR reference ref(holder_type& r) { static SPROUT_CONSTEXPR reference ref(holder_type& r) {
@ -57,10 +57,10 @@ namespace sprout {
static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) { static SPROUT_CONSTEXPR const_reference ref(holder_type const& r) {
return *r; return *r;
} }
static SPROUT_CONSTEXPR pointer ptr(holder_type& r) { static SPROUT_CONSTEXPR pointer ptr(holder_type& r) SPROUT_NOEXCEPT {
return &r; 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; return &r;
} }
}; };
@ -77,13 +77,13 @@ namespace sprout {
typedef T& param_type; typedef T& param_type;
typedef T* holder_type; typedef T* holder_type;
public: public:
static SPROUT_CONSTEXPR holder_type hold(param_type p) { static SPROUT_CONSTEXPR holder_type hold(param_type p) SPROUT_NOEXCEPT {
return &p; return &p;
} }
static SPROUT_CONSTEXPR reference ref(holder_type r) { static SPROUT_CONSTEXPR reference ref(holder_type r) {
return *r; return *r;
} }
static SPROUT_CONSTEXPR pointer ptr(holder_type r) { static SPROUT_CONSTEXPR pointer ptr(holder_type r) SPROUT_NOEXCEPT {
return r; return r;
} }
}; };
@ -100,13 +100,13 @@ namespace sprout {
typedef T const& param_type; typedef T const& param_type;
typedef T const* holder_type; typedef T const* holder_type;
public: public:
static SPROUT_CONSTEXPR holder_type hold(param_type p) { static SPROUT_CONSTEXPR holder_type hold(param_type p) SPROUT_NOEXCEPT {
return &p; return &p;
} }
static SPROUT_CONSTEXPR reference ref(holder_type r) { static SPROUT_CONSTEXPR reference ref(holder_type r) {
return *r; return *r;
} }
static SPROUT_CONSTEXPR pointer ptr(holder_type r) { static SPROUT_CONSTEXPR pointer ptr(holder_type r) SPROUT_NOEXCEPT {
return r; return r;
} }
}; };
@ -176,22 +176,22 @@ namespace sprout {
return helper_type::ref(holder_); return helper_type::ref(holder_);
} }
pointer operator->() { pointer operator->() SPROUT_NOEXCEPT {
return helper_type::ptr(holder_); 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_); return helper_type::ptr(holder_);
} }
pointer get_pointer() { pointer get_pointer() SPROUT_NOEXCEPT {
return helper_type::ptr(holder_); 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_); return helper_type::ptr(holder_);
} }
pointer get_ptr() { pointer get_ptr() SPROUT_NOEXCEPT {
return get_pointer(); 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(); return get_pointer();
} }
}; };