Lagrange
Loading...
Searching...
No Matches
SafeVector.h
1/*
2 * Copyright 2025 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12#pragma once
13
14#include <lagrange/utils/assert.h>
15
16#include <vector>
17
18#ifdef LAGRANGE_WITH_PYTHON
19
20 #include <memory>
21
22namespace lagrange {
23
24template <typename T>
25class SharedPtrVector : public std::vector<std::shared_ptr<T>>
26{
27public:
28 using Super = std::vector<std::shared_ptr<T>>;
29
30public:
31 struct Iterator : public Super::iterator
32 {
33 private:
34 using SuperIt = typename Super::iterator;
35
36 public:
37 using iterator_category = std::input_iterator_tag;
38 using difference_type = std::ptrdiff_t;
39 using value_type = T;
40 using pointer = T*;
41 using reference = T&;
42
43 public:
44 using SuperIt::SuperIt;
45 Iterator(const SuperIt& it)
46 : SuperIt(it)
47 {}
48 Iterator(SuperIt&& it)
49 : SuperIt(std::move(it))
50 {}
51 const T& operator*() const { return *SuperIt::operator*(); }
52 T& operator*() { return *SuperIt::operator*(); }
53 };
54
55 struct ConstIterator : public Super::const_iterator
56 {
57 private:
58 using SuperIt = typename Super::const_iterator;
59
60 public:
61 using iterator_category = std::input_iterator_tag;
62 using difference_type = std::ptrdiff_t;
63 using value_type = T;
64 using pointer = const T*;
65 using reference = const T&;
66
67 public:
68 using SuperIt::SuperIt;
69 ConstIterator(const SuperIt& it)
70 : SuperIt(it)
71 {}
72 ConstIterator(SuperIt&& it)
73 : SuperIt(std::move(it))
74 {}
75 const T& operator*() const { return *SuperIt::operator*(); }
76 };
77
78public:
79 using Super::Super;
80
81 template <typename InputIter>
82 SharedPtrVector(InputIter first, InputIter last)
83 {
84 for (auto it = first; it != last; ++it) {
85 Super::push_back(std::make_shared<T>(*it));
86 }
87 }
88 SharedPtrVector(std::initializer_list<T> init)
89 : SharedPtrVector(init.begin(), init.end())
90 {}
91 SharedPtrVector(const std::vector<T>& values)
92 : SharedPtrVector(values.begin(), values.end())
93 {}
94 SharedPtrVector(std::vector<T>&& values)
95 : SharedPtrVector(values.begin(), values.end())
96 {}
97
98 void push_back(const T& value) { Super::emplace_back(std::make_shared<T>(value)); }
99 void push_back(T&& value) { Super::push_back(std::make_shared<T>(std::move(value))); }
100 template <typename... Args>
101 void emplace_back(Args&&... args)
102 {
103 Super::push_back(std::make_shared<T>(std::forward<Args>(args)...));
104 }
105 const T& back() const { return *Super::back().get(); }
106 T& back() { return *Super::back().get(); }
107 const T& front() const { return *Super::front().get(); }
108 T& front() { return *Super::front().get(); }
109 const T& operator[](size_t i) const { return *Super::operator[](i).get(); }
110 T& operator[](size_t i) { return *Super::operator[](i).get(); }
111 const T& at(size_t i) const { return *Super::at(i).get(); }
112 T& at(size_t i) { return *Super::at(i).get(); }
113
114 Iterator begin() { return Super::begin(); }
115 Iterator end() { return Super::end(); }
116 ConstIterator begin() const { return Super::begin(); }
117 ConstIterator end() const { return Super::end(); }
118};
119
120template <typename T>
121struct DerivedVector : public std::vector<T>
122{
123 using Super = std::vector<T>;
124
125 using Super::Super;
126
127 DerivedVector(const std::vector<T>& values)
128 : Super(values.begin(), values.end())
129 {}
130 DerivedVector(std::vector<T>&& values)
131 : Super(values.begin(), values.end())
132 {}
133};
134
135template <typename T>
136using SafeVector =
137 std::conditional_t<std::is_arithmetic_v<T>, DerivedVector<T>, SharedPtrVector<T>>;
138
139} // namespace lagrange
140
141#else
142
143namespace lagrange {
144
145template <typename T>
146using SafeVector = std::vector<T>;
147
148}
149
150#endif
Main namespace for Lagrange.