From fea03e59c2570baaaef6dfaf01cd3ee095402e1e Mon Sep 17 00:00:00 2001 From: Michał Cichoń Date: Sat, 5 Dec 2015 14:27:47 +0100 Subject: Add player based on Windows Media Foundation. --- src/player/backends/utility/optional.h | 517 +++++++++++++++++++++++++++++++++ 1 file changed, 517 insertions(+) create mode 100644 src/player/backends/utility/optional.h (limited to 'src/player/backends/utility/optional.h') diff --git a/src/player/backends/utility/optional.h b/src/player/backends/utility/optional.h new file mode 100644 index 0000000..9ee0b71 --- /dev/null +++ b/src/player/backends/utility/optional.h @@ -0,0 +1,517 @@ +//------------------------------------------------------------------------------ +// +//------------------------------------------------------------------------------ +# ifndef __TD__OPTIONAL_H__ +# define __TD__OPTIONAL_H__ +# pragma once + +# include +# include +# include + + +//------------------------------------------------------------------------------ +struct nullopt_t +{ + struct init {}; + nullopt_t(init) {} +}; + +const nullopt_t nullopt((nullopt_t::init())); + +template +struct optional +{ +private: + typedef typename std::aligned_storage::value>::type storage_type; + + typedef void (optional::*bool_type)() const; + void safe_bool() const { } + + +public: + optional(); + optional(nullopt_t); + optional(const optional& v); + optional(optional&& v); + optional(const T& v); + optional(T&& v); + ~optional(); + + operator bool_type() const; + + optional& operator=(nullopt_t); + + optional& operator=(const optional& other); + optional& operator=(optional&& other); + + // The function does not participate in overload resolution unless std::is_same, T>::value is true + template + // optional& operator=(U&& value); + optional& operator=(typename std::enable_if::type, T>::value, U>::type&& value); + + T* operator->(); + const T* operator->() const; + T& operator*(); + const T& operator*() const; + + T& value(); + const T& value() const; + +# if defined(_MSC_VER) && (_MSC_VER > 1600) + template + T value_or(U&& default_value) const &; + + template + T value_or(U&& default_value) &&; +# else + T value_or(const T& default_value); + T value_or(const T& default_value) const; +# endif + + bool has_value() const; + + void swap(optional& other); + +private: + T* value_ptr() { return reinterpret_cast< T*>(&_value); } + const T* value_ptr() const { return reinterpret_cast(&_value); } + + T& value_ref() { return *value_ptr(); } + const T& value_ref() const { return *value_ptr(); } + + bool _has_value; + storage_type _value; +# if defined(_DEBUG) + const T& _preview; +# endif +}; + + +//------------------------------------------------------------------------------ +template +inline optional::optional(): + _has_value(false) +# if defined(_DEBUG) + ,_preview(value_ref()) +# endif +{ +} + +template +inline optional::optional(nullopt_t): + _has_value(false) +# if defined(_DEBUG) + , _preview(value_ref()) +# endif +{ +} + +template +inline optional::optional(const optional& v): + _has_value(v._has_value) +# if defined(_DEBUG) + , _preview(value_ref()) +# endif +{ + if (_has_value) + new (value_ptr()) T(v.value_ref()); +} + +template +inline optional::optional(optional&& v): + _has_value(v._has_value) +# if defined(_DEBUG) + , _preview(value_ref()) +# endif +{ + if (!_has_value) + return; + + new (value_ptr()) T(std::move(v.value_ref())); + v.value_ref().~T(); + + v._has_value = false; +} + +template +inline optional::optional(const T& v): + _has_value(true) +# if defined(_DEBUG) + , _preview(value_ref()) +# endif +{ + new (value_ptr()) T(v); +} + +template +inline optional::optional(T&& v): + _has_value(true) +# if defined(_DEBUG) + , _preview(value_ref()) +# endif +{ + new (value_ptr()) T(std::forward(v)); +} + +template +inline optional::~optional() +{ + if (_has_value) + value_ref().~T(); +} + +template +inline optional::operator bool_type() const +{ + return _has_value ? &optional::safe_bool : nullptr; +} + +template +inline optional& optional::operator= (nullopt_t) +{ + optional().swap(*this); + _has_value = false; + return *this; +} + +template +inline optional& optional::operator=(const optional& other) +{ + optional(other).swap(*this); + return *this; +} + +template +inline optional& optional::operator=(optional&& other) +{ + optional(std::forward(other)).swap(*this); + return *this; +} + +template +template +inline optional& optional::operator=(typename std::enable_if::type, T>::value, U>::type&& value) +{ + optional(value).swap(*this); + return *this; +} + + +template +inline T* optional::operator->() +{ + assert(_has_value); + return value_ptr(); +} + +template +inline const T* optional::operator->() const +{ + assert(_has_value); + return value_ptr(); +} + +template +inline T& optional::operator*() +{ + assert(_has_value); + return value_ref(); +} + +template +inline const T& optional::operator*() const +{ + assert(_has_value); + return value_ref(); +} + +template +inline T& optional::value() +{ + assert(_has_value); + return value_ref(); +} + +template +inline const T& optional::value() const +{ + assert(_has_value); + return value_ref(); +} + +# if defined(_MSC_VER) && (_MSC_VER > 1600) +template +template +inline T optional::value_or(U&& default_value) const & +{ + return bool(*this) ? value_ref() : static_cast(std::forward(default_value)); +} + +template +template +inline T optional::value_or(U&& default_value) && +{ + return bool(*this) ? std::move(value_ref()) : static_cast(std::forward(default_value)); +} +# else +template +T optional::value_or(const T& default_value) +{ + return _has_value ? value_ref() : default_value; +} + +template +T optional::value_or(const T& default_value) const +{ + return _has_value ? value_ref() : default_value; +} +# endif + +template +inline bool optional::has_value() const +{ + return _has_value; +} + +template +inline void optional::swap(optional& other) +{ + using std::swap; + + if (_has_value && other._has_value) + { + swap(value_ref(), other.value_ref()); + } + else if (_has_value && !other._has_value) + { + new (other.value_ptr()) T(std::forward(value_ref())); + + value_ref().~T(); + + _has_value = false; + other._has_value = true; + } + else if (!_has_value && other._has_value) + { + new (value_ptr()) T(std::forward(other.value_ref())); + + other.value_ref().~T(); + + _has_value = true; + other._has_value = false; + } +} + + +//------------------------------------------------------------------------------ +template +optional make_optional(T&& v) +{ + return optional(std::forward(v)); +} + +template +inline void swap(optional& lhs, optional& rhs) +{ + lhs.swap(rhs); +} + +template +inline bool operator==(const optional& lhs, const optional& rhs) +{ + if (static_cast(lhs) != static_cast(rhs)) + return false; + if (!static_cast(lhs)) + return true; + return *lhs == *rhs; +} + +template +bool operator!=(const optional& lhs, const optional& rhs) +{ + return !(lhs == rhs); +} + +template +inline bool operator<(const optional& lhs, const optional& rhs) +{ + if (!static_cast(rhs)) + return false; + if (!static_cast(lhs)) + return true; + return *lhs < *rhs; +} + +template +inline bool operator>(const optional& lhs, const optional& rhs) +{ + return rhs < lhs; +} + +template +inline bool operator<=(const optional& lhs, const optional& rhs) +{ + return !(rhs < lhs); +} + +template +inline bool operator>=(const optional& lhs, const optional& rhs) +{ + return !(lhs < rhs); +} + +template +inline bool operator==(const optional& opt, nullopt_t) +{ + return !static_cast(opt); +} + +template +inline bool operator==(nullopt_t, const optional& opt) +{ + return static_cast(opt); +} + +template +inline bool operator!=(const optional& opt, nullopt_t) +{ + return static_cast(opt); +} + +template +inline bool operator!=(nullopt_t, const optional& opt) +{ + return !static_cast(opt); +} + +template +inline bool operator<(const optional& opt, nullopt_t) +{ + return false; +} + +template +inline bool operator<(nullopt_t, const optional& opt) +{ + return static_cast(opt); +} + +template +inline bool operator<=(const optional& opt, nullopt_t) +{ + return !opt; +} + +template +inline bool operator<=(nullopt_t, const optional& opt) +{ + return true; +} + +template +inline bool operator>(const optional& opt, nullopt_t) +{ + return static_cast(opt); +} + +template +inline bool operator>(nullopt_t, const optional& opt) +{ + return false; +} + +template +inline bool operator>=(const optional&, nullopt_t) +{ + return true; +} + +template +inline bool operator>=(nullopt_t, const optional& opt) +{ + return !opt; +} + +template +inline bool operator==(const optional& opt, const T& v) +{ + return static_cast(opt) ? *opt == v : false; +} + +template +inline bool operator==(const T& v, const optional& opt) +{ + return static_cast(opt) ? *opt == v : false; +} + +template +inline bool operator!=(const optional& opt, const T& v) +{ + return static_cast(opt) ? *opt != v : true; +} + +template +inline bool operator!=(const T& v, const optional& opt) +{ + return static_cast(opt) ? *opt != v : true; +} + +template +inline bool operator<(const optional& opt, const T& v) +{ + using namespace std; + return static_cast(opt) ? less(*opt, v) : true; +} + +template +inline bool operator<(const T& v, const optional& opt) +{ + using namespace std; + return static_cast(opt) ? less(v, *opt) : false; +} + +template +inline bool operator<=(const optional& opt, const T& v) +{ + using namespace std; + return static_cast(opt) ? less_equal(*opt, v) : true; +} + +template +inline bool operator<=(const T& v, const optional& opt) +{ + using namespace std; + return static_cast(opt) ? less_equal(v, *opt) : false; +} + +template +inline bool operator>(const optional& opt, const T& v) +{ + using namespace std; + return static_cast(opt) ? greater(*opt, v) : false; +} + +template +inline bool operator>(const T& v, const optional& opt) +{ + using namespace std; + return static_cast(opt) ? greater(v, *opt) : true; +} + +template +inline bool operator>=(const optional& opt, const T& v) +{ + using namespace std; + return static_cast(opt) ? greater_equal(*opt, v) : false; +} + +template +inline bool operator>=(const T& v, const optional& opt) +{ + using namespace std; + return static_cast(opt) ? greater_equal(v, *opt) : true; +} + + +# endif // __TD__OPTIONAL_H__ -- cgit v1.2.3