mirror of
https://github.com/microsoft/GSL.git
synced 2024-11-03 17:56:43 -05:00
Prevent inefficient copying when using not_null::get (#1059)
Closes issue #550, which highlighted overhead in not_null::get for larger types such as shared_ptr. Every call to get would return a copy of the contained value. This PR implements Herb's suggestion for changing the return type of not_null::get. The not_null's value will now only be copied if it is "trivially copyable"; otherwise, it will be returned by const reference. Note: this change also forces the returned copy to be const.
This commit is contained in:
parent
7d49d4b45d
commit
991fa6682e
@ -46,6 +46,17 @@ namespace details
|
||||
: std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
// Resolves to the more efficient of `const T` or `const T&`, in the context of returning a const-qualified value
|
||||
// of type T.
|
||||
//
|
||||
// Copied from cppfront's implementation of the CppCoreGuidelines F.16 (https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rf-in)
|
||||
template<typename T>
|
||||
using value_or_reference_return_t = std::conditional_t<
|
||||
sizeof(T) < 2*sizeof(void*) && std::is_trivially_copy_constructible<T>::value,
|
||||
const T,
|
||||
const T&>;
|
||||
|
||||
} // namespace details
|
||||
|
||||
//
|
||||
@ -104,7 +115,7 @@ public:
|
||||
|
||||
not_null(const not_null& other) = default;
|
||||
not_null& operator=(const not_null& other) = default;
|
||||
constexpr std::conditional_t<std::is_copy_constructible<T>::value, T, const T&> get() const
|
||||
constexpr details::value_or_reference_return_t<T> get() const
|
||||
{
|
||||
Ensures(ptr_ != nullptr);
|
||||
return ptr_;
|
||||
|
@ -52,7 +52,7 @@ template <typename T>
|
||||
struct CustomPtr
|
||||
{
|
||||
CustomPtr(T* p) : p_(p) {}
|
||||
operator T*() { return p_; }
|
||||
operator T*() const { return p_; }
|
||||
bool operator!=(std::nullptr_t) const { return p_ != nullptr; }
|
||||
T* p_ = nullptr;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user