122 lines
3.6 KiB
C++
122 lines
3.6 KiB
C++
#pragma once
|
|
|
|
#include <limits> // std::numeric_limits
|
|
#include <utility> // std::forward
|
|
#include <cstddef>
|
|
|
|
#include "libipc/pool_alloc.h"
|
|
|
|
namespace ipc {
|
|
namespace mem {
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
/// The allocator wrapper class for STL
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
namespace detail {
|
|
|
|
template <typename T, typename AllocP>
|
|
struct rebind {
|
|
template <typename U>
|
|
using alloc_t = AllocP;
|
|
};
|
|
|
|
template <typename T, template <typename> class AllocT>
|
|
struct rebind<T, AllocT<T>> {
|
|
template <typename U>
|
|
using alloc_t = AllocT<U>;
|
|
};
|
|
|
|
} // namespace detail
|
|
|
|
template <typename T, typename AllocP>
|
|
class allocator_wrapper {
|
|
|
|
template <typename U, typename AllocU>
|
|
friend class allocator_wrapper;
|
|
|
|
public:
|
|
// type definitions
|
|
typedef T value_type;
|
|
typedef value_type* pointer;
|
|
typedef const value_type* const_pointer;
|
|
typedef value_type& reference;
|
|
typedef const value_type& const_reference;
|
|
typedef std::size_t size_type;
|
|
typedef std::ptrdiff_t difference_type;
|
|
typedef AllocP alloc_policy;
|
|
|
|
private:
|
|
alloc_policy alloc_;
|
|
|
|
public:
|
|
allocator_wrapper() noexcept {}
|
|
|
|
// construct by copying (do nothing)
|
|
allocator_wrapper (const allocator_wrapper<T, AllocP>&) noexcept {}
|
|
allocator_wrapper& operator=(const allocator_wrapper<T, AllocP>&) noexcept { return *this; }
|
|
|
|
// construct from a related allocator (do nothing)
|
|
template <typename U, typename AllocU> allocator_wrapper (const allocator_wrapper<U, AllocU>&) noexcept {}
|
|
template <typename U, typename AllocU> allocator_wrapper& operator=(const allocator_wrapper<U, AllocU>&) noexcept { return *this; }
|
|
|
|
allocator_wrapper (allocator_wrapper && rhs) noexcept : alloc_ ( std::move(rhs.alloc_) ) {}
|
|
allocator_wrapper& operator=(allocator_wrapper && rhs) noexcept { alloc_ = std::move(rhs.alloc_); return *this; }
|
|
|
|
public:
|
|
// the other type of std_allocator
|
|
template <typename U>
|
|
struct rebind {
|
|
using other = allocator_wrapper< U, typename detail::rebind<T, AllocP>::template alloc_t<U> >;
|
|
};
|
|
|
|
constexpr size_type max_size(void) const noexcept {
|
|
return (std::numeric_limits<size_type>::max)() / sizeof(value_type);
|
|
}
|
|
|
|
public:
|
|
pointer allocate(size_type count) noexcept {
|
|
if (count == 0) return nullptr;
|
|
if (count > this->max_size()) return nullptr;
|
|
return static_cast<pointer>(alloc_.alloc(count * sizeof(value_type)));
|
|
}
|
|
|
|
void deallocate(pointer p, size_type count) noexcept {
|
|
alloc_.free(p, count * sizeof(value_type));
|
|
}
|
|
|
|
template <typename... P>
|
|
static void construct(pointer p, P && ... params) {
|
|
ipc::mem::construct(p, std::forward<P>(params)...);
|
|
}
|
|
|
|
static void destroy(pointer p) {
|
|
ipc::mem::destruct(p);
|
|
}
|
|
};
|
|
|
|
template <class AllocP>
|
|
class allocator_wrapper<void, AllocP> {
|
|
public:
|
|
// type definitions
|
|
typedef void value_type;
|
|
typedef value_type* pointer;
|
|
typedef const value_type* const_pointer;
|
|
typedef std::size_t size_type;
|
|
typedef std::ptrdiff_t difference_type;
|
|
typedef AllocP alloc_policy;
|
|
};
|
|
|
|
template <typename T, typename U, class AllocP>
|
|
constexpr bool operator==(const allocator_wrapper<T, AllocP>&, const allocator_wrapper<U, AllocP>&) noexcept {
|
|
return true;
|
|
}
|
|
|
|
template <typename T, typename U, class AllocP>
|
|
constexpr bool operator!=(const allocator_wrapper<T, AllocP>&, const allocator_wrapper<U, AllocP>&) noexcept {
|
|
return false;
|
|
}
|
|
|
|
} // namespace mem
|
|
} // namespace ipc
|