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/com_ptr.h | 148 ++++++++++ src/player/backends/utility/optional.h | 517 +++++++++++++++++++++++++++++++++ 2 files changed, 665 insertions(+) create mode 100644 src/player/backends/utility/com_ptr.h create mode 100644 src/player/backends/utility/optional.h (limited to 'src/player/backends/utility') 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 +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 + com_ptr(const com_ptr& 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(rhs)).swap(*this); + return *this; + } + + template + com_ptr& operator = (const com_ptr& 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 inline bool operator==(const com_ptr& a, const com_ptr& b) { return a.get() == b.get(); } +template inline bool operator!=(const com_ptr& a, const com_ptr& b) { return a.get() != b.get(); } +template inline bool operator==(const com_ptr& a, U* b) { return a.get() == b; } +template inline bool operator!=(const com_ptr& a, U* b) { return a.get() != b; } +template inline bool operator==(T* a, const com_ptr& b) { return a == b.get(); } +template inline bool operator!=(T* a, const com_ptr& b) { return a != b.get(); } +template inline bool operator==(const com_ptr& p, std::nullptr_t) { return p.get() == nullptr; } +template inline bool operator==(std::nullptr_t, const com_ptr& p) { return p.get() == nullptr; } +template inline bool operator!=(const com_ptr& p, std::nullptr_t) { return p.get() != nullptr; } +template inline bool operator!=(std::nullptr_t, const com_ptr& p) { return p.get() != nullptr; } +template inline bool operator<(const com_ptr& a, const com_ptr& b) { return std::less()(a.get(), b.get()); } +template inline bool operator<=(const com_ptr& a, const com_ptr& b) { return std::less_equal()(a.get(), b.get()); } +template inline bool operator>(const com_ptr& a, const com_ptr& b) { return std::greater()(a.get(), b.get()); } +template inline bool operator>=(const com_ptr& a, const com_ptr& b) { return std::greater_equal()(a.get(), b.get()); } +template void swap(com_ptr & lhs, com_ptr & 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 +# 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