#pragma once extern "C" { #include } #include #include namespace av { // Generic error class struct error : public std::runtime_error { using runtime_error::runtime_error; }; // Type of a freeing function (for wrapper) template using deleter = void(*)(T*); // Kind of unique_ptr, but with const-semantics template > struct wrapper { wrapper(T * data_ = nullptr, D deleter_ = D()) : data(data_) , deleter(deleter_) {} wrapper(wrapper && o) : data(o.data) , deleter(o.deleter) { o.release(); } wrapper & operator=(wrapper && o) { data = o.data; deleter = o.deleter; o.release(); return *this; } wrapper(wrapper const & o) = delete; wrapper & operator=(wrapper const & o) = delete; ~wrapper(){ reset(); } T * get() { return data; } T const * get() const { return data; } T & operator*() { return *get(); } T const & operator*() const { return *get(); } T * operator->() { return get(); } T const * operator->() const { return get(); } T * release() { auto t = data; data = nullptr; return t; } void reset() { if(data && deleter) deleter(data); data = nullptr; } operator bool() const { return get(); } private: T * data; D deleter; }; // Allocator template struct allocator { using value_type = T; using size_type = size_t; T* allocate(size_type n) const { auto ptr = av_malloc(n * sizeof(T)); if(!ptr) throw std::bad_alloc(); return static_cast(ptr); } void deallocate(T* ptr, size_type /*n*/) const noexcept { av_free(ptr); } }; template bool operator==(allocator const &, allocator const &) noexcept { return true; } template bool operator!=(allocator const &, allocator const &) noexcept { return false; } }