33#ifndef BEMAN_INPLACE_VECTOR_INPLACE_VECTOR_HPP
44#define BEMAN_INPLACE_VECTOR_INPLACE_VECTOR_HPP
55
6+ #if !defined(__has_include) || __has_include(<beman/inplace_vector/config.hpp>)
7+ #include < beman/inplace_vector/config.hpp>
8+ #endif
9+
610#include < algorithm> // for rotate...
711#include < array>
812#include < compare>
913#include < concepts> // for lots...
1014#include < cstddef> // for size_t
1115#include < cstdint> // for fixed-width integer types
1216#include < cstdio> // for assertion diagnostics
13- #include < cstdlib> // for abort
1417#include < functional> // for less and equal_to
1518#include < iterator> // for reverse_iterator and iterator traits
1619#include < limits> // for numeric_limits
1720#include < memory> // for destroy
1821#include < new> // for operator new
1922#include < ranges>
20- #include < stdexcept> // for length_error
2123#include < type_traits> // for aligned_storage and all meta-functions
2224
2325// Artifact from previous implementation, can be used as hints for optimizer
2426#define IV_EXPECT (EXPR )
2527
28+ #ifndef BEMAN_IV_THROW_OR_ABORT
29+ #if BEMAN_INPLACE_VECTOR_NO_EXCEPTIONS()
30+ #include < cstdlib> // for abort
31+ #define BEMAN_IV_THROW_OR_ABORT (x ) abort()
32+ #else
33+ #include < stdexcept> // for length_error
34+ #define BEMAN_IV_THROW_OR_ABORT (x ) throw x
35+ #endif
36+ #endif
37+
2638// beman::from_range_t
2739namespace beman {
2840struct from_range_t {};
@@ -260,8 +272,9 @@ struct inplace_vector
260272 static constexpr size_type max_size () noexcept { return N; }
261273 static constexpr size_type capacity () noexcept { return N; }
262274 constexpr void reserve (size_type n) {
263- if (n > N) [[unlikely]]
264- throw std::bad_alloc ();
275+ if (n > N) [[unlikely]] {
276+ BEMAN_IV_THROW_OR_ABORT (std::bad_alloc ());
277+ }
265278 }
266279 constexpr void shrink_to_fit () {}
267280
@@ -351,8 +364,9 @@ struct inplace_vector
351364 constexpr T &emplace_back (Args &&...args)
352365 requires(std::constructible_from<T, Args...>)
353366 {
354- if (!try_emplace_back (std::forward<Args>(args)...)) [[unlikely]]
355- throw std::bad_alloc ();
367+ if (!try_emplace_back (std::forward<Args>(args)...)) [[unlikely]] {
368+ BEMAN_IV_THROW_OR_ABORT (std::bad_alloc ());
369+ }
356370 return back ();
357371 }
358372 constexpr T &push_back (const T &x)
@@ -395,12 +409,14 @@ struct inplace_vector
395409 requires(std::constructible_from<T, std::ranges::range_reference_t <R>>)
396410 {
397411 if constexpr (std::ranges::sized_range<R>) {
398- if (size () + std::ranges::size (rg) > capacity ()) [[unlikely]]
399- throw std::bad_alloc ();
412+ if (size () + std::ranges::size (rg) > capacity ()) [[unlikely]] {
413+ BEMAN_IV_THROW_OR_ABORT (std::bad_alloc ());
414+ }
400415 }
401416 for (auto &&e : rg) {
402- if (size () == capacity ()) [[unlikely]]
403- throw std::bad_alloc ();
417+ if (size () == capacity ()) [[unlikely]] {
418+ BEMAN_IV_THROW_OR_ABORT (std::bad_alloc ());
419+ }
404420 emplace_back (std::forward<decltype (e)>(e));
405421 }
406422 }
@@ -438,8 +454,9 @@ struct inplace_vector
438454 assert_iterator_in_range (position);
439455 if constexpr (std::random_access_iterator<InputIterator>) {
440456 if (size () + static_cast <size_type>(std::distance (first, last)) >
441- capacity ()) [[unlikely]]
442- throw std::bad_alloc{};
457+ capacity ()) [[unlikely]] {
458+ BEMAN_IV_THROW_OR_ABORT (std::bad_alloc ());
459+ }
443460 }
444461 auto b = end ();
445462 for (; first != last; ++first)
@@ -555,9 +572,9 @@ struct inplace_vector
555572 {
556573 if (sz == size ())
557574 return ;
558- else if (sz > N) [[unlikely]]
559- throw std::bad_alloc{} ;
560- else if (sz > size ())
575+ else if (sz > N) [[unlikely]] {
576+ BEMAN_IV_THROW_OR_ABORT ( std::bad_alloc ()) ;
577+ } else if (sz > size ())
561578 insert (end (), sz - size (), c);
562579 else {
563580 unsafe_destroy (begin () + sz, end ());
@@ -569,25 +586,27 @@ struct inplace_vector
569586 {
570587 if (sz == size ())
571588 return ;
572- else if (sz > N) [[unlikely]]
573- throw std::bad_alloc{} ;
574- else if (sz > size ())
589+ else if (sz > N) [[unlikely]] {
590+ BEMAN_IV_THROW_OR_ABORT ( std::bad_alloc ()) ;
591+ } else if (sz > size ()) {
575592 while (size () != sz)
576593 emplace_back (T{});
577- else {
594+ } else {
578595 unsafe_destroy (begin () + sz, end ());
579596 unsafe_set_size (sz);
580597 }
581598 }
582599
583600 constexpr reference at (size_type pos) {
584- if (pos >= size ()) [[unlikely]]
585- throw std::out_of_range (" inplace_vector::at" );
601+ if (pos >= size ()) [[unlikely]] {
602+ BEMAN_IV_THROW_OR_ABORT (std::out_of_range (" inplace_vector::at" ));
603+ }
586604 return details::inplace_vector::index (*this , pos);
587605 }
588606 constexpr const_reference at (size_type pos) const {
589- if (pos >= size ()) [[unlikely]]
590- throw std::out_of_range (" inplace_vector::at" );
607+ if (pos >= size ()) [[unlikely]] {
608+ BEMAN_IV_THROW_OR_ABORT (std::out_of_range (" inplace_vector::at" ));
609+ }
591610 return details::inplace_vector::index (*this , pos);
592611 }
593612
@@ -606,7 +625,7 @@ struct inplace_vector
606625 std::copyable<T>)
607626 {
608627 for (auto &&e : x)
609- emplace_back (e);
628+ unchecked_emplace_back (e);
610629 }
611630
612631 constexpr inplace_vector (inplace_vector &&x)
@@ -618,7 +637,7 @@ struct inplace_vector
618637 std::movable<T>)
619638 {
620639 for (auto &&e : x)
621- emplace_back (std::move (e));
640+ unchecked_emplace_back (std::move (e));
622641 }
623642
624643 constexpr inplace_vector &operator =(const inplace_vector &x)
@@ -636,7 +655,7 @@ struct inplace_vector
636655 {
637656 clear ();
638657 for (auto &&e : x)
639- emplace_back (e);
658+ unchecked_emplace_back (e);
640659 return *this ;
641660 }
642661
@@ -655,7 +674,7 @@ struct inplace_vector
655674 {
656675 clear ();
657676 for (auto &&e : x)
658- emplace_back (std::move (e));
677+ unchecked_emplace_back (std::move (e));
659678 return *this ;
660679 }
661680
0 commit comments