From a0a33d94a73a78959051abd1f075f93cb6f1262e Mon Sep 17 00:00:00 2001 From: Paul Reimer Date: Thu, 10 May 2018 13:30:35 -0700 Subject: [PATCH] Add string view [C++] (#4730) * Add view() method on flatbuffers::String, to return a string_view type if support for std::string_view (or alternately std::experimental::string_view) is found * Move detection/definition of FLATBUFFERS_STRING_VIEW to base.h, use the macro (if it is defined) as the argument type for an overload of CreateString * Rename String::view() to String::string_view() and use the existing c_str() method for the data pointer * Add and explain minimum C++ standard version checks for FLATBUFFERS_STRING_VIEW implementations * Updated preprocessor indenting for FLATBUFFERS_STRING_VIEW * Convert FLATBUFFERS_STRING_VIEW macro to typedef in flatbuffers:: namespace, and boolean feature toggle macro FLATBUFFERS_HAS_STRING_VIEW * Prepend flatbuffers:: namespace to disambiguate flatbuffers::string_view typedef from String::string_view() * clang-format as-she-is-spoke for FLATBUFFERS_HAS_STRING_VIEW --- include/flatbuffers/base.h | 22 ++++++++++++++++++++++ include/flatbuffers/flatbuffers.h | 19 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/include/flatbuffers/base.h b/include/flatbuffers/base.h index b955cbdaf..5fe501779 100644 --- a/include/flatbuffers/base.h +++ b/include/flatbuffers/base.h @@ -153,6 +153,28 @@ #pragma warning(disable: 4127) // C4127: conditional expression is constant #endif +#ifndef FLATBUFFERS_HAS_STRING_VIEW + // Only provide flatbuffers::string_view if __has_include can be used + // to detect a header that provides an implementation + #if defined(__has_include) + // Check for std::string_view (in c++17) + #if __has_include() && (__cplusplus > 201402) + #include + namespace flatbuffers { + typedef std::string_view string_view; + } + #define FLATBUFFERS_HAS_STRING_VIEW 1 + // Check for std::experimental::string_view (in c++14, compiler-dependent) + #elif __has_include() && (__cplusplus > 201103) + #include + namespace flatbuffers { + typedef std::experimental::string_view string_view; + } + #define FLATBUFFERS_HAS_STRING_VIEW 1 + #endif + #endif // __has_include +#endif // !FLATBUFFERS_HAS_STRING_VIEW + /// @endcond /// @file diff --git a/include/flatbuffers/flatbuffers.h b/include/flatbuffers/flatbuffers.h index cc9936409..e513e7938 100644 --- a/include/flatbuffers/flatbuffers.h +++ b/include/flatbuffers/flatbuffers.h @@ -344,6 +344,14 @@ struct String : public Vector { const char *c_str() const { return reinterpret_cast(Data()); } std::string str() const { return std::string(c_str(), Length()); } + // clang-format off + #ifdef FLATBUFFERS_HAS_STRING_VIEW + flatbuffers::string_view string_view() const { + return flatbuffers::string_view(c_str(), Length()); + } + #endif // FLATBUFFERS_HAS_STRING_VIEW + // clang-format on + bool operator<(const String &o) const { return strcmp(c_str(), o.c_str()) < 0; } @@ -1077,6 +1085,17 @@ class FlatBufferBuilder { return CreateString(str.c_str(), str.length()); } + // clang-format off + #ifdef FLATBUFFERS_HAS_STRING_VIEW + /// @brief Store a string in the buffer, which can contain any binary data. + /// @param[in] str A const string_view to copy in to the buffer. + /// @return Returns the offset in the buffer where the string starts. + Offset CreateString(flatbuffers::string_view str) { + return CreateString(str.data(), str.size()); + } + #endif // FLATBUFFERS_HAS_STRING_VIEW + // clang-format on + /// @brief Store a string in the buffer, which can contain any binary data. /// @param[in] str A const pointer to a `String` struct to add to the buffer. /// @return Returns the offset in the buffer where the string starts