cp-library

競技プログラミング用 C++ ライブラリ

View the Project on GitHub qandori/cp-library

:heavy_check_mark: 整列した配列のアロケータ

components/aligned_allocator.hpp · GitHub で見る

共通ページ

std::vector などに指定できる、境界を指定したアロケータです。

#include "lib/components/aligned_allocator.hpp"
#include <cstdint>
#include <vector>

std::vector<std::int64_t, AlignedAllocator<std::int64_t>> values(100);

AlignedAllocator<T,Alignment=64> は、確保する先頭アドレスを Alignment byte の倍数に揃えます。Alignment は alignof(T) 以上の 2 の冪です。allocate(n) は n 要素の未初期化領域を返し、deallocate(p,n) は同じアロケータで確保した領域を解放します。同じ Alignment のアロケータは互換です。

確保できない場合は std::bad_alloc、要素数からバイト数への変換がオーバーフローする場合は std::bad_array_new_length を送出します。

確保する空間は \(O(n)\) です。確保と解放の時間は OS とアロケータに依存します。

検証コード

コード

#ifndef ALIGNED_ALLOCATOR_HPP
#define ALIGNED_ALLOCATOR_HPP

#include <cstddef>
#include <limits>
#include <new>

template<class T, std::size_t Alignment = 64> struct AlignedAllocator {
	static_assert(Alignment >= alignof(T) && !(Alignment & (Alignment - 1)));
	using value_type = T;
	template<class U> struct rebind { using other = AlignedAllocator<U, Alignment>; };
	AlignedAllocator() = default;
	template<class U> AlignedAllocator(const AlignedAllocator<U, Alignment> &) {}
	T *allocate(std::size_t n) {
		if (n > std::numeric_limits<std::size_t>::max() / sizeof(T)) throw std::bad_array_new_length();
		return static_cast<T *>(::operator new(n * sizeof(T), std::align_val_t(Alignment)));
	}
	void deallocate(T *p, std::size_t) { ::operator delete(p, std::align_val_t(Alignment)); }
	template<class U> bool operator==(const AlignedAllocator<U, Alignment> &) const { return true; }
};

#endif
Back to top page