mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Add enable_if_lvalue
This commit is contained in:
committed by
Tom Ritchford
parent
5c67f99ef9
commit
612bb71165
@@ -20,7 +20,7 @@
|
||||
#ifndef BEAST_UTILITY_META_H_INCLUDED
|
||||
#define BEAST_UTILITY_META_H_INCLUDED
|
||||
|
||||
#include <type_traits>
|
||||
#include <beast/cxx14/type_traits.h> // <type_traits>
|
||||
|
||||
namespace beast {
|
||||
|
||||
@@ -60,6 +60,81 @@ struct static_sum<>
|
||||
|
||||
static_assert(static_sum<5, 2, 17, 0>::value == 24, "");
|
||||
|
||||
template <class T, class U>
|
||||
struct enable_if_lvalue
|
||||
: public std::enable_if
|
||||
<
|
||||
std::is_same<std::decay_t<T>, U>::value &&
|
||||
std::is_lvalue_reference<T>::value
|
||||
>
|
||||
{
|
||||
};
|
||||
|
||||
/** Ensure const reference function parameters are valid lvalues.
|
||||
|
||||
Some functions, especially class constructors, accept const references and
|
||||
store them for later use. If any of those parameters are rvalue objects,
|
||||
the object will be freed as soon as the function returns. This could
|
||||
potentially lead to a variety of "use after free" errors.
|
||||
|
||||
If the function is rewritten as a template using this type and the
|
||||
parameters references as rvalue references (eg. TX&&), a compiler
|
||||
error will be generated if an rvalue is provided in the caller.
|
||||
|
||||
@code
|
||||
// Example:
|
||||
struct X
|
||||
{
|
||||
};
|
||||
struct Y
|
||||
{
|
||||
};
|
||||
|
||||
struct Unsafe
|
||||
{
|
||||
Unsafe (X const& x, Y const& y)
|
||||
: x_ (x)
|
||||
, y_ (y)
|
||||
{
|
||||
}
|
||||
|
||||
X const& x_;
|
||||
Y const& y_;
|
||||
};
|
||||
|
||||
struct Safe
|
||||
{
|
||||
template <class TX, class TY,
|
||||
class = beast::enable_if_lvalue_t<TX, X>,
|
||||
class = beast::enable_if_lvalue_t < TY, Y >>
|
||||
Safe (TX&& x, TY&& y)
|
||||
: x_ (x)
|
||||
, y_ (y)
|
||||
{
|
||||
}
|
||||
|
||||
X const& x_;
|
||||
Y const& y_;
|
||||
};
|
||||
|
||||
struct demo
|
||||
{
|
||||
void
|
||||
createObjects ()
|
||||
{
|
||||
X x {};
|
||||
Y const y {};
|
||||
Unsafe u1 (x, y); // ok
|
||||
Unsafe u2 (X (), y); // compiles, but u2.x_ becomes invalid at the end of the line.
|
||||
Safe s1 (x, y); // ok
|
||||
// Safe s2 (X (), y); // compile-time error
|
||||
}
|
||||
};
|
||||
@endcode
|
||||
*/
|
||||
template <class T, class U>
|
||||
using enable_if_lvalue_t = typename enable_if_lvalue<T, U>::type;
|
||||
|
||||
} // beast
|
||||
|
||||
#endif // BEAST_UTILITY_META_H_INCLUDED
|
||||
|
||||
Reference in New Issue
Block a user