CommonLibSSE (Parapets fork)
ReferenceArray.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "RE/A/Array.h"
4 #include "RE/B/BSTSmartPointer.h"
6 #include "RE/V/Variable.h"
7 
8 namespace RE
9 {
10  namespace BSScript
11  {
12  template <class, class = void>
14 
15  template <class T>
17  T,
18  std::enable_if_t<
19  std::disjunction_v<
20  is_builtin_convertible<T>,
21  is_form_pointer<T>>>>
22  {
23  public:
24  using container_type = std::vector<T>;
25  using value_type = typename container_type::value_type;
26  using size_type = typename container_type::size_type;
27  using difference_type = typename container_type::difference_type;
28  using reference = typename container_type::reference;
29  using const_reference = typename container_type::const_reference;
30  using pointer = typename container_type::pointer;
31  using const_pointer = typename container_type::const_pointer;
32  using iterator = typename container_type::iterator;
33  using const_iterator = typename container_type::const_iterator;
34  using reverse_iterator = typename container_type::reverse_iterator;
35  using const_reverse_iterator = typename container_type::const_reverse_iterator;
36 
38  _unwrapped(),
39  _wrapped(nullptr)
40  {}
41 
42  reference_array(const Variable* a_wrapped) :
43  _unwrapped(),
44  _wrapped(nullptr)
45  {
46  do_unwrap(a_wrapped);
47  }
48 
49  reference_array(const reference_array&) = delete;
50 
52  _unwrapped(std::move(a_rhs._unwrapped)),
53  _wrapped(std::move(a_rhs._wrapped))
54  {}
55 
56  ~reference_array() { do_wrap(); }
57 
58  reference_array& operator=(const Variable* a_wrapped)
59  {
60  do_unwrap(a_wrapped);
61  return *this;
62  }
63 
65 
67  {
68  if (this != std::addressof(a_rhs)) {
69  do_wrap();
70  _unwrapped = std::move(a_rhs._unwrapped);
71  _wrapped = std::move(a_rhs._wrapped);
72  }
73  return *this;
74  }
75 
76  [[nodiscard]] operator container_type() const { return _unwrapped; }
77 
78  [[nodiscard]] reference at(size_type a_pos) { return _unwrapped.at(a_pos); }
79  [[nodiscard]] const_reference at(size_type a_pos) const { return _unwrapped.at(a_pos); }
80 
81  [[nodiscard]] reference operator[](size_type a_pos) { return _unwrapped[a_pos]; }
82  [[nodiscard]] const_reference operator[](size_type a_pos) const { return _unwrapped[a_pos]; }
83 
84  [[nodiscard]] reference front() { return _unwrapped.front(); }
85  [[nodiscard]] const_reference front() const { return _unwrapped.front(); }
86 
87  [[nodiscard]] reference back() { return _unwrapped.back(); }
88  [[nodiscard]] const_reference back() const { return _unwrapped.back(); }
89 
90  [[nodiscard]] pointer data() noexcept { return _unwrapped.data(); }
91  [[nodiscard]] const_pointer data() const noexcept { return _unwrapped.data(); }
92 
93  [[nodiscard]] iterator begin() noexcept { return _unwrapped.begin(); }
94  [[nodiscard]] const_iterator begin() const noexcept { return _unwrapped.begin(); }
95  [[nodiscard]] const_iterator cbegin() const noexcept { return _unwrapped.cbegin(); }
96 
97  [[nodiscard]] iterator end() noexcept { return _unwrapped.end(); }
98  [[nodiscard]] const_iterator end() const noexcept { return _unwrapped.end(); }
99  [[nodiscard]] const_iterator cend() const noexcept { return _unwrapped.cend(); }
100 
101  [[nodiscard]] reverse_iterator rbegin() noexcept { return _unwrapped.rbegin(); }
102  [[nodiscard]] const_reverse_iterator rbegin() const noexcept { return _unwrapped.rbegin(); }
103  [[nodiscard]] const_reverse_iterator crbegin() const noexcept { return _unwrapped.crbegin(); }
104 
105  [[nodiscard]] reverse_iterator rend() noexcept { return _unwrapped.rend(); }
106  [[nodiscard]] const_reverse_iterator rend() const noexcept { return _unwrapped.rend(); }
107  [[nodiscard]] const_reverse_iterator crend() const noexcept { return _unwrapped.crend(); }
108 
109  [[nodiscard]] bool empty() const noexcept { return _unwrapped.empty(); }
110 
111  [[nodiscard]] size_type size() const noexcept { return _unwrapped.size(); }
112 
113  void swap(reference_array& a_rhs)
114  {
115  using std::swap;
116  swap(_unwrapped, a_rhs._unwrapped);
117  swap(_wrapped, a_rhs._wrapped);
118  }
119 
120  private:
121  void do_wrap()
122  {
123  if (_wrapped) {
124  const auto SIZE = static_cast<std::uint32_t>(_unwrapped.size());
125  for (std::uint32_t i = 0; i < SIZE; ++i) {
126  (*_wrapped)[i].Pack(_unwrapped[i]);
127  }
128  }
129  }
130 
131  void do_unwrap(const Variable* a_wrapped)
132  {
133  assert(a_wrapped && a_wrapped->IsArray());
134  auto arr = a_wrapped->GetArray();
135  if (_wrapped != arr) {
136  _wrapped = std::move(arr);
137  _unwrapped.reserve(_wrapped->size());
138  for (auto& elem : *_wrapped) {
139  _unwrapped.push_back(elem.Unpack<value_type>());
140  }
141  }
142  }
143 
144  container_type _unwrapped;
145  BSTSmartPointer<Array> _wrapped;
146  };
147 
148  template <class T>
150  {
151  a_lhs.swap(a_rhs);
152  }
153  }
154 
155  template <class T>
157 }
Definition: Variable.h:15
typename container_type::const_reverse_iterator const_reverse_iterator
Definition: ReferenceArray.h:35
Definition: ReferenceArray.h:13
void swap(reference_array< T > &a_lhs, reference_array< T > &a_rhs)
Definition: ReferenceArray.h:149
Definition: AbsorbEffect.h:6
Definition: NiBinaryStream.h:94