LIBINT 2.9.0
array_adaptor.h
1/*
2 * Copyright (C) 2004-2024 Edward F. Valeev
3 *
4 * This file is part of Libint library.
5 *
6 * Libint library is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Libint library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with Libint library. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#ifndef INCLUDE_LIBINT2_UTIL_ARRAY_ADAPTOR_H_
22#define INCLUDE_LIBINT2_UTIL_ARRAY_ADAPTOR_H_
23
24#include <cassert>
25#include <cstddef>
26#include <cstdlib>
27#include <type_traits>
28#include <vector>
29
30namespace libint2 {
31namespace detail {
32
35template <class T, std::size_t N>
37 public:
38 using value_type = T;
39 using pointer = T*;
40 using difference_type =
41 typename std::pointer_traits<pointer>::difference_type;
42 using size_type = typename std::make_unsigned<difference_type>::type;
43 using propagate_on_container_copy_assignment = std::true_type;
44 using propagate_on_container_move_assignment = std::true_type;
45
46 static auto constexpr size = N;
47 typedef T array_type[N];
48
49 private:
50 T* stack_; // stack-allocated storage
51 T* free_; // ptr to the first free element on stack
52
53 public:
54 ext_stack_allocator() noexcept : stack_(nullptr), free_(stack_) {}
55 ext_stack_allocator(const ext_stack_allocator& other) = default;
57 : stack_(other.stack_), free_(other.free_) {}
58 ext_stack_allocator& operator=(const ext_stack_allocator& other) = default;
59 ext_stack_allocator& operator=(ext_stack_allocator&& other) noexcept {
60 stack_ = other.stack_;
61 free_ = other.free_;
62 return *this;
63 }
64
65 explicit ext_stack_allocator(array_type& array) noexcept
66 : stack_(&array[0]), free_(stack_) {}
67 template <typename U,
68 typename = typename std::enable_if<std::is_same<const U, T>::value>>
69 explicit ext_stack_allocator(U (&array)[N]) noexcept
70 : stack_(const_cast<T*>(&array[0])), free_(stack_) {}
71
72 template <class _Up>
73 struct rebind {
75 };
76
77 T* allocate(std::size_t n) {
78 assert(stack_ != nullptr && "array_view_allocator not initialized");
79 if (stack_ + N - free_ >=
80 static_cast<std::ptrdiff_t>(n)) { // have free space on stack
81 const auto result = free_;
82 free_ += n;
83 return result;
84 } else {
85 return new T[n];
86 }
87 }
88 void deallocate(T* p, std::size_t n) noexcept {
89 if (pointer_on_stack(p)) {
90 assert(p + n == free_ && "stack deallocation out of order");
91 free_ -= n;
92 } else {
93 delete[] p;
94 }
95 }
96
97 template <class T1, std::size_t N1>
98 friend bool operator==(const ext_stack_allocator<T1, N1>& x,
99 const ext_stack_allocator<T1, N1>& y) noexcept;
100
101 private:
102 bool pointer_on_stack(T* ptr) const {
103 return stack_ <= ptr && ptr < stack_ + N;
104 }
105};
106
107template <class T, std::size_t N>
108inline bool operator==(const ext_stack_allocator<T, N>& x,
109 const ext_stack_allocator<T, N>& y) noexcept {
110 return x.stack_ == y.stack_ && x.free_ == y.free_;
111}
112
113template <class T, std::size_t N>
114inline bool operator!=(const ext_stack_allocator<T, N>& x,
115 const ext_stack_allocator<T, N>& y) noexcept {
116 return !(x == y);
117}
118} // namespace detail
119} // namespace libint2
120
121#endif // INCLUDE_LIBINT2_UTIL_ARRAY_ADAPTOR_H_
allocator that uses an externally-managed stack-allocated array for allocations up to max_size,...
Definition array_adaptor.h:36
Defaults definitions for various parameters assumed by Libint.
Definition algebra.cc:24