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
|
: 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
|
} // namespace details
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -104,7 +115,7 @@ public:
|
|||||||
|
|
||||||
not_null(const not_null& other) = default;
|
not_null(const not_null& other) = default;
|
||||||
not_null& operator=(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);
|
Ensures(ptr_ != nullptr);
|
||||||
return ptr_;
|
return ptr_;
|
||||||
|
@ -52,7 +52,7 @@ template <typename T>
|
|||||||
struct CustomPtr
|
struct CustomPtr
|
||||||
{
|
{
|
||||||
CustomPtr(T* p) : p_(p) {}
|
CustomPtr(T* p) : p_(p) {}
|
||||||
operator T*() { return p_; }
|
operator T*() const { return p_; }
|
||||||
bool operator!=(std::nullptr_t) const { return p_ != nullptr; }
|
bool operator!=(std::nullptr_t) const { return p_ != nullptr; }
|
||||||
T* p_ = nullptr;
|
T* p_ = nullptr;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user