Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to use string_view from std::experimental #2364

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ matrix:
compiler: gcc
env:
- COMPILER=g++-9
- CXXFLAGS=-std=c++2a
- CXX_STANDARD=17
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be better to specify CXX_STANDARD=20, however, cmake v3.9.2 at Travis doesn't support such option. Anyway, this setting had no effect before.

addons:
apt:
sources: ['ubuntu-toolchain-r-test']
Expand Down Expand Up @@ -306,7 +306,7 @@ matrix:
compiler: clang
env:
- COMPILER=clang++-7
- CXXFLAGS=-std=c++1z
- CXX_STANDARD=17
addons:
apt:
sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-7']
Expand All @@ -333,6 +333,12 @@ script:
# by default, use implicit conversions
- if [[ "${IMPLICIT_CONVERSIONS}" == "" ]]; then export IMPLICIT_CONVERSIONS=ON; fi

# append CXX_STANDARD to CMAKE_OPTIONS if required
- CMAKE_OPTIONS+=${CXX_STANDARD:+ -DCMAKE_CXX_STANDARD=$CXX_STANDARD -DCMAKE_CXX_STANDARD_REQUIRED=ON}

# force verbose build
- CMAKE_OPTIONS+=" -DCMAKE_VERBOSE_MAKEFILE=ON"

# compile and execute unit tests
- mkdir -p build && cd build
- cmake .. ${CMAKE_OPTIONS} -DJSON_MultipleHeaders=${MULTIPLE_HEADERS} -DJSON_ImplicitConversions=${IMPLICIT_CONVERSIONS} -DJSON_BuildTests=On -GNinja && cmake --build . --config Release
Expand Down
19 changes: 19 additions & 0 deletions include/nlohmann/detail/macro_scope.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,25 @@
#define JSON_HAS_CPP_14
#endif

namespace nlohmann {
namespace std_aliases { }
using namespace std_aliases;
}

#if defined(JSON_HAS_CPP_17)
#if __has_include(<string_view>)
#include <string_view>
namespace nlohmann::std_aliases {
using std::string_view;
}
#elif __has_include(<experimental/string_view>)
#include <experimental/string_view>
namespace nlohmann::std_aliases {
using std::experimental::string_view;
}
#endif
#endif

// disable float-equal warnings on GCC/clang
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
#pragma GCC diagnostic push
Expand Down
2 changes: 1 addition & 1 deletion include/nlohmann/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3230,7 +3230,7 @@ class basic_json
!detail::is_basic_json<ValueType>::value
&& !std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
&& !std::is_same<ValueType, typename std::string_view>::value
&& !std::is_same<ValueType, string_view>::value
#endif
&& detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
, int >::type = 0 >
Expand Down
21 changes: 20 additions & 1 deletion single_include/nlohmann/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2048,6 +2048,25 @@ JSON_HEDLEY_DIAGNOSTIC_POP
#define JSON_HAS_CPP_14
#endif

namespace nlohmann {
namespace std_aliases { }
using namespace std_aliases;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This introduces a mix of qualified and unqualified names in source code. E.g. we have std::string but string_view instead of std::string_view. We cannot introduce any names (such as std::expermental::string_view) directly into std. There is other option to consider:

namespace nlohmann {
    namespace std_aliases {
        using namespace std;
    }
}

This allows regular qualification approach (std_aliases::string and std_aliases::string_view) but requires a lots of changes in almost all files.

}

#if defined(JSON_HAS_CPP_17)
#if __has_include(<string_view>)
#include <string_view>
namespace nlohmann::std_aliases {
using std::string_view;
}
#elif __has_include(<experimental/string_view>)
#include <experimental/string_view>
namespace nlohmann::std_aliases {
using std::experimental::string_view;
}
#endif
#endif

// disable float-equal warnings on GCC/clang
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
#pragma GCC diagnostic push
Expand Down Expand Up @@ -19736,7 +19755,7 @@ class basic_json
!detail::is_basic_json<ValueType>::value
&& !std::is_same<ValueType, std::initializer_list<typename string_t::value_type>>::value
#if defined(JSON_HAS_CPP_17) && (defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER <= 1914))
&& !std::is_same<ValueType, typename std::string_view>::value
&& !std::is_same<ValueType, string_view>::value
#endif
&& detail::is_detected<detail::get_template_function, const basic_json_t&, ValueType>::value
, int >::type = 0 >
Expand Down
39 changes: 18 additions & 21 deletions test/src/unit-conversions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ SOFTWARE.
#define JSON_TESTS_PRIVATE
#include <nlohmann/json.hpp>
using nlohmann::json;
using namespace nlohmann::std_aliases;

#include <deque>
#include <forward_list>
Expand All @@ -48,10 +49,6 @@ using nlohmann::json;
#define JSON_HAS_CPP_14
#endif

#if defined(JSON_HAS_CPP_17)
#include <string_view>
#endif

TEST_CASE("value conversion")
{
SECTION("get an object (explicit)")
Expand Down Expand Up @@ -465,7 +462,7 @@ TEST_CASE("value conversion")
#if defined(JSON_HAS_CPP_17)
SECTION("std::string_view")
{
std::string_view s = j.get<std::string_view>();
string_view s = j.get<string_view>();
CHECK(json(s) == j);
}
#endif
Expand Down Expand Up @@ -514,27 +511,27 @@ TEST_CASE("value conversion")
#if defined(JSON_HAS_CPP_17)
SECTION("exception in case of a non-string type using string_view")
{
CHECK_THROWS_AS(json(json::value_t::null).get<std::string_view>(), json::type_error&);
CHECK_THROWS_AS(json(json::value_t::object).get<std::string_view>(), json::type_error&);
CHECK_THROWS_AS(json(json::value_t::array).get<std::string_view>(), json::type_error&);
CHECK_THROWS_AS(json(json::value_t::boolean).get<std::string_view>(), json::type_error&);
CHECK_THROWS_AS(json(json::value_t::number_integer).get<std::string_view>(), json::type_error&);
CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<std::string_view>(), json::type_error&);
CHECK_THROWS_AS(json(json::value_t::number_float).get<std::string_view>(), json::type_error&);
CHECK_THROWS_AS(json(json::value_t::null).get<string_view>(), json::type_error&);
CHECK_THROWS_AS(json(json::value_t::object).get<string_view>(), json::type_error&);
CHECK_THROWS_AS(json(json::value_t::array).get<string_view>(), json::type_error&);
CHECK_THROWS_AS(json(json::value_t::boolean).get<string_view>(), json::type_error&);
CHECK_THROWS_AS(json(json::value_t::number_integer).get<string_view>(), json::type_error&);
CHECK_THROWS_AS(json(json::value_t::number_unsigned).get<string_view>(), json::type_error&);
CHECK_THROWS_AS(json(json::value_t::number_float).get<string_view>(), json::type_error&);

CHECK_THROWS_WITH(json(json::value_t::null).get<std::string_view>(),
CHECK_THROWS_WITH(json(json::value_t::null).get<string_view>(),
"[json.exception.type_error.302] type must be string, but is null");
CHECK_THROWS_WITH(json(json::value_t::object).get<std::string_view>(),
CHECK_THROWS_WITH(json(json::value_t::object).get<string_view>(),
"[json.exception.type_error.302] type must be string, but is object");
CHECK_THROWS_WITH(json(json::value_t::array).get<std::string_view>(),
CHECK_THROWS_WITH(json(json::value_t::array).get<string_view>(),
"[json.exception.type_error.302] type must be string, but is array");
CHECK_THROWS_WITH(json(json::value_t::boolean).get<std::string_view>(),
CHECK_THROWS_WITH(json(json::value_t::boolean).get<string_view>(),
"[json.exception.type_error.302] type must be string, but is boolean");
CHECK_THROWS_WITH(json(json::value_t::number_integer).get<std::string_view>(),
CHECK_THROWS_WITH(json(json::value_t::number_integer).get<string_view>(),
"[json.exception.type_error.302] type must be string, but is number");
CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<std::string_view>(),
CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get<string_view>(),
"[json.exception.type_error.302] type must be string, but is number");
CHECK_THROWS_WITH(json(json::value_t::number_float).get<std::string_view>(),
CHECK_THROWS_WITH(json(json::value_t::number_float).get<string_view>(),
"[json.exception.type_error.302] type must be string, but is number");
}
#endif
Expand Down Expand Up @@ -562,7 +559,7 @@ TEST_CASE("value conversion")
SECTION("std::string_view")
{
std::string s = "previous value";
std::string_view sv = s;
string_view sv = s;
j.get_to(sv);
CHECK(json(sv) == j);
}
Expand Down Expand Up @@ -617,7 +614,7 @@ TEST_CASE("value conversion")
#if defined(JSON_HAS_CPP_17)
SECTION("std::string_view")
{
std::string_view s = j.get<std::string_view>();
string_view s = j.get<string_view>();
CHECK(json(s) == j);
}
#endif
Expand Down