22
33#include < algorithm>
44#include < cassert>
5- #include < compare>
6- #include < concepts>
75#include < exception>
86#include < iterator>
97#include < limits>
108#include < memory>
119#include < new>
12- #include < ranges>
1310#include < stdexcept>
1411#include < type_traits>
12+ #include < utility>
13+
14+ #ifdef __cpp_concepts
15+ #include < concepts>
16+ #endif
17+
18+ #ifdef __cpp_lib_containers_ranges
19+ #include < ranges>
20+ #endif
21+
22+ #ifdef __cpp_lib_three_way_comparison
23+ #include < compare>
24+ #endif
1525
1626namespace beman ::inplace_vector {
27+ #ifdef __cpp_concepts
1728namespace detail {
1829// Exposition-only container-compatible-range
1930template <typename T>
@@ -29,6 +40,7 @@ concept container_compatible_range_impl = requires(T &&t) {
2940template <typename T>
3041constexpr bool container_compatible_range =
3142 detail::container_compatible_range_impl<T>;
43+ #endif
3244
3345template <bool Condition, typename TrueType, typename FalseType>
3446using If = typename std::conditional<Condition, TrueType, FalseType>::type;
@@ -99,12 +111,12 @@ struct inplace_vector_base : public inplace_vector_destruct_base<T, Capacity> {
99111 inplace_vector_base (const inplace_vector_base &other) noexcept (
100112 std::is_nothrow_copy_constructible_v<T>)
101113 : inplace_vector_destruct_base<T, Capacity>(other.size) {
102- std::ranges:: copy (other.begin (), other.end (), begin ());
114+ std::copy (other.begin (), other.end (), begin ());
103115 }
104116 inplace_vector_base (inplace_vector_base &&other) noexcept (
105117 Capacity == 0 || std::is_nothrow_move_constructible_v<T>)
106118 : inplace_vector_destruct_base<T, Capacity>(other.size) {
107- std::ranges:: copy (other.begin (), other.end (), begin ());
119+ std::copy (other.begin (), other.end (), begin ());
108120 std::destroy (other.begin (), other.end ());
109121 other.size = 0 ;
110122 }
@@ -114,17 +126,16 @@ struct inplace_vector_base : public inplace_vector_destruct_base<T, Capacity> {
114126 const auto diff = static_cast <std::ptrdiff_t >(other.size () - size ());
115127 // other.size is less than size
116128 if (diff < 0 ) {
117- const auto new_end =
118- std::ranges::copy (other.begin (), other.end (), begin ());
129+ const auto new_end = std::copy (other.begin (), other.end (), begin ());
119130 // destroy unnecessary memory
120131 std::destroy (new_end, end ());
121132 }
122133 // other.size is greater than size
123134 else {
124135 // copy other vector into the current vector until it runs ouf of size
125- std::ranges:: copy (other.begin (), other.begin () + size (), begin ());
136+ std::copy (other.begin (), other.begin () + size (), begin ());
126137 // copy the other half after the end of the current vector
127- std::ranges:: copy (other.begin () + size (), other.end (), end ());
138+ std::copy (other.begin () + size (), other.end (), end ());
128139 }
129140 this ->size_ = other.size ();
130141 return *this ;
@@ -200,7 +211,7 @@ struct inplace_vector_base : public inplace_vector_destruct_base<T, Capacity> {
200211 template <typename Iter>
201212 static constexpr void uninitialized_copy (Iter first, Iter last,
202213 iterator dest) noexcept {
203- std::ranges:: copy (first, last, dest);
214+ std::copy (first, last, dest);
204215 }
205216
206217 template <typename Iter>
@@ -244,13 +255,15 @@ class inplace_vector : public inplace_vector_base<T, Capacity> {
244255 base::uninitialized_fill (this ->begin (), this ->end (), value);
245256 }
246257
258+ #ifdef __cpp_concepts
247259 template <class InputIterator >
248260 requires std::input_iterator<T>
249261 constexpr inplace_vector (InputIterator first, InputIterator last) : base() {
250262 for (; first != last; ++first) {
251263 emplace_back (*first);
252264 }
253265 }
266+
254267 template <class InputIterator >
255268 requires std::forward_iterator<T>
256269 constexpr inplace_vector (InputIterator first, InputIterator last)
@@ -259,15 +272,22 @@ class inplace_vector : public inplace_vector_base<T, Capacity> {
259272 base::uninitialized_copy (first, last, this ->begin ());
260273 }
261274 }
262- #ifdef __cpp_lib_containers_ranges
275+ #else
276+ template <class Itr > constexpr inplace_vector (Itr first, Itr last) : base() {
277+ for (; first != last; ++first) {
278+ emplace_back (*first);
279+ }
280+ }
281+ #endif
282+
283+ #if defined(__cpp_lib_containers_ranges) && defined(__cpp_concepts)
263284 template <typename R>
264285 requires container_compatible_range<R>
265286 constexpr inplace_vector (std::from_range_t , R &&rg) {
266287 for (auto &&value : rg) {
267288 emplace_back (std::forward<decltype (value)>(value));
268289 }
269290 }
270- #else
271291#endif
272292 constexpr inplace_vector (std::initializer_list<T> il) : base(il.size()) {
273293 if (il.size () != 0 ) {
@@ -282,14 +302,13 @@ class inplace_vector : public inplace_vector_base<T, Capacity> {
282302 // The current size is greater
283303 if (diff < 0 ) {
284304 // if other.size is less than just copy normally
285- const iterator new_end =
286- std::ranges::copy (il.begin (), il.end (), this ->begin ());
305+ const iterator new_end = std::copy (il.begin (), il.end (), this ->begin ());
287306 // destroy the wasted memory
288307 std::destroy (new_end, this ->end ());
289308 // The other size is greater than size
290309 } else {
291310 // copy other vector into the current vector until it runs ouf of size
292- std::ranges:: copy (il.begin (), il.begin () + this ->size (), this ->begin ());
311+ std::copy (il.begin (), il.begin () + this ->size (), this ->begin ());
293312 // copy the other half after the end of the current vector
294313 base::uninitialized_copy (il.begin () + this ->size (), il.end (),
295314 this ->end ());
@@ -318,6 +337,7 @@ class inplace_vector : public inplace_vector_base<T, Capacity> {
318337 }
319338 }; // freestanding-deleted
320339
340+ #if defined(__cpp_lib_containers_ranges) and defined(__cpp_concepts)
321341 template <typename R>
322342 requires container_compatible_range<R>
323343 constexpr void assign_range (R &&rg) {
@@ -340,6 +360,8 @@ class inplace_vector : public inplace_vector_base<T, Capacity> {
340360 emplace_back (*first);
341361 }
342362 }; // freestanding-deleted
363+ #endif
364+
343365 constexpr void assign (size_type n, const T &u) {
344366 if (Capacity == 0 ) {
345367 assert (size () == 0 &&
@@ -366,13 +388,12 @@ class inplace_vector : public inplace_vector_base<T, Capacity> {
366388 // other size is less than size
367389 if (diff < 0 ) {
368390 // if other.size is less than just copy normally
369- const iterator new_end =
370- std::ranges::copy (il.begin (), il.end (), this ->begin ());
391+ const iterator new_end = std::copy (il.begin (), il.end (), this ->begin ());
371392 std::destroy (new_end, this ->end );
372393 // other.size is greater than size
373394 } else {
374395 // copy other vector into the current vector until it runs ouf of size
375- std::ranges:: copy (il.begin (), il.begin () + this ->size (), this ->begin ());
396+ std::copy (il.begin (), il.begin () + this ->size (), this ->begin ());
376397 // copy the other half after the end of the current vector
377398 base::uninitialized_copy (il.begin () + this ->size (), il.end (),
378399 this ->end ());
@@ -491,6 +512,8 @@ class inplace_vector : public inplace_vector_base<T, Capacity> {
491512 }
492513 return this ->unchecked_emplace_back (std::move (x));
493514 }; // freestanding-deleted
515+
516+ #if defined(__cpp_lib_containers_ranges) and defined(__cpp_concepts)
494517 template <typename R>
495518 requires container_compatible_range<T>
496519 constexpr void append_range (R &&rg) {
@@ -500,6 +523,8 @@ class inplace_vector : public inplace_vector_base<T, Capacity> {
500523 emplace_back (*first);
501524 }
502525 }; // freestanding-deleted
526+ #endif
527+
503528 constexpr void pop_back () {
504529 if (!empty ()) {
505530 const auto end = this ->end ();
@@ -546,7 +571,10 @@ class inplace_vector : public inplace_vector_base<T, Capacity> {
546571
547572 template <class ... Args>
548573 constexpr reference unchecked_emplace_back (Args &&...args) {
549- auto final = std::construct_at (end (), std::forward<Args>(args)...);
574+ // TODO: what is the feature flag for std::construct_at ??
575+ // auto final = std::construct_at(end(), std::forward<Args>(args)...);
576+ // This is just construct_at expanded out.
577+ auto final = ::new (end ()) T (std::forward<Args>(args)...);
550578 this ->change_size (1 );
551579 return *final ;
552580 };
@@ -644,13 +672,14 @@ class inplace_vector : public inplace_vector_base<T, Capacity> {
644672 InputIterator imiddle = std::next (first, to_copy);
645673 base::uninitialized_copy (imiddle, last, end);
646674 base::uninitialized_move (pos, end, middle);
647- std::ranges:: copy (first, imiddle, pos);
675+ std::copy (first, imiddle, pos);
648676 } else {
649677 base::uninitialized_move (end - count, end, end);
650678 std::move_backward (pos, end - count, end);
651- std::ranges:: copy (first, last, pos);
679+ std::copy (first, last, pos);
652680 }
653681 } // freestanding-deleted
682+ #if defined(__cpp_lib_containers_ranges) and defined(__cpp_concepts)
654683 template <typename R>
655684 requires container_compatible_range<R>
656685 constexpr iterator insert_range (const_iterator position, R &&rg) {
@@ -665,6 +694,7 @@ class inplace_vector : public inplace_vector_base<T, Capacity> {
665694 std::rotate (pos, old_end, this ->end ());
666695 return pos;
667696 } // freestanding-deleted
697+ #endif
668698 constexpr iterator insert (const_iterator position,
669699 std::initializer_list<T> il) {
670700 const iterator pos = position;
@@ -744,10 +774,13 @@ class inplace_vector : public inplace_vector_base<T, Capacity> {
744774 return std::equal (x.begin (), x.end (), y.begin (), y.end ());
745775 }
746776
777+ #ifdef __cpp_lib_three_way_comparison
747778 constexpr friend std::compare_three_way_result<T>
748779 operator <=>(const inplace_vector &x, const inplace_vector &y) {
749780 return std::lexicographical_compare (x.begin (), x.end (), y.begin (), y.end ());
750781 };
782+ #endif
783+
751784 constexpr friend void swap (inplace_vector &x, inplace_vector &y) noexcept (
752785 Capacity == 0 || (std::is_nothrow_swappable_v<T> &&
753786 std::is_nothrow_move_constructible_v<T>)) {
0 commit comments