|
|
|
#pragma once
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
#include <libavutil/mem.h>
|
|
|
|
}
|
|
|
|
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
namespace av {
|
|
|
|
// Generic error class
|
|
|
|
struct error : public std::runtime_error {
|
|
|
|
using runtime_error::runtime_error;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Type of a freeing function (for wrapper)
|
|
|
|
template <typename T>
|
|
|
|
using deleter = void(*)(T*);
|
|
|
|
|
|
|
|
// Kind of unique_ptr, but with const-semantics
|
|
|
|
template <typename T, typename D = deleter<T>>
|
|
|
|
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 <typename T>
|
|
|
|
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<T*>(ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void deallocate(T* ptr, size_type /*n*/) const noexcept {
|
|
|
|
av_free(ptr);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T, typename S>
|
|
|
|
bool operator==(allocator<T> const &, allocator<S> const &) noexcept { return true; }
|
|
|
|
template <typename T, typename S>
|
|
|
|
bool operator!=(allocator<T> const &, allocator<S> const &) noexcept { return false; }
|
|
|
|
}
|