add static_asserts/remove the need for CopyConstructible in get

This commit is contained in:
Théo DELRIEU 2017-01-21 17:56:59 +01:00
parent ba0b35f414
commit 9c6ef74a28
2 changed files with 24 additions and 18 deletions

View file

@ -3073,8 +3073,11 @@ class basic_json
@since version 2.1.0 @since version 2.1.0
*/ */
template <typename T, template <
detail::enable_if_t<std::is_same<T, basic_json_t>::value, int> = 0> typename T,
detail::enable_if_t<std::is_same<typename std::remove_const<T>::type,
basic_json_t>::value,
int> = 0 >
basic_json get() const basic_json get() const
{ {
return *this; return *this;
@ -3104,16 +3107,15 @@ class basic_json
not detail::has_non_default_from_json<basic_json_t, not detail::has_non_default_from_json<basic_json_t,
U>::value, U>::value,
int > = 0 > int > = 0 >
// do we really want the uncvref ? if a user call get<int &>, shouldn't we
// static assert ?
// i know there is a special behaviour for boolean_t* and such
U get() const noexcept(noexcept(JSONSerializer<U>::from_json( U get() const noexcept(noexcept(JSONSerializer<U>::from_json(
std::declval<const basic_json_t&>(), std::declval<U&>()))) std::declval<const basic_json_t&>(), std::declval<U&>())))
{ {
static_assert(std::is_default_constructible<U>::value and // we cannot static_assert on T being non-const, because there is support
std::is_copy_constructible<U>::value, // for get<const basic_json_t>(), which is why we still need the uncvref
"Types must be DefaultConstructible and " static_assert(not std::is_reference<T>::value, "get cannot be used with reference types, you might want to use get_ref");
"CopyConstructible when used with get"); static_assert(not std::is_pointer<T>::value, "get cannot be used with pointer types, you might want to use get_ptr");
static_assert(std::is_default_constructible<U>::value,
"Types must be DefaultConstructible when used with get");
U ret; U ret;
JSONSerializer<U>::from_json(*this, ret); JSONSerializer<U>::from_json(*this, ret);
return ret; return ret;
@ -3143,6 +3145,8 @@ class basic_json
int> = 0 > int> = 0 >
U get() const noexcept(noexcept(JSONSerializer<T>::from_json(std::declval<const basic_json_t&>()))) U get() const noexcept(noexcept(JSONSerializer<T>::from_json(std::declval<const basic_json_t&>())))
{ {
static_assert(not std::is_reference<T>::value, "get cannot be used with reference types, you might want to use get_ref");
static_assert(not std::is_pointer<T>::value, "get cannot be used with pointer types, you might want to use get_ptr");
return JSONSerializer<T>::from_json(*this); return JSONSerializer<T>::from_json(*this);
} }

View file

@ -3073,8 +3073,11 @@ class basic_json
@since version 2.1.0 @since version 2.1.0
*/ */
template <typename T, template <
detail::enable_if_t<std::is_same<T, basic_json_t>::value, int> = 0> typename T,
detail::enable_if_t<std::is_same<typename std::remove_const<T>::type,
basic_json_t>::value,
int> = 0 >
basic_json get() const basic_json get() const
{ {
return *this; return *this;
@ -3104,16 +3107,14 @@ class basic_json
not detail::has_non_default_from_json<basic_json_t, not detail::has_non_default_from_json<basic_json_t,
U>::value, U>::value,
int > = 0 > int > = 0 >
// do we really want the uncvref ? if a user call get<int &>, shouldn't we
// static assert ?
// i know there is a special behaviour for boolean_t* and such
U get() const noexcept(noexcept(JSONSerializer<U>::from_json( U get() const noexcept(noexcept(JSONSerializer<U>::from_json(
std::declval<const basic_json_t&>(), std::declval<U&>()))) std::declval<const basic_json_t&>(), std::declval<U&>())))
{ {
static_assert(std::is_default_constructible<U>::value and // we cannot static_assert on T being non-const, because there is support
std::is_copy_constructible<U>::value, // for get<const basic_json_t>(), which is why we still need the uncvref
"Types must be DefaultConstructible and " static_assert(not std::is_reference<T>::value, "get cannot be used with reference types, you might want to use get_ref");
"CopyConstructible when used with get"); static_assert(std::is_default_constructible<U>::value,
"Types must be DefaultConstructible when used with get");
U ret; U ret;
JSONSerializer<U>::from_json(*this, ret); JSONSerializer<U>::from_json(*this, ret);
return ret; return ret;
@ -3143,6 +3144,7 @@ class basic_json
int> = 0 > int> = 0 >
U get() const noexcept(noexcept(JSONSerializer<T>::from_json(std::declval<const basic_json_t&>()))) U get() const noexcept(noexcept(JSONSerializer<T>::from_json(std::declval<const basic_json_t&>())))
{ {
static_assert(not std::is_reference<T>::value, "get cannot be used with reference types, you might want to use get_ref");
return JSONSerializer<T>::from_json(*this); return JSONSerializer<T>::from_json(*this);
} }