diff --git a/include/xgboost/json.h b/include/xgboost/json.h index 393424d40..a10941942 100644 --- a/include/xgboost/json.h +++ b/include/xgboost/json.h @@ -1,5 +1,5 @@ /*! - * Copyright (c) by XGBoost Contributors 2019-2020 + * Copyright (c) by XGBoost Contributors 2019-2021 */ #ifndef XGBOOST_JSON_H_ #define XGBOOST_JSON_H_ @@ -301,12 +301,14 @@ class JsonBoolean : public Value { struct StringView { private: using CharT = char; // unsigned char + using Traits = std::char_traits; CharT const* str_; size_t size_; public: StringView() = default; StringView(CharT const* str, size_t size) : str_{str}, size_{size} {} + explicit StringView(CharT const* str) : str_{str}, size_{Traits::length(str)} {} CharT const& operator[](size_t p) const { return str_[p]; } CharT const& at(size_t p) const { // NOLINT @@ -322,9 +324,16 @@ struct StringView { CHECK_LE(beg, size_); return std::string {str_ + beg, n < (size_ - beg) ? n : (size_ - beg)}; } - char const* c_str() const { return str_; } // NOLINT + CharT const* c_str() const { return str_; } // NOLINT + + CharT const* cbegin() const { return str_; } // NOLINT + CharT const* cend() const { return str_ + size(); } // NOLINT + CharT const* begin() const { return str_; } // NOLINT + CharT const* end() const { return str_ + size(); } // NOLINT }; +std::ostream &operator<<(std::ostream &os, StringView const v); + /*! * \brief Data structure representing JSON format. * diff --git a/src/c_api/c_api.cc b/src/c_api/c_api.cc index d2333e718..8af8b2ab9 100644 --- a/src/c_api/c_api.cc +++ b/src/c_api/c_api.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2020 by Contributors +// Copyright (c) 2014-2021 by Contributors #include #include @@ -50,8 +50,7 @@ XGB_DLL int XGBRegisterLogCallback(void (*callback)(const char*)) { XGB_DLL int XGBSetGlobalConfig(const char* json_str) { API_BEGIN(); - std::string str{json_str}; - Json config{Json::Load(StringView{str.data(), str.size()})}; + Json config{Json::Load(StringView{json_str})}; for (auto& items : get(config)) { switch (items.second.GetValue().Type()) { case xgboost::Value::ValueKind::kInteger: { @@ -514,8 +513,7 @@ XGB_DLL int XGBoosterBoostedRounds(BoosterHandle handle, int* out) { XGB_DLL int XGBoosterLoadJsonConfig(BoosterHandle handle, char const* json_parameters) { API_BEGIN(); CHECK_HANDLE(); - std::string str {json_parameters}; - Json config { Json::Load(StringView{str.c_str(), str.size()}) }; + Json config { Json::Load(StringView{json_parameters}) }; static_cast(handle)->LoadConfig(config); API_END(); } diff --git a/src/common/json.cc b/src/common/json.cc index cdec3aede..9502073d7 100644 --- a/src/common/json.cc +++ b/src/common/json.cc @@ -1,5 +1,5 @@ /*! - * Copyright (c) by Contributors 2019-2020 + * Copyright (c) by Contributors 2019-2021 */ #include #include @@ -744,4 +744,11 @@ void Json::Dump(Json json, std::string* str) { } Json& Json::operator=(Json const &other) = default; + +std::ostream &operator<<(std::ostream &os, StringView const v) { + for (auto c : v) { + os.put(c); + } + return os; +} } // namespace xgboost diff --git a/tests/cpp/common/test_json.cc b/tests/cpp/common/test_json.cc index 029beee8d..3ddac2dac 100644 --- a/tests/cpp/common/test_json.cc +++ b/tests/cpp/common/test_json.cc @@ -1,5 +1,5 @@ /*! - * Copyright (c) by Contributors 2019 + * Copyright (c) by Contributors 2019-2021 */ #include #include @@ -574,4 +574,14 @@ TEST(Json, DISABLED_RoundTripExhaustive) { test(static_cast(i)); } } + +TEST(StringView, Basic) { + StringView str{"This is a string."}; + std::stringstream ss; + ss << str; + + std::string res = ss.str(); + ASSERT_EQ(str.size(), res.size()); + ASSERT_TRUE(std::equal(res.cbegin(), res.cend(), str.cbegin())); +} } // namespace xgboost