4
4
#ifndef _MSFT_PROXY_
5
5
#define _MSFT_PROXY_
6
6
7
- #include < cstring>
8
7
#include < bit>
9
8
#include < concepts>
10
9
#include < initializer_list>
@@ -197,8 +196,8 @@ void copying_dispatcher(char* self, const char* rhs)
197
196
}
198
197
template <std::size_t Len, std::size_t Align>
199
198
void copying_default_dispatcher (char * self, const char * rhs) noexcept {
200
- std::memcpy (std::assume_aligned<Align>(self),
201
- std::assume_aligned<Align>(rhs), Len);
199
+ std::uninitialized_copy_n (
200
+ std::assume_aligned<Align>(rhs), Len, std::assume_aligned<Align>(self) );
202
201
}
203
202
template <class P >
204
203
void relocation_dispatcher (char * self, const char * rhs)
@@ -525,7 +524,7 @@ class proxy {
525
524
if (rhs.meta_ .has_value ()) {
526
525
if constexpr (F::constraints.relocatability ==
527
526
constraint_level::trivial) {
528
- memcpy (ptr_, rhs.ptr_ , F::constraints. max_size );
527
+ std::ranges::uninitialized_copy ( rhs.ptr_ , ptr_ );
529
528
} else {
530
529
rhs.meta_ ->Traits ::relocatability_meta::dispatcher (ptr_, rhs.ptr_ );
531
530
}
@@ -698,23 +697,25 @@ constexpr proxiable_ptr_constraints trivial_ptr_constraints{
698
697
namespace details {
699
698
700
699
template <class T >
701
- class sbo_ptr {
700
+ class inplace_ptr {
702
701
public:
703
702
template <class ... Args>
704
- sbo_ptr (Args&&... args) noexcept (std::is_nothrow_constructible_v<T, Args...>)
703
+ inplace_ptr (Args&&... args)
704
+ noexcept (std::is_nothrow_constructible_v<T, Args...>)
705
705
requires (std::is_constructible_v<T, Args...>)
706
706
: value_(std::forward<Args>(args)...) {}
707
- sbo_ptr (const sbo_ptr&) noexcept (std::is_nothrow_copy_constructible_v<T> )
708
- = default ;
709
- sbo_ptr (sbo_ptr&&) noexcept (std::is_nothrow_move_constructible_v<T> )
710
- = default ;
707
+ inplace_ptr (const inplace_ptr& )
708
+ noexcept (std::is_nothrow_copy_constructible_v<T>) = default ;
709
+ inplace_ptr (inplace_ptr&& )
710
+ noexcept (std::is_nothrow_move_constructible_v<T>) = default ;
711
711
712
712
T* operator ->() const noexcept { return &value_; }
713
713
714
714
private:
715
715
mutable T value_;
716
716
};
717
717
718
+ #if __STDC_HOSTED__
718
719
template <class T , class Alloc >
719
720
static auto rebind_allocator (const Alloc& alloc) {
720
721
return typename std::allocator_traits<Alloc>::template rebind_alloc<T>(alloc);
@@ -761,7 +762,6 @@ class allocated_ptr {
761
762
Alloc alloc_;
762
763
T* ptr_;
763
764
};
764
-
765
765
template <class T , class Alloc >
766
766
class compact_ptr {
767
767
public:
@@ -782,36 +782,63 @@ class compact_ptr {
782
782
struct storage {
783
783
template <class ... Args>
784
784
explicit storage (const Alloc& alloc, Args&&... args)
785
- : alloc(alloc), value(std::forward<Args>(args)...) {}
785
+ : value(std::forward<Args>(args)...), alloc(alloc ) {}
786
786
787
- Alloc alloc;
788
787
T value;
788
+ Alloc alloc;
789
789
};
790
790
791
791
storage* ptr_;
792
792
};
793
-
794
793
template <class F , class T , class Alloc , class ... Args>
795
794
proxy<F> allocate_proxy_impl (const Alloc& alloc, Args&&... args) {
796
- if constexpr (proxiable<details::sbo_ptr<T>, F>) {
797
- return proxy<F>{std::in_place_type<details::sbo_ptr<T>>,
798
- std::forward<Args>(args)...};
799
- } else if constexpr (proxiable<details::allocated_ptr<T, Alloc>, F>) {
800
- return proxy<F>{std::in_place_type<details::allocated_ptr<T, Alloc>>,
795
+ if constexpr (proxiable<allocated_ptr<T, Alloc>, F>) {
796
+ return proxy<F>{std::in_place_type<allocated_ptr<T, Alloc>>,
801
797
alloc, std::forward<Args>(args)...};
802
798
} else {
803
- return proxy<F>{std::in_place_type<details:: compact_ptr<T, Alloc>>,
799
+ return proxy<F>{std::in_place_type<compact_ptr<T, Alloc>>,
804
800
alloc, std::forward<Args>(args)...};
805
801
}
806
802
}
807
803
template <class F , class T , class ... Args>
808
804
proxy<F> make_proxy_impl (Args&&... args) {
809
- return allocate_proxy_impl<F, T>(
810
- std::allocator<T>{}, std::forward<Args>(args)...);
805
+ if constexpr (proxiable<inplace_ptr<T>, F>) {
806
+ return proxy<F>{std::in_place_type<inplace_ptr<T>>,
807
+ std::forward<Args>(args)...};
808
+ } else {
809
+ return allocate_proxy_impl<F, T>(
810
+ std::allocator<T>{}, std::forward<Args>(args)...);
811
+ }
811
812
}
813
+ #endif // __STDC_HOSTED__
812
814
813
815
} // namespace details
814
816
817
+ template <class T , class F >
818
+ concept inplace_proxiable_target = proxiable<details::inplace_ptr<T>, F>;
819
+
820
+ template <facade F, inplace_proxiable_target<F> T, class ... Args>
821
+ proxy<F> make_proxy_inplace (Args&&... args)
822
+ noexcept (std::is_nothrow_constructible_v<T, Args...>) {
823
+ return proxy<F>{std::in_place_type<details::inplace_ptr<T>>,
824
+ std::forward<Args>(args)...};
825
+ }
826
+ template <facade F, inplace_proxiable_target<F> T, class U , class ... Args>
827
+ proxy<F> make_proxy_inplace (std::initializer_list<U> il, Args&&... args)
828
+ noexcept (std::is_nothrow_constructible_v<
829
+ T, std::initializer_list<U>&, Args...>) {
830
+ return proxy<F>{std::in_place_type<details::inplace_ptr<T>>,
831
+ il, std::forward<Args>(args)...};
832
+ }
833
+ template <facade F, class T >
834
+ proxy<F> make_proxy_inplace (T&& value)
835
+ noexcept (std::is_nothrow_constructible_v<std::decay_t <T>, T>)
836
+ requires(inplace_proxiable_target<std::decay_t <T>, F>) {
837
+ return proxy<F>{std::in_place_type<details::inplace_ptr<std::decay_t <T>>>,
838
+ std::forward<T>(value)};
839
+ }
840
+
841
+ #if __STDC_HOSTED__
815
842
template <facade F, class T , class Alloc , class ... Args>
816
843
proxy<F> allocate_proxy (const Alloc& alloc, Args&&... args) {
817
844
return details::allocate_proxy_impl<F, T>(alloc, std::forward<Args>(args)...);
@@ -837,6 +864,7 @@ template <facade F, class T>
837
864
proxy<F> make_proxy (T&& value) {
838
865
return details::make_proxy_impl<F, std::decay_t <T>>(std::forward<T>(value));
839
866
}
867
+ #endif // __STDC_HOSTED__
840
868
841
869
// The following types and macros aim to simplify definition of dispatch and
842
870
// facade types prior to C++26
0 commit comments