From ebc50dcefef3df70b679580f7621aad058b900b1 Mon Sep 17 00:00:00 2001 From: Michael Fabian 'Xaymar' Dirks Date: Tue, 14 Jan 2020 01:11:08 +0100 Subject: [PATCH] utility: Merge util-math and util-memory --- CMakeLists.txt | 4 - source/obs/gs/gs-vertex.cpp | 2 +- source/obs/gs/gs-vertexbuffer.cpp | 2 +- source/obs/gs/gs-vertexbuffer.hpp | 3 +- source/util-math.cpp | 124 ---------------- source/util-math.hpp | 145 ------------------ source/util-memory.cpp | 36 ----- source/util-memory.hpp | 111 -------------- source/utility.cpp | 136 +++++++++++++++++ source/utility.hpp | 236 ++++++++++++++++++++++++++++++ 10 files changed, 375 insertions(+), 424 deletions(-) delete mode 100644 source/util-math.cpp delete mode 100644 source/util-memory.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4031a3e4..059c97f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -339,10 +339,6 @@ set(PROJECT_PRIVATE_SOURCE "${PROJECT_SOURCE_DIR}/source/utility.cpp" "${PROJECT_SOURCE_DIR}/source/util-event.hpp" "${PROJECT_SOURCE_DIR}/source/util-event.cpp" - "${PROJECT_SOURCE_DIR}/source/util-math.hpp" - "${PROJECT_SOURCE_DIR}/source/util-math.cpp" - "${PROJECT_SOURCE_DIR}/source/util-memory.hpp" - "${PROJECT_SOURCE_DIR}/source/util-memory.cpp" # Graphics "${PROJECT_SOURCE_DIR}/source/gfx/gfx-source-texture.hpp" diff --git a/source/obs/gs/gs-vertex.cpp b/source/obs/gs/gs-vertex.cpp index 53320161..656d456d 100644 --- a/source/obs/gs/gs-vertex.cpp +++ b/source/obs/gs/gs-vertex.cpp @@ -19,7 +19,7 @@ #include "gs-vertex.hpp" #include -#include "util-memory.hpp" +#include "utility.hpp" gs::vertex::vertex() : position(nullptr), normal(nullptr), tangent(nullptr), color(nullptr), _has_store(true), _store(nullptr) diff --git a/source/obs/gs/gs-vertexbuffer.cpp b/source/obs/gs/gs-vertexbuffer.cpp index aaf10abf..113009c3 100644 --- a/source/obs/gs/gs-vertexbuffer.cpp +++ b/source/obs/gs/gs-vertexbuffer.cpp @@ -20,7 +20,7 @@ #include "gs-vertexbuffer.hpp" #include #include "obs/gs/gs-helper.hpp" -#include "util-memory.hpp" +#include "utility.hpp" // OBS #ifdef _MSC_VER diff --git a/source/obs/gs/gs-vertexbuffer.hpp b/source/obs/gs/gs-vertexbuffer.hpp index 41e5132f..db9859d3 100644 --- a/source/obs/gs/gs-vertexbuffer.hpp +++ b/source/obs/gs/gs-vertexbuffer.hpp @@ -21,8 +21,7 @@ #include #include "gs-limits.hpp" #include "gs-vertex.hpp" -#include "util-math.hpp" -#include "util-memory.hpp" +#include "utility.hpp" // OBS #ifdef _MSC_VER diff --git a/source/util-math.cpp b/source/util-math.cpp deleted file mode 100644 index 68e23270..00000000 --- a/source/util-math.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* -* Modern effects for a modern Streamer -* Copyright (C) 2017 Michael Fabian Dirks -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA -*/ - -#include "util-math.hpp" -#include -#include -#include -#include "util-memory.hpp" - -void* util::vec2a::operator new(size_t count) -{ - return util::malloc_aligned(16, count); -} - -void* util::vec2a::operator new[](size_t count) -{ - return util::malloc_aligned(16, count); -} - -void util::vec2a::operator delete(void* p) -{ - util::free_aligned(p); -} - -void util::vec2a::operator delete[](void* p) -{ - util::free_aligned(p); -} - -void* util::vec3a::operator new(size_t count) -{ - return util::malloc_aligned(16, count); -} - -void* util::vec3a::operator new[](size_t count) -{ - return util::malloc_aligned(16, count); -} - -void util::vec3a::operator delete(void* p) -{ - util::free_aligned(p); -} - -void util::vec3a::operator delete[](void* p) -{ - util::free_aligned(p); -} - -void* util::vec4a::operator new(size_t count) -{ - return util::malloc_aligned(16, count); -} - -void* util::vec4a::operator new[](size_t count) -{ - return util::malloc_aligned(16, count); -} - -void util::vec4a::operator delete(void* p) -{ - util::free_aligned(p); -} - -void util::vec4a::operator delete[](void* p) -{ - util::free_aligned(p); -} - -std::pair util::size_from_string(std::string text, bool allowSquare) -{ - int64_t width, height; - - const char* begin = text.c_str(); - const char* end = text.c_str() + text.size() + 1; - char* here = const_cast(end); - - long long res = strtoll(begin, &here, 0); - if (errno == ERANGE) { - return {0, 0}; - } - width = res; - - while (here != end) { - if (isdigit(*here) || (*here == '-') || (*here == '+')) { - break; - } - here++; - } - if (here == end) { - // Are we allowed to return a square? - if (allowSquare) { - // Yes: Return width,width. - return {width, width}; - } else { - // No: Return width,0. - return {width, 0}; - } - } - - res = strtoll(here, nullptr, 0); - if (errno == ERANGE) { - return {width, 0}; - } - height = res; - - return {width, height}; -} diff --git a/source/util-math.hpp b/source/util-math.hpp index 237d59c8..b4504d3c 100644 --- a/source/util-math.hpp +++ b/source/util-math.hpp @@ -23,153 +23,8 @@ #include #include -// OBS -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4201) -#endif -#include -#include -#include -#ifdef _MSC_VER -#pragma warning(pop) -#endif -// Constants -#define S_PI 3.1415926535897932384626433832795 // PI = pi -#define S_PI2 6.283185307179586476925286766559 // 2PI = 2 * pi -#define S_PI2_SQROOT 2.506628274631000502415765284811 // sqrt(2 * pi) - -#define S_RAD 57.295779513082320876798154814105 // 180/pi -#define S_DEG 0.01745329251994329576923690768489 // pi/180 -#define D_DEG_TO_RAD(x) (x * S_DEG) -#define D_RAD_TO_DEG(x) (x * S_RAD) - -inline size_t GetNearestPowerOfTwoAbove(size_t v) -{ - return 1ull << size_t(ceil(log10(double(v)) / log10(2.0))); -} - -inline size_t GetNearestPowerOfTwoBelow(size_t v) -{ - return 1ull << size_t(floor(log10(double(v)) / log10(2.0))); -} namespace util { - struct vec2a : public vec2 { - // 16-byte Aligned version of vec2 - static void* operator new(size_t count); - static void* operator new[](size_t count); - static void operator delete(void* p); - static void operator delete[](void* p); - }; -#ifdef _MSC_VER - __declspec(align(16)) -#endif - struct vec3a : public vec3 { - // 16-byte Aligned version of vec3 - static void* operator new(size_t count); - static void* operator new[](size_t count); - static void operator delete(void* p); - static void operator delete[](void* p); - }; - -#ifdef _MSC_VER - __declspec(align(16)) -#endif - struct vec4a : public vec4 { - // 16-byte Aligned version of vec4 - static void* operator new(size_t count); - static void* operator new[](size_t count); - static void operator delete(void* p); - static void operator delete[](void* p); - }; - - std::pair size_from_string(std::string text, bool allowSquare = true); - - namespace math { - // Proven by tests to be the fastest implementation on Intel and AMD CPUs. - // Ranking: log10, loop < bitscan < pow - // loop and log10 trade blows, usually almost identical. - // loop is used for integers, log10 for anything else. - template - inline bool is_power_of_two(T v) - { - return T(1ull << uint64_t(floor(log10(T(v)) / log10(2.0)))) == v; - }; - - template - inline bool is_power_of_two_loop(T v) - { - bool have_bit = false; - for (size_t index = 0; index < (sizeof(T) * 8); index++) { - bool cur = (v & (static_cast(1ull) << index)) != 0; - if (cur) { - if (have_bit) - return false; - have_bit = true; - } - } - return true; - } - -#pragma push_macro("P_IS_POWER_OF_TWO_AS_LOOP") -#define P_IS_POWER_OF_TWO_AS_LOOP(x) \ - template<> \ - inline bool is_power_of_two(x v) \ - { \ - return is_power_of_two_loop(v); \ - } - P_IS_POWER_OF_TWO_AS_LOOP(int8_t); - P_IS_POWER_OF_TWO_AS_LOOP(uint8_t); - P_IS_POWER_OF_TWO_AS_LOOP(int16_t); - P_IS_POWER_OF_TWO_AS_LOOP(uint16_t); - P_IS_POWER_OF_TWO_AS_LOOP(int32_t); - P_IS_POWER_OF_TWO_AS_LOOP(uint32_t); - P_IS_POWER_OF_TWO_AS_LOOP(int64_t); - P_IS_POWER_OF_TWO_AS_LOOP(uint64_t); -#undef P_IS_POWER_OF_TWO_AS_LOOP -#pragma pop_macro("P_IS_POWER_OF_TWO_AS_LOOP") - - template - inline uint64_t get_power_of_two_exponent_floor(T v) - { - return uint64_t(floor(log10(T(v)) / log10(2.0))); - } - - template - inline uint64_t get_power_of_two_exponent_ceil(T v) - { - return uint64_t(ceil(log10(T(v)) / log10(2.0))); - } - - template - inline bool is_equal(T target, C value) - { - return (target > (value - std::numeric_limits::epsilon())) - && (target < (value + std::numeric_limits::epsilon())); - } - - template - inline T gaussian(T x, T o /*, T u = 0*/) - { - // u/µ can be simulated by subtracting that value from x. - static const double_t pi = 3.1415926535897932384626433832795; - static const double_t two_pi = pi * 2.; - static const double_t two_pi_sqroot = 2.506628274631000502415765284811; //sqrt(two_pi); - - if (is_equal(0, o)) { - return T(std::numeric_limits::infinity()); - } - - // g(x) = (1 / o√(2Π)) * e(-(1/2) * ((x-u)/o)²) - double_t left_e = 1. / (o * two_pi_sqroot); - double_t mid_right_e = ((x /* - u*/) / o); - double_t right_e = -0.5 * mid_right_e * mid_right_e; - double_t final = left_e * exp(right_e); - - return T(final); - } - } // namespace math } // namespace util diff --git a/source/util-memory.cpp b/source/util-memory.cpp index 4ff50dbb..cf4d8fce 100644 --- a/source/util-memory.cpp +++ b/source/util-memory.cpp @@ -29,39 +29,3 @@ #endif using namespace std; - -void* util::malloc_aligned(size_t align, size_t size) -{ -#ifdef USE_MSC_ALLOC - return _aligned_malloc(size, align); -#elif defined(USE_STD_ALLOC) - return aligned_alloc(size, align); -#else - // Ensure that we have space for the pointer and the data. - size_t asize = aligned_offset(align, size + (sizeof(void*) * 2)); - - // Allocate memory and store integer representation of pointer. - void* ptr = malloc(asize); - - // Calculate actual aligned position - intptr_t ptr_off = static_cast(aligned_offset(align, reinterpret_cast(ptr) + sizeof(void*))); - - // Store actual pointer at ptr_off - sizeof(void*). - *reinterpret_cast(ptr_off - sizeof(void*)) = reinterpret_cast(ptr); - - // Return aligned pointer - return reinterpret_cast(ptr_off); -#endif -} - -void util::free_aligned(void* mem) -{ -#ifdef USE_MSC_ALLOC - _aligned_free(mem); -#elif defined(USE_STD_ALLOC_FREE) - free(mem); -#else - void* ptr = reinterpret_cast(*reinterpret_cast(static_cast(mem) - sizeof(void*))); - free(ptr); -#endif -} diff --git a/source/util-memory.hpp b/source/util-memory.hpp deleted file mode 100644 index e7e4c1e8..00000000 --- a/source/util-memory.hpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Modern effects for a modern Streamer - * Copyright (C) 2017 Michael Fabian Dirks - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#pragma once -#include - -namespace util { - inline size_t aligned_offset(size_t align, size_t pos) - { - return ((pos / align) + 1) * align; - } - void* malloc_aligned(size_t align, size_t size); - void free_aligned(void* mem); - - template - class AlignmentAllocator { - public: - typedef T value_type; - typedef size_t size_type; -#ifdef __clang__ - typedef ptrdiff_t difference_type; -#else - typedef std::ptrdiff_t difference_type; -#endif - - typedef T* pointer; - typedef const T* const_pointer; - - typedef T& reference; - typedef const T& const_reference; - - public: - inline AlignmentAllocator() {} - - template - inline AlignmentAllocator(const AlignmentAllocator&) - {} - - inline ~AlignmentAllocator() {} - - inline pointer adress(reference r) - { - return &r; - } - - inline const_pointer adress(const_reference r) const - { - return &r; - } - - inline pointer allocate(size_type n) - { - return (pointer)malloc_aligned(n * sizeof(value_type), N); - } - - inline void deallocate(pointer p, size_type) - { - free_aligned(p); - } - - inline void construct(pointer p, const value_type& wert) - { - new (p) value_type(wert); - } - - inline void destroy(pointer p) - { - p->~value_type(); - p; - } - - inline size_type max_size() const - { - return size_type(-1) / sizeof(value_type); - } - - template - struct rebind { - typedef AlignmentAllocator other; - }; - - bool operator!=(const AlignmentAllocator& other) const - { - return !(*this == other); - } - - // Returns true if and only if storage allocated from *this - // can be deallocated from other, and vice versa. - // Always returns true for stateless allocators. - bool operator==(const AlignmentAllocator&) const - { - return true; - } - }; -}; // namespace util diff --git a/source/utility.cpp b/source/utility.cpp index c241316b..2b463b13 100644 --- a/source/utility.cpp +++ b/source/utility.cpp @@ -92,3 +92,139 @@ obs_property_t* util::obs_properties_add_tristate(obs_properties_t* props, const obs_property_list_add_int(p, D_TRANSLATE(S_STATE_ENABLED), 1); return p; } + +void* util::vec2a::operator new(size_t count) +{ + return util::malloc_aligned(16, count); +} + +void* util::vec2a::operator new[](size_t count) +{ + return util::malloc_aligned(16, count); +} + +void util::vec2a::operator delete(void* p) +{ + util::free_aligned(p); +} + +void util::vec2a::operator delete[](void* p) +{ + util::free_aligned(p); +} + +void* util::vec3a::operator new(size_t count) +{ + return util::malloc_aligned(16, count); +} + +void* util::vec3a::operator new[](size_t count) +{ + return util::malloc_aligned(16, count); +} + +void util::vec3a::operator delete(void* p) +{ + util::free_aligned(p); +} + +void util::vec3a::operator delete[](void* p) +{ + util::free_aligned(p); +} + +void* util::vec4a::operator new(size_t count) +{ + return util::malloc_aligned(16, count); +} + +void* util::vec4a::operator new[](size_t count) +{ + return util::malloc_aligned(16, count); +} + +void util::vec4a::operator delete(void* p) +{ + util::free_aligned(p); +} + +void util::vec4a::operator delete[](void* p) +{ + util::free_aligned(p); +} + +std::pair util::size_from_string(std::string text, bool allowSquare) +{ + int64_t width, height; + + const char* begin = text.c_str(); + const char* end = text.c_str() + text.size() + 1; + char* here = const_cast(end); + + long long res = strtoll(begin, &here, 0); + if (errno == ERANGE) { + return {0, 0}; + } + width = res; + + while (here != end) { + if (isdigit(*here) || (*here == '-') || (*here == '+')) { + break; + } + here++; + } + if (here == end) { + // Are we allowed to return a square? + if (allowSquare) { + // Yes: Return width,width. + return {width, width}; + } else { + // No: Return width,0. + return {width, 0}; + } + } + + res = strtoll(here, nullptr, 0); + if (errno == ERANGE) { + return {width, 0}; + } + height = res; + + return {width, height}; +} + +void* util::malloc_aligned(size_t align, size_t size) +{ +#ifdef USE_MSC_ALLOC + return _aligned_malloc(size, align); +#elif defined(USE_STD_ALLOC) + return aligned_alloc(size, align); +#else + // Ensure that we have space for the pointer and the data. + size_t asize = aligned_offset(align, size + (sizeof(void*) * 2)); + + // Allocate memory and store integer representation of pointer. + void* ptr = malloc(asize); + + // Calculate actual aligned position + intptr_t ptr_off = static_cast(aligned_offset(align, reinterpret_cast(ptr) + sizeof(void*))); + + // Store actual pointer at ptr_off - sizeof(void*). + *reinterpret_cast(ptr_off - sizeof(void*)) = reinterpret_cast(ptr); + + // Return aligned pointer + return reinterpret_cast(ptr_off); +#endif +} + +void util::free_aligned(void* mem) +{ +#ifdef USE_MSC_ALLOC + _aligned_free(mem); +#elif defined(USE_STD_ALLOC_FREE) + free(mem); +#else + void* ptr = reinterpret_cast(*reinterpret_cast(static_cast(mem) - sizeof(void*))); + free(ptr); +#endif +} diff --git a/source/utility.hpp b/source/utility.hpp index 314d1773..202562af 100644 --- a/source/utility.hpp +++ b/source/utility.hpp @@ -20,13 +20,34 @@ #pragma once #include #include +#include #include +#include extern "C" { +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4201) +#endif +#include +#include +#include #include #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif } +// Constants +#define S_PI 3.1415926535897932384626433832795 // PI = pi +#define S_PI2 6.283185307179586476925286766559 // 2PI = 2 * pi +#define S_PI2_SQROOT 2.506628274631000502415765284811 // sqrt(2 * pi) +#define S_RAD 57.295779513082320876798154814105 // 180/pi +#define S_DEG 0.01745329251994329576923690768489 // pi/180 +#define D_DEG_TO_RAD(x) (x * S_DEG) +#define D_RAD_TO_DEG(x) (x * S_RAD) + const char* obs_module_recursive_text(const char* to_translate, size_t depth = std::numeric_limits::max()); template @@ -123,4 +144,219 @@ namespace util { uint8_t b; }; } argb32; + + struct vec2a : public vec2 { + // 16-byte Aligned version of vec2 + static void* operator new(size_t count); + static void* operator new[](size_t count); + static void operator delete(void* p); + static void operator delete[](void* p); + }; + +#ifdef _MSC_VER + __declspec(align(16)) +#endif + struct vec3a : public vec3 { + // 16-byte Aligned version of vec3 + static void* operator new(size_t count); + static void* operator new[](size_t count); + static void operator delete(void* p); + static void operator delete[](void* p); + }; + +#ifdef _MSC_VER + __declspec(align(16)) +#endif + struct vec4a : public vec4 { + // 16-byte Aligned version of vec4 + static void* operator new(size_t count); + static void* operator new[](size_t count); + static void operator delete(void* p); + static void operator delete[](void* p); + }; + + inline size_t GetNearestPowerOfTwoAbove(size_t v) + { + return 1ull << size_t(ceil(log10(double(v)) / log10(2.0))); + } + + inline size_t GetNearestPowerOfTwoBelow(size_t v) + { + return 1ull << size_t(floor(log10(double(v)) / log10(2.0))); + } + + std::pair size_from_string(std::string text, bool allowSquare = true); + + namespace math { + // Proven by tests to be the fastest implementation on Intel and AMD CPUs. + // Ranking: log10, loop < bitscan < pow + // loop and log10 trade blows, usually almost identical. + // loop is used for integers, log10 for anything else. + template + inline bool is_power_of_two(T v) + { + return T(1ull << uint64_t(floor(log10(T(v)) / log10(2.0)))) == v; + }; + + template + inline bool is_power_of_two_loop(T v) + { + bool have_bit = false; + for (size_t index = 0; index < (sizeof(T) * 8); index++) { + bool cur = (v & (static_cast(1ull) << index)) != 0; + if (cur) { + if (have_bit) + return false; + have_bit = true; + } + } + return true; + } + +#pragma push_macro("P_IS_POWER_OF_TWO_AS_LOOP") +#define P_IS_POWER_OF_TWO_AS_LOOP(x) \ + template<> \ + inline bool is_power_of_two(x v) \ + { \ + return is_power_of_two_loop(v); \ + } + P_IS_POWER_OF_TWO_AS_LOOP(int8_t); + P_IS_POWER_OF_TWO_AS_LOOP(uint8_t); + P_IS_POWER_OF_TWO_AS_LOOP(int16_t); + P_IS_POWER_OF_TWO_AS_LOOP(uint16_t); + P_IS_POWER_OF_TWO_AS_LOOP(int32_t); + P_IS_POWER_OF_TWO_AS_LOOP(uint32_t); + P_IS_POWER_OF_TWO_AS_LOOP(int64_t); + P_IS_POWER_OF_TWO_AS_LOOP(uint64_t); +#undef P_IS_POWER_OF_TWO_AS_LOOP +#pragma pop_macro("P_IS_POWER_OF_TWO_AS_LOOP") + + template + inline uint64_t get_power_of_two_exponent_floor(T v) + { + return uint64_t(floor(log10(T(v)) / log10(2.0))); + } + + template + inline uint64_t get_power_of_two_exponent_ceil(T v) + { + return uint64_t(ceil(log10(T(v)) / log10(2.0))); + } + + template + inline bool is_equal(T target, C value) + { + return (target > (value - std::numeric_limits::epsilon())) + && (target < (value + std::numeric_limits::epsilon())); + } + + template + inline T gaussian(T x, T o /*, T u = 0*/) + { + // u/µ can be simulated by subtracting that value from x. + static const double_t pi = 3.1415926535897932384626433832795; + static const double_t two_pi = pi * 2.; + static const double_t two_pi_sqroot = 2.506628274631000502415765284811; //sqrt(two_pi); + + if (is_equal(0, o)) { + return T(std::numeric_limits::infinity()); + } + + // g(x) = (1 / o√(2Π)) * e(-(1/2) * ((x-u)/o)²) + double_t left_e = 1. / (o * two_pi_sqroot); + double_t mid_right_e = ((x /* - u*/) / o); + double_t right_e = -0.5 * mid_right_e * mid_right_e; + double_t final = left_e * exp(right_e); + + return T(final); + } + } // namespace math + + inline size_t aligned_offset(size_t align, size_t pos) + { + return ((pos / align) + 1) * align; + } + void* malloc_aligned(size_t align, size_t size); + void free_aligned(void* mem); + + template + class AlignmentAllocator { + public: + typedef T value_type; + typedef size_t size_type; +#ifdef __clang__ + typedef ptrdiff_t difference_type; +#else + typedef std::ptrdiff_t difference_type; +#endif + + typedef T* pointer; + typedef const T* const_pointer; + + typedef T& reference; + typedef const T& const_reference; + + public: + inline AlignmentAllocator() {} + + template + inline AlignmentAllocator(const AlignmentAllocator&) + {} + + inline ~AlignmentAllocator() {} + + inline pointer adress(reference r) + { + return &r; + } + + inline const_pointer adress(const_reference r) const + { + return &r; + } + + inline pointer allocate(size_type n) + { + return (pointer)malloc_aligned(n * sizeof(value_type), N); + } + + inline void deallocate(pointer p, size_type) + { + free_aligned(p); + } + + inline void construct(pointer p, const value_type& wert) + { + new (p) value_type(wert); + } + + inline void destroy(pointer p) + { + p->~value_type(); + p; + } + + inline size_type max_size() const + { + return size_type(-1) / sizeof(value_type); + } + + template + struct rebind { + typedef AlignmentAllocator other; + }; + + bool operator!=(const AlignmentAllocator& other) const + { + return !(*this == other); + } + + // Returns true if and only if storage allocated from *this + // can be deallocated from other, and vice versa. + // Always returns true for stateless allocators. + bool operator==(const AlignmentAllocator&) const + { + return true; + } + }; } // namespace util