diff --git a/include/gsl/pointers b/include/gsl/pointers index a0a77ac..94a7192 100644 --- a/include/gsl/pointers +++ b/include/gsl/pointers @@ -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 + using value_or_reference_return_t = std::conditional_t< + sizeof(T) < 2*sizeof(void*) && std::is_trivially_copy_constructible::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::value, T, const T&> get() const + constexpr details::value_or_reference_return_t get() const { Ensures(ptr_ != nullptr); return ptr_; diff --git a/tests/notnull_tests.cpp b/tests/notnull_tests.cpp index ccb652a..420c87b 100644 --- a/tests/notnull_tests.cpp +++ b/tests/notnull_tests.cpp @@ -52,7 +52,7 @@ template 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; };