diff options
author | Michał Cichoń <michcic@gmail.com> | 2015-12-05 16:07:26 +0100 |
---|---|---|
committer | Michał Cichoń <michcic@gmail.com> | 2015-12-05 16:07:26 +0100 |
commit | 13e06e633d966a7600794deb43d725cbd89e108c (patch) | |
tree | 5285721085c225f1a547830471e3a628d0657565 /src/player/backends/utility | |
parent | d25764daa0c4c1e4a5887ca1599d4975a7a799c6 (diff) | |
parent | 864afb87798a0669f9a58aaebba5d874546acffe (diff) | |
download | pianobar-windows-13e06e633d966a7600794deb43d725cbd89e108c.tar.gz pianobar-windows-13e06e633d966a7600794deb43d725cbd89e108c.tar.bz2 pianobar-windows-13e06e633d966a7600794deb43d725cbd89e108c.zip |
Merge branch 'release/2015.12.05'2015.12.05
Diffstat (limited to 'src/player/backends/utility')
-rw-r--r-- | src/player/backends/utility/com_ptr.h | 148 | ||||
-rw-r--r-- | src/player/backends/utility/optional.h | 517 |
2 files changed, 665 insertions, 0 deletions
diff --git a/src/player/backends/utility/com_ptr.h b/src/player/backends/utility/com_ptr.h new file mode 100644 index 0000000..23534b2 --- /dev/null +++ b/src/player/backends/utility/com_ptr.h @@ -0,0 +1,148 @@ +# ifndef __TD__COM_PTR_H__ +# define __TD__COM_PTR_H__ +# pragma once + +template <typename T> +class com_ptr +{ +//private: +// typedef void (com_ptr::*bool_type)() const; +// void safe_bool() const {} +// +// +public: + com_ptr(): + _ptr(nullptr) + { + } + + com_ptr(T* ptr, bool add_ref = false): + _ptr(ptr) + { + if (_ptr && add_ref) + _ptr->AddRef(); + } + + com_ptr(const com_ptr& rhs): + _ptr(rhs._ptr) + { + if (_ptr) + _ptr->AddRef(); + } + + com_ptr(com_ptr&& rhs): + _ptr(rhs._ptr) + { + rhs._ptr = nullptr; + } + + template <typename U> + com_ptr(const com_ptr<U>& rhs): + _ptr(rhs._ptr) + { + if (_ptr) + _ptr->AddRef(); + } + + ~com_ptr() + { + if (_ptr) + _ptr->Release(); + } + + com_ptr& operator = (const com_ptr& rhs) + { + com_ptr(rhs).swap(*this); + return *this; + } + + com_ptr& operator = (com_ptr&& rhs) + { + com_ptr(static_cast<com_ptr&&>(rhs)).swap(*this); + return *this; + } + + template <typename U> + com_ptr& operator = (const com_ptr<U>& rhs) + { + com_ptr(rhs).swap(*this): + return *this; + } + + com_ptr& operator = (T* rhs) + { + com_ptr(rhs).swap(*this); + return *this; + } + + //operator bool_type() const + //{ + // return _ptr ? &com_ptr::safe_bool : nullptr; + //} + + //bool_type operator !() const + //{ + // return !((bool_type)*this); + //} + + void reset() + { + com_ptr().swap(*this); + } + + void reset(T* rhs) + { + com_ptr(rhs).swap(*this); + } + + void reset(T* rhs, bool add_ref) + { + com_ptr(rhs, add_ref).swap(*this); + } + + T* get() const + { + return _ptr; + } + + T* detach() + { + auto result = _ptr; + _ptr = nullptr; + return result; + } + + void swap(com_ptr& rhs) + { + T* temp = rhs._ptr; + rhs._ptr = _ptr; + _ptr = temp; + } + + T& operator * () const { return *_ptr; } + T* operator -> () const { return _ptr; } + + operator T* () const { return _ptr; } + T** operator & () { return &_ptr; } + +private: + T* _ptr; +}; + +template <typename T, typename U> inline bool operator==(const com_ptr<T>& a, const com_ptr<U>& b) { return a.get() == b.get(); } +template <typename T, typename U> inline bool operator!=(const com_ptr<T>& a, const com_ptr<U>& b) { return a.get() != b.get(); } +template <typename T, typename U> inline bool operator==(const com_ptr<T>& a, U* b) { return a.get() == b; } +template <typename T, typename U> inline bool operator!=(const com_ptr<T>& a, U* b) { return a.get() != b; } +template <typename T, typename U> inline bool operator==(T* a, const com_ptr<U>& b) { return a == b.get(); } +template <typename T, typename U> inline bool operator!=(T* a, const com_ptr<U>& b) { return a != b.get(); } +template <typename T> inline bool operator==(const com_ptr<T>& p, std::nullptr_t) { return p.get() == nullptr; } +template <typename T> inline bool operator==(std::nullptr_t, const com_ptr<T>& p) { return p.get() == nullptr; } +template <typename T> inline bool operator!=(const com_ptr<T>& p, std::nullptr_t) { return p.get() != nullptr; } +template <typename T> inline bool operator!=(std::nullptr_t, const com_ptr<T>& p) { return p.get() != nullptr; } +template <typename T> inline bool operator<(const com_ptr<T>& a, const com_ptr<T>& b) { return std::less<T*>()(a.get(), b.get()); } +template <typename T> inline bool operator<=(const com_ptr<T>& a, const com_ptr<T>& b) { return std::less_equal<T*>()(a.get(), b.get()); } +template <typename T> inline bool operator>(const com_ptr<T>& a, const com_ptr<T>& b) { return std::greater<T*>()(a.get(), b.get()); } +template <typename T> inline bool operator>=(const com_ptr<T>& a, const com_ptr<T>& b) { return std::greater_equal<T*>()(a.get(), b.get()); } +template <typename T> void swap(com_ptr<T> & lhs, com_ptr<T> & rhs) { lhs.swap(rhs); } + +# endif // __TD__COM_PTR_H__
\ No newline at end of file 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 <type_traits> +# include <utility> +# include <cassert> + + +//------------------------------------------------------------------------------ +struct nullopt_t +{ + struct init {}; + nullopt_t(init) {} +}; + +const nullopt_t nullopt((nullopt_t::init())); + +template <typename T> +struct optional +{ +private: + typedef typename std::aligned_storage<sizeof(T), std::alignment_of<T>::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<std::decay_t<U>, T>::value is true + template <typename U> + // optional& operator=(U&& value); + optional& operator=(typename std::enable_if<std::is_same<typename std::decay<U>::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 <typename U> + T value_or(U&& default_value) const &; + + template <typename U> + 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<const T*>(&_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 <typename T> +inline optional<T>::optional(): + _has_value(false) +# if defined(_DEBUG) + ,_preview(value_ref()) +# endif +{ +} + +template <typename T> +inline optional<T>::optional(nullopt_t): + _has_value(false) +# if defined(_DEBUG) + , _preview(value_ref()) +# endif +{ +} + +template <typename T> +inline optional<T>::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 <typename T> +inline optional<T>::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 <typename T> +inline optional<T>::optional(const T& v): + _has_value(true) +# if defined(_DEBUG) + , _preview(value_ref()) +# endif +{ + new (value_ptr()) T(v); +} + +template <typename T> +inline optional<T>::optional(T&& v): + _has_value(true) +# if defined(_DEBUG) + , _preview(value_ref()) +# endif +{ + new (value_ptr()) T(std::forward<T>(v)); +} + +template <typename T> +inline optional<T>::~optional() +{ + if (_has_value) + value_ref().~T(); +} + +template <typename T> +inline optional<T>::operator bool_type() const +{ + return _has_value ? &optional::safe_bool : nullptr; +} + +template <typename T> +inline optional<T>& optional<T>::operator= (nullopt_t) +{ + optional().swap(*this); + _has_value = false; + return *this; +} + +template <typename T> +inline optional<T>& optional<T>::operator=(const optional& other) +{ + optional(other).swap(*this); + return *this; +} + +template <typename T> +inline optional<T>& optional<T>::operator=(optional&& other) +{ + optional(std::forward<optional>(other)).swap(*this); + return *this; +} + +template <typename T> +template <typename U> +inline optional<T>& optional<T>::operator=(typename std::enable_if<std::is_same<typename std::decay<U>::type, T>::value, U>::type&& value) +{ + optional<T>(value).swap(*this); + return *this; +} + + +template <typename T> +inline T* optional<T>::operator->() +{ + assert(_has_value); + return value_ptr(); +} + +template <typename T> +inline const T* optional<T>::operator->() const +{ + assert(_has_value); + return value_ptr(); +} + +template <typename T> +inline T& optional<T>::operator*() +{ + assert(_has_value); + return value_ref(); +} + +template <typename T> +inline const T& optional<T>::operator*() const +{ + assert(_has_value); + return value_ref(); +} + +template <typename T> +inline T& optional<T>::value() +{ + assert(_has_value); + return value_ref(); +} + +template <typename T> +inline const T& optional<T>::value() const +{ + assert(_has_value); + return value_ref(); +} + +# if defined(_MSC_VER) && (_MSC_VER > 1600) +template <typename T> +template <typename U> +inline T optional<T>::value_or(U&& default_value) const & +{ + return bool(*this) ? value_ref() : static_cast<T>(std::forward<U>(default_value)); +} + +template <typename T> +template <typename U> +inline T optional<T>::value_or(U&& default_value) && +{ + return bool(*this) ? std::move(value_ref()) : static_cast<T>(std::forward<U>(default_value)); +} +# else +template <typename T> +T optional<T>::value_or(const T& default_value) +{ + return _has_value ? value_ref() : default_value; +} + +template <typename T> +T optional<T>::value_or(const T& default_value) const +{ + return _has_value ? value_ref() : default_value; +} +# endif + +template <typename T> +inline bool optional<T>::has_value() const +{ + return _has_value; +} + +template <typename T> +inline void optional<T>::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<T>(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<T>(other.value_ref())); + + other.value_ref().~T(); + + _has_value = true; + other._has_value = false; + } +} + + +//------------------------------------------------------------------------------ +template <typename T> +optional<T> make_optional(T&& v) +{ + return optional<T>(std::forward<T>(v)); +} + +template <typename T> +inline void swap(optional<T>& lhs, optional<T>& rhs) +{ + lhs.swap(rhs); +} + +template <typename T> +inline bool operator==(const optional<T>& lhs, const optional<T>& rhs) +{ + if (static_cast<bool>(lhs) != static_cast<bool>(rhs)) + return false; + if (!static_cast<bool>(lhs)) + return true; + return *lhs == *rhs; +} + +template <typename T> +bool operator!=(const optional<T>& lhs, const optional<T>& rhs) +{ + return !(lhs == rhs); +} + +template <typename T> +inline bool operator<(const optional<T>& lhs, const optional<T>& rhs) +{ + if (!static_cast<bool>(rhs)) + return false; + if (!static_cast<bool>(lhs)) + return true; + return *lhs < *rhs; +} + +template <typename T> +inline bool operator>(const optional<T>& lhs, const optional<T>& rhs) +{ + return rhs < lhs; +} + +template <typename T> +inline bool operator<=(const optional<T>& lhs, const optional<T>& rhs) +{ + return !(rhs < lhs); +} + +template <typename T> +inline bool operator>=(const optional<T>& lhs, const optional<T>& rhs) +{ + return !(lhs < rhs); +} + +template <typename T> +inline bool operator==(const optional<T>& opt, nullopt_t) +{ + return !static_cast<bool>(opt); +} + +template <typename T> +inline bool operator==(nullopt_t, const optional<T>& opt) +{ + return static_cast<bool>(opt); +} + +template <typename T> +inline bool operator!=(const optional<T>& opt, nullopt_t) +{ + return static_cast<bool>(opt); +} + +template <typename T> +inline bool operator!=(nullopt_t, const optional<T>& opt) +{ + return !static_cast<bool>(opt); +} + +template <typename T> +inline bool operator<(const optional<T>& opt, nullopt_t) +{ + return false; +} + +template <typename T> +inline bool operator<(nullopt_t, const optional<T>& opt) +{ + return static_cast<bool>(opt); +} + +template <typename T> +inline bool operator<=(const optional<T>& opt, nullopt_t) +{ + return !opt; +} + +template <typename T> +inline bool operator<=(nullopt_t, const optional<T>& opt) +{ + return true; +} + +template <typename T> +inline bool operator>(const optional<T>& opt, nullopt_t) +{ + return static_cast<bool>(opt); +} + +template <typename T> +inline bool operator>(nullopt_t, const optional<T>& opt) +{ + return false; +} + +template <typename T> +inline bool operator>=(const optional<T>&, nullopt_t) +{ + return true; +} + +template <typename T> +inline bool operator>=(nullopt_t, const optional<T>& opt) +{ + return !opt; +} + +template <typename T> +inline bool operator==(const optional<T>& opt, const T& v) +{ + return static_cast<bool>(opt) ? *opt == v : false; +} + +template <typename T> +inline bool operator==(const T& v, const optional<T>& opt) +{ + return static_cast<bool>(opt) ? *opt == v : false; +} + +template <typename T> +inline bool operator!=(const optional<T>& opt, const T& v) +{ + return static_cast<bool>(opt) ? *opt != v : true; +} + +template <typename T> +inline bool operator!=(const T& v, const optional<T>& opt) +{ + return static_cast<bool>(opt) ? *opt != v : true; +} + +template <typename T> +inline bool operator<(const optional<T>& opt, const T& v) +{ + using namespace std; + return static_cast<bool>(opt) ? less<T>(*opt, v) : true; +} + +template <typename T> +inline bool operator<(const T& v, const optional<T>& opt) +{ + using namespace std; + return static_cast<bool>(opt) ? less<T>(v, *opt) : false; +} + +template <typename T> +inline bool operator<=(const optional<T>& opt, const T& v) +{ + using namespace std; + return static_cast<bool>(opt) ? less_equal<T>(*opt, v) : true; +} + +template <typename T> +inline bool operator<=(const T& v, const optional<T>& opt) +{ + using namespace std; + return static_cast<bool>(opt) ? less_equal<T>(v, *opt) : false; +} + +template <typename T> +inline bool operator>(const optional<T>& opt, const T& v) +{ + using namespace std; + return static_cast<bool>(opt) ? greater<T>(*opt, v) : false; +} + +template <typename T> +inline bool operator>(const T& v, const optional<T>& opt) +{ + using namespace std; + return static_cast<bool>(opt) ? greater<T>(v, *opt) : true; +} + +template <typename T> +inline bool operator>=(const optional<T>& opt, const T& v) +{ + using namespace std; + return static_cast<bool>(opt) ? greater_equal<T>(*opt, v) : false; +} + +template <typename T> +inline bool operator>=(const T& v, const optional<T>& opt) +{ + using namespace std; + return static_cast<bool>(opt) ? greater_equal<T>(v, *opt) : true; +} + + +# endif // __TD__OPTIONAL_H__ |