Remove JSON_HAS_STRING_VIEW

Instead implement @gregmarr's PR comments that perfect forwarding should be used. Also cleaned up cpp language standard detection.
This commit is contained in:
Jamie Seward 2017-10-23 00:43:26 -07:00
parent d468f8c4e6
commit 33c6511dd0
2 changed files with 70 additions and 32 deletions

View file

@ -109,16 +109,14 @@ SOFTWARE.
#define JSON_UNLIKELY(x) x #define JSON_UNLIKELY(x) x
#endif #endif
// string_view support // cpp language standard detection
#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_MSC_VER) && _MSC_VER > 1900 && defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
#define JSON_HAS_STRING_VIEW #define JSON_HAS_CPP_17
#define JSON_HAS_CPP_14
#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
#define JSON_HAS_CPP_14
#endif #endif
#if defined(JSON_HAS_STRING_VIEW)
#include <string_view>
#endif
/*! /*!
@brief namespace for Niels Lohmann @brief namespace for Niels Lohmann
@see https://github.com/nlohmann @see https://github.com/nlohmann
@ -7600,26 +7598,18 @@ class basic_json
specified "unordered" nature of JSON objects. specified "unordered" nature of JSON objects.
*/ */
#if defined(JSON_HAS_STRING_VIEW) #if defined(JSON_HAS_CPP_14)
// if std::string_view is to be used the object_t must // Use transparent comparator if possible, combined with perfect forwarding
// be declared with a transparent comparator // on find() and count() calls prevents unnecessary string construction.
// https://stackoverflow.com/questions/35525777/use-of-string-view-for-map-lookup using object_comparator_t = std::less<>;
using object_t = ObjectType<StringType,
basic_json,
std::less<>,
AllocatorType<std::pair<const StringType,
basic_json>>>;
using object_comparator_key_t = std::string_view;
#else #else
using object_t = ObjectType<StringType, using object_comparator_t = std::less<StringType>;
basic_json,
std::less<StringType>,
AllocatorType<std::pair<const StringType,
basic_json>>>;
using object_comparator_key_t = typename object_t::key_type;
#endif #endif
using object_t = ObjectType<StringType,
basic_json,
object_comparator_t,
AllocatorType<std::pair<const StringType,
basic_json>>>;
/*! /*!
@brief a type for an array @brief a type for an array
@ -9868,7 +9858,7 @@ class basic_json
#ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015 #ifndef _MSC_VER // fix for issue #167 operator<< ambiguity under VS2015
and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value and not std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
#endif #endif
#if defined(JSON_HAS_STRING_VIEW) #if defined(JSON_HAS_CPP_17)
and not std::is_same<ValueType, typename std::string_view>::value and not std::is_same<ValueType, typename std::string_view>::value
#endif #endif
, int >::type = 0 > , int >::type = 0 >
@ -10906,7 +10896,7 @@ class basic_json
@since version 1.0.0 @since version 1.0.0
*/ */
iterator find(object_comparator_key_t key) iterator find(typename object_t::key_type key)
{ {
auto result = end(); auto result = end();
@ -10920,9 +10910,9 @@ class basic_json
/*! /*!
@brief find an element in a JSON object @brief find an element in a JSON object
@copydoc find(object_transparent_comparator_key_t) @copydoc find(typename object_t::key_type)
*/ */
const_iterator find(object_comparator_key_t key) const const_iterator find(typename object_t::key_type key) const
{ {
auto result = cend(); auto result = cend();
@ -10934,6 +10924,42 @@ class basic_json
return result; return result;
} }
#ifdef JSON_HAS_CPP_14
/*!
@brief find an element in a JSON object
@copydoc find(typename object_t::key_type)
*/
template<typename KeyT>
iterator find(KeyT&& key)
{
auto result = end();
if (is_object())
{
result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
}
return result;
}
/*!
@brief find an element in a JSON object
@copydoc find(typename object_t::key_type)
*/
template<typename KeyT>
const_iterator find(KeyT&& key) const
{
auto result = cend();
if (is_object())
{
result.m_it.object_iterator = m_value.object->find(std::forward<KeyT>(key));
}
return result;
}
#endif
/*! /*!
@brief returns the number of occurrences of a key in a JSON object @brief returns the number of occurrences of a key in a JSON object
@ -10955,12 +10981,24 @@ class basic_json
@since version 1.0.0 @since version 1.0.0
*/ */
size_type count(object_comparator_key_t key) const size_type count(typename object_t::key_type key) const
{ {
// return 0 for all nonobject types // return 0 for all nonobject types
return is_object() ? m_value.object->count(key) : 0; return is_object() ? m_value.object->count(key) : 0;
} }
#ifdef JSON_HAS_CPP_14
/*!
@brief returns the number of occurrences of a key in a JSON object
@copydoc count(typename object_t::key_type)
*/
template<typename KeyT>
size_type count(KeyT&& key) const
{
// return 0 for all nonobject types
return is_object() ? m_value.object->count(std::forward<KeyT>(key)) : 0;
}
#endif
/// @} /// @}

View file

@ -82,7 +82,7 @@ if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4389 /wd4309 /wd4566 /wd4996") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4389 /wd4309 /wd4566 /wd4996")
if(MSVC_VERSION GREATER_EQUAL 1910) if(MSVC_VERSION GREATER_EQUAL 1910)
# Enable c++17 support in Visual Studio 2017 (for testing string_view support) # Enable c++17 support in Visual Studio 2017 (for testing perfect forwarding and transparent comparator in find() / count())
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17")
endif() endif()
endif() endif()