LIBINT 2.7.2
array_adaptor.h
1/*
2 * Copyright (C) 2004-2021 Edward F. Valeev
3 *
4 * This file is part of Libint.
5 *
6 * Libint 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 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. 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 <cstdlib>
26#include <cstddef>
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, typename = typename std::enable_if<std::is_same<const U,T>::value>>
68 explicit ext_stack_allocator(U (&array)[N]) noexcept
69 : stack_(const_cast<T*>(&array[0])), free_(stack_) {}
70
71 template <class _Up>
72 struct rebind {
74 };
75
76 T* allocate(std::size_t n) {
77 assert(stack_ != nullptr && "array_view_allocator not initialized");
78 if (stack_ + N - free_ >=
79 static_cast<std::ptrdiff_t>(n)) { // have free space on stack
80 const auto result = free_;
81 free_ += n;
82 return result;
83 } else {
84 return new T[n];
85 }
86 }
87 void deallocate(T* p, std::size_t n) noexcept {
88 if (pointer_on_stack(p)) {
89 assert(p + n == free_ && "stack deallocation out of order");
90 free_ -= n;
91 } else {
92 delete[] p;
93 }
94 }
95
96 template <class T1, std::size_t N1>
97 friend bool operator==(const ext_stack_allocator<T1, N1>& x,
98 const ext_stack_allocator<T1, N1>& y) noexcept;
99
100 private:
101 bool pointer_on_stack(T* ptr) const {
102 return stack_ <= ptr && ptr < stack_ + N;
103 }
104};
105
106template <class T, std::size_t N>
107inline bool operator==(const ext_stack_allocator<T, N>& x,
108 const ext_stack_allocator<T, N>& y) noexcept {
109 return x.stack_ == y.stack_ && x.free_ == y.free_;
110}
111
112template <class T, std::size_t N>
113inline bool operator!=(const ext_stack_allocator<T, N>& x,
114 const ext_stack_allocator<T, N>& y) noexcept {
115 return !(x == y);
116}
117} // namespace detail
118} // namespace libint2
119
120#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
Definition: array_adaptor.h:72