diff --git a/Release/CMakeLists.txt b/Release/CMakeLists.txt
index 000516e1be..8092c72cad 100644
--- a/Release/CMakeLists.txt
+++ b/Release/CMakeLists.txt
@@ -13,6 +13,29 @@ set(CPPREST_VERSION_MAJOR 2)
set(CPPREST_VERSION_MINOR 10)
set(CPPREST_VERSION_REVISION 14)
+# Note: when bumping CMake version to 3.3 or higher if(... IN_LIST ...) may be used
+list(FIND CMAKE_CXX_COMPILE_FEATURES cxx_std_17 COMPILER_HAS_CXX_STD_17)
+set(CPPREST_USE_STRING_VIEWS_DEFAULT_PER_CXX_STANDARD OFF)
+if(COMPILER_HAS_CXX_STD_17 EQUAL "-1")
+ if(CPPREST_USE_STRING_VIEWS)
+ if(CMAKE_VERSION VERSION_LESS 3.8)
+ message(FATAL_ERROR "CPPREST_USE_STRING_VIEWS cannot be enabled. CMake 3.8 or higher required to support C++17.")
+ else()
+ message(FATAL_ERROR "CPPREST_USE_STRING_VIEWS cannot be enabled. Compiler (${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}) does not support C++17.")
+ endif()
+ endif()
+elseif(CMAKE_CXX_STANDARD LESS 17)
+ if(CPPREST_USE_STRING_VIEWS)
+ message(FATAL_ERROR "CPPREST_USE_STRING_VIEWS cannot be enabled when C++ standard is less than 17")
+ endif()
+elseif((NOT CMAKE_CXX_STANDARD GREATER 16.99) AND (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR IOS OR CMAKE_CXX_COMPILER_ID MATCHES "GNU"))
+ if(CPPREST_USE_STRING_VIEWS)
+ message(FATAL_ERROR "CPPREST_USE_STRING_VIEWS cannot be enabled without setting C++ standard to 17 or greater for current configuration") # see compiler specific settings below
+ endif()
+else()
+ set(CPPREST_USE_STRING_VIEWS_DEFAULT_PER_CXX_STANDARD ON)
+endif()
+
enable_testing()
set(WERROR ON CACHE BOOL "Treat Warnings as Errors.")
@@ -20,6 +43,7 @@ set(CPPREST_EXCLUDE_WEBSOCKETS OFF CACHE BOOL "Exclude websockets functionality.
set(CPPREST_EXCLUDE_COMPRESSION OFF CACHE BOOL "Exclude compression functionality.")
set(CPPREST_EXCLUDE_BROTLI ON CACHE BOOL "Exclude Brotli compression functionality.")
set(CPPREST_EXPORT_DIR cpprestsdk CACHE STRING "Directory to install CMake config files.")
+option(CPPREST_USE_STRING_VIEWS "Use string_view types" ${CPPREST_USE_STRING_VIEWS_DEFAULT_PER_CXX_STANDARD})
set(CPPREST_INSTALL_HEADERS ON CACHE BOOL "Install header files.")
set(CPPREST_INSTALL ON CACHE BOOL "Add install commands.")
@@ -116,6 +140,11 @@ endif()
set(WARNINGS)
set(ANDROID_LIBS)
+# Generic build settings
+if(CPPREST_USE_STRING_VIEWS)
+ add_definitions(-DCPPREST_USE_STRING_VIEWS)
+endif()
+
# Platform (not compiler) specific settings
if(ANDROID)
# These are used in the shared library case
@@ -140,6 +169,15 @@ else()
endif()
# Compiler (not platform) specific settings
+if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR IOS OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
+ if(NOT CMAKE_CXX_STANDARD GREATER 0)
+ if(CPPREST_USE_STRING_VIEWS)
+ message(FATAL_ERROR "internal cpprestsdk cmake error: CPPREST_USE_STRING_VIEWS ON while C++ standard not set")
+ endif()
+ set(CMAKE_CXX_STANDARD 11)
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
+ endif()
+endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR IOS)
message("-- Setting clang options")
@@ -157,10 +195,10 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR IOS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -Wno-return-type-c-linkage -Wno-unneeded-internal-declaration")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
- set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11")
+ set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++${CMAKE_CXX_STANDARD}")
endif()
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-strict-aliasing")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing")
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
message("-- Setting gcc options")
@@ -168,7 +206,7 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
set(WARNINGS -Wall -Wextra -Wunused-parameter -Wcast-align -Wcast-qual -Wconversion -Wformat=2 -Winit-self -Winvalid-pch -Wmissing-format-attribute -Wmissing-include-dirs -Wpacked -Wredundant-decls -Wunreachable-code)
set(LD_FLAGS "${LD_FLAGS} -Wl,-z,defs")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-strict-aliasing")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive -D_GLIBCXX_USE_SCHED_YIELD -D_GLIBCXX_USE_NANOSLEEP")
endif()
@@ -193,6 +231,13 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
add_compile_options(/permissive-)
endif()
endif()
+
+ # Suppress C++17 deprecation warning in aiso per https://github.com/chriskohlhoff/asio/issues/290#issuecomment-371867040
+ # MSVC has addressed issue in 16.0 per https://devblogs.microsoft.com/cppblog/cpp17-20-features-and-fixes-in-vs-2019/
+ if(MSVC_VERSION GREATER 1912 AND MSVC_VERSION LESS 1920)
+ add_definitions(-D_SILENCE_CXX17_ALLOCATOR_VOID_DEPRECATION_WARNING)
+ endif()
+
else()
message("-- Unknown compiler, success is doubtful.")
message("CMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID}")
diff --git a/Release/include/cpprest/base64_utils.h b/Release/include/cpprest/base64_utils.h
index d986b5973d..a5c0823664 100644
--- a/Release/include/cpprest/base64_utils.h
+++ b/Release/include/cpprest/base64_utils.h
@@ -36,7 +36,7 @@ _ASYNCRTIMP utility::string_t __cdecl to_base64(uint64_t data);
///
/// Decode the given base64 string to a byte array
///
-_ASYNCRTIMP std::vector __cdecl from_base64(const utility::string_t& str);
+_ASYNCRTIMP std::vector __cdecl from_base64(utility::string_view_t str);
} // namespace conversions
diff --git a/Release/include/cpprest/details/basic_types.h b/Release/include/cpprest/details/basic_types.h
index 5630d61cb1..9a546665ea 100644
--- a/Release/include/cpprest/details/basic_types.h
+++ b/Release/include/cpprest/details/basic_types.h
@@ -18,6 +18,9 @@
#include
#include
#include
+#if defined(CPPREST_USE_STRING_VIEWS)
+#include
+#endif
#ifndef _WIN32
#ifndef __STDC_LIMIT_MACROS
@@ -44,11 +47,22 @@ typedef uint64_t size64_t;
typedef uint32_t HRESULT; // Needed for PPLX
#endif
+#if defined(CPPREST_USE_STRING_VIEWS)
+typedef std::string_view nstring_view_t;
+typedef std::wstring_view wstring_view_t;
+template using string_view = std::basic_string_view;
+#else
+typedef const std::string & nstring_view_t;
+typedef const std::wstring & wstring_view_t;
+template using string_view = const std::basic_string &;
+#endif
+
#ifdef _UTF16_STRINGS
//
// On Windows, all strings are wide
//
typedef wchar_t char_t;
+typedef wstring_view_t string_view_t;
typedef std::wstring string_t;
#define _XPLATSTR(x) L##x
typedef std::wostringstream ostringstream_t;
@@ -66,6 +80,7 @@ typedef std::wstringstream stringstream_t;
// On POSIX platforms, all strings are narrow
//
typedef char char_t;
+typedef nstring_view_t string_view_t;
typedef std::string string_t;
#define _XPLATSTR(x) x
typedef std::ostringstream ostringstream_t;
@@ -90,6 +105,7 @@ typedef std::stringstream stringstream_t;
} // namespace utility
typedef char utf8char;
+typedef utility::nstring_view_t utf8string_view;
typedef std::string utf8string;
typedef std::stringstream utf8stringstream;
typedef std::ostringstream utf8ostringstream;
@@ -99,6 +115,7 @@ typedef std::istringstream utf8istringstream;
#if defined(_UTF16_STRINGS) || defined(_WIN32)
typedef wchar_t utf16char;
+typedef utility::wstring_view_t utf16string_view;
typedef std::wstring utf16string;
typedef std::wstringstream utf16stringstream;
typedef std::wostringstream utf16ostringstream;
@@ -107,6 +124,11 @@ typedef std::wistream utf16istream;
typedef std::wistringstream utf16istringstream;
#else
typedef char16_t utf16char;
+#if defined(CPPREST_USE_STRING_VIEWS)
+typedef std::u16string_view utf16string_view;
+#else
+typedef const std::u16string & utf16string_view;
+#endif
typedef std::u16string utf16string;
typedef std::basic_stringstream utf16stringstream;
typedef std::basic_ostringstream utf16ostringstream;
diff --git a/Release/include/cpprest/details/web_utilities.h b/Release/include/cpprest/details/web_utilities.h
index d7c7fdb36b..441775cf62 100644
--- a/Release/include/cpprest/details/web_utilities.h
+++ b/Release/include/cpprest/details/web_utilities.h
@@ -32,7 +32,7 @@ class winrt_encryption
{
public:
winrt_encryption() = default;
- _ASYNCRTIMP winrt_encryption(const ::utility::string_t& data);
+ _ASYNCRTIMP winrt_encryption(utility::string_view_t data);
_ASYNCRTIMP plaintext_string decrypt() const;
private:
@@ -43,7 +43,7 @@ class win32_encryption
{
public:
win32_encryption() = default;
- _ASYNCRTIMP win32_encryption(const ::utility::string_t& data);
+ _ASYNCRTIMP win32_encryption(::utility::string_view_t data);
_ASYNCRTIMP ~win32_encryption();
_ASYNCRTIMP plaintext_string decrypt() const;
@@ -73,7 +73,7 @@ class credentials
///
/// User name as a string.
/// Password as a string.
- credentials(utility::string_t username, const utility::string_t& password)
+ credentials(utility::string_t username, utility::string_view_t password)
: m_username(std::move(username)), m_password(password)
{
}
diff --git a/Release/include/cpprest/filestream.h b/Release/include/cpprest/filestream.h
index a9e6351caa..d71f9c20a7 100644
--- a/Release/include/cpprest/filestream.h
+++ b/Release/include/cpprest/filestream.h
@@ -713,7 +713,7 @@ class basic_file_buffer : public details::streambuf_state_manager<_CharType>
#if !defined(__cplusplus_winrt)
static pplx::task>> open(
- const utility::string_t& _Filename,
+ utility::string_view_t _Filename,
std::ios_base::openmode _Mode = std::ios_base::out,
#ifdef _WIN32
int _Prot = (int)std::ios_base::_Openprot
@@ -724,7 +724,7 @@ class basic_file_buffer : public details::streambuf_state_manager<_CharType>
{
auto result_tce = pplx::task_completion_event>>();
auto callback = new _filestream_callback_open(result_tce);
- _open_fsb_str(callback, _Filename.c_str(), _Mode, _Prot);
+ _open_fsb_str(callback, _Filename.data(), _Mode, _Prot);
return pplx::create_task(result_tce);
}
@@ -955,7 +955,7 @@ class file_buffer
/// The opening mode of the file
/// The file protection mode
/// A task that returns an opened stream buffer on completion.
- static pplx::task> open(const utility::string_t& file_name,
+ static pplx::task> open(utility::string_view_t file_name,
std::ios_base::openmode mode = std::ios_base::out,
#ifdef _WIN32
int prot = _SH_DENYRD
@@ -1010,7 +1010,7 @@ class file_stream
/// The opening mode of the file
/// The file protection mode
/// A task that returns an opened input stream on completion.
- static pplx::task> open_istream(const utility::string_t& file_name,
+ static pplx::task> open_istream(utility::string_view_t file_name,
std::ios_base::openmode mode = std::ios_base::in,
#ifdef _WIN32
int prot = (int)std::ios_base::_Openprot
@@ -1035,7 +1035,7 @@ class file_stream
/// The opening mode of the file
/// The file protection mode
/// A task that returns an opened output stream on completion.
- static pplx::task> open_ostream(const utility::string_t& file_name,
+ static pplx::task> open_ostream(utility::string_view_t file_name,
std::ios_base::openmode mode = std::ios_base::out,
#ifdef _WIN32
int prot = (int)std::ios_base::_Openprot
diff --git a/Release/include/cpprest/json.h b/Release/include/cpprest/json.h
index 1f180bac9e..174da35212 100644
--- a/Release/include/cpprest/json.h
+++ b/Release/include/cpprest/json.h
@@ -281,7 +281,7 @@ class value
#if defined(_UTF16_STRINGS)
private:
// Only used internally by JSON parser.
- static _ASYNCRTIMP value __cdecl string(const std::string& value);
+ static _ASYNCRTIMP value __cdecl string(utility::nstring_view_t value);
public:
#endif
@@ -394,7 +394,7 @@ class value
/// Parses a string and construct a JSON value.
///
/// The C++ value to create a JSON value from, a C++ STL double-byte string
- _ASYNCRTIMP static value __cdecl parse(const utility::string_t& value);
+ _ASYNCRTIMP static value __cdecl parse(utility::string_view_t value);
///
/// Attempts to parse a string and construct a JSON value.
@@ -402,7 +402,7 @@ class value
/// The C++ value to create a JSON value from, a C++ STL double-byte string
/// If parsing fails, the error code is greater than 0
/// The parsed object. Returns web::json::value::null if failed
- _ASYNCRTIMP static value __cdecl parse(const utility::string_t& value, std::error_code& errorCode);
+ _ASYNCRTIMP static value __cdecl parse(utility::string_view_t value, std::error_code& errorCode);
///
/// Serializes the current JSON value to a C++ string.
@@ -539,56 +539,56 @@ class value
///
/// The name of the field
/// True if the field exists, false otherwise.
- bool has_field(const utility::string_t& key) const;
+ bool has_field(utility::string_view_t key) const;
///
/// Tests for the presence of a number field
///
/// The name of the field
/// True if the field exists, false otherwise.
- _ASYNCRTIMP bool has_number_field(const utility::string_t& key) const;
+ _ASYNCRTIMP bool has_number_field(utility::string_view_t key) const;
///
/// Tests for the presence of an integer field
///
/// The name of the field
/// True if the field exists, false otherwise.
- _ASYNCRTIMP bool has_integer_field(const utility::string_t& key) const;
+ _ASYNCRTIMP bool has_integer_field(utility::string_view_t key) const;
///
/// Tests for the presence of a double field
///
/// The name of the field
/// True if the field exists, false otherwise.
- _ASYNCRTIMP bool has_double_field(const utility::string_t& key) const;
+ _ASYNCRTIMP bool has_double_field(utility::string_view_t key) const;
///
/// Tests for the presence of a boolean field
///
/// The name of the field
/// True if the field exists, false otherwise.
- _ASYNCRTIMP bool has_boolean_field(const utility::string_t& key) const;
+ _ASYNCRTIMP bool has_boolean_field(utility::string_view_t key) const;
///
/// Tests for the presence of a string field
///
/// The name of the field
/// True if the field exists, false otherwise.
- _ASYNCRTIMP bool has_string_field(const utility::string_t& key) const;
+ _ASYNCRTIMP bool has_string_field(utility::string_view_t key) const;
///
/// Tests for the presence of an array field
///
/// The name of the field
/// True if the field exists, false otherwise.
- _ASYNCRTIMP bool has_array_field(const utility::string_t& key) const;
+ _ASYNCRTIMP bool has_array_field(utility::string_view_t key) const;
///
/// Tests for the presence of an object field
///
/// The name of the field
/// True if the field exists, false otherwise.
- _ASYNCRTIMP bool has_object_field(const utility::string_t& key) const;
+ _ASYNCRTIMP bool has_object_field(utility::string_view_t key) const;
///
/// Accesses a field of a JSON object.
@@ -609,7 +609,7 @@ class value
/// Erases an element of a JSON object. Throws if the key doesn't exist.
///
/// The key of the element to erase in the JSON object.
- _ASYNCRTIMP void erase(const utility::string_t& key);
+ _ASYNCRTIMP void erase(utility::string_view_t key);
///
/// Accesses an element of a JSON array. Throws when index out of bounds.
@@ -630,26 +630,26 @@ class value
///
/// The key of an element in the JSON object.
/// If the key exists, a reference to the value.
- _ASYNCRTIMP json::value& at(const utility::string_t& key);
+ _ASYNCRTIMP json::value& at(utility::string_view_t key);
///
/// Accesses an element of a JSON object. If the key doesn't exist, this method throws.
///
/// The key of an element in the JSON object.
/// If the key exists, a reference to the value.
- _ASYNCRTIMP const json::value& at(const utility::string_t& key) const;
+ _ASYNCRTIMP const json::value& at(utility::string_view_t key) const;
///
/// Accesses a field of a JSON object.
///
/// The name of the field
/// A reference to the value kept in the field.
- _ASYNCRTIMP value& operator[](const utility::string_t& key);
+ _ASYNCRTIMP value& operator[](utility::string_view_t key);
#if defined(_UTF16_STRINGS)
private:
// Only used internally by JSON parser
- _ASYNCRTIMP value& operator[](const std::string& key)
+ _ASYNCRTIMP value& operator[](utility::nstring_view_t key)
{
// JSON object stores its field map as a unordered_map of string_t, so this conversion is hard to avoid
return operator[](utility::conversions::to_string_t(key));
@@ -1050,7 +1050,7 @@ class object
/// Deletes an element of the JSON object. If the key doesn't exist, this method throws.
///
/// The key of an element in the JSON object.
- void erase(const utility::string_t& key)
+ void erase(utility::string_view_t key)
{
auto iter = find_by_key(key);
if (iter == m_elements.end())
@@ -1066,7 +1066,7 @@ class object
///
/// The key of an element in the JSON object.
/// If the key exists, a reference to the value kept in the field.
- json::value& at(const utility::string_t& key)
+ json::value& at(utility::string_view_t key)
{
auto iter = find_by_key(key);
if (iter == m_elements.end())
@@ -1082,7 +1082,7 @@ class object
///
/// The key of an element in the JSON object.
/// If the key exists, a reference to the value kept in the field.
- const json::value& at(const utility::string_t& key) const
+ const json::value& at(utility::string_view_t key) const
{
auto iter = find_by_key(key);
if (iter == m_elements.end())
@@ -1099,7 +1099,7 @@ class object
/// The key of an element in the JSON object.
/// If the key exists, a reference to the value kept in the field, otherwise a newly created null value
/// that will be stored for the given key.
- json::value& operator[](const utility::string_t& key)
+ json::value& operator[](utility::string_view_t key)
{
auto iter = find_insert_location(key);
@@ -1116,7 +1116,7 @@ class object
///
/// The key of an element in the JSON object.
/// A const iterator to the value kept in the field.
- const_iterator find(const utility::string_t& key) const { return find_by_key(key); }
+ const_iterator find(utility::string_view_t key) const { return find_by_key(key); }
///
/// Gets the number of elements of the object.
@@ -1136,12 +1136,12 @@ class object
{
return p1.first < p2.first;
}
- static bool compare_with_key(const std::pair& p1, const utility::string_t& key)
+ static bool compare_with_key(const std::pair& p1, utility::string_view_t key)
{
return p1.first < key;
}
- storage_type::iterator find_insert_location(const utility::string_t& key)
+ storage_type::iterator find_insert_location(utility::string_view_t key)
{
if (m_keep_order)
{
@@ -1155,7 +1155,7 @@ class object
}
}
- storage_type::const_iterator find_by_key(const utility::string_t& key) const
+ storage_type::const_iterator find_by_key(utility::string_view_t key) const
{
if (m_keep_order)
{
@@ -1174,7 +1174,7 @@ class object
}
}
- storage_type::iterator find_by_key(const utility::string_t& key)
+ storage_type::iterator find_by_key(utility::string_view_t key)
{
auto iter = find_insert_location(key);
if (iter != m_elements.end() && key != iter->first)
@@ -1357,14 +1357,14 @@ class _Value
public:
virtual std::unique_ptr<_Value> _copy_value() = 0;
- virtual bool has_field(const utility::string_t&) const { return false; }
- virtual value get_field(const utility::string_t&) const { throw json_exception("not an object"); }
+ virtual bool has_field(utility::string_view_t) const { return false; }
+ virtual value get_field(utility::string_view_t) const { throw json_exception("not an object"); }
virtual value get_element(array::size_type) const { throw json_exception("not an array"); }
- virtual value& index(const utility::string_t&) { throw json_exception("not an object"); }
+ virtual value& index(utility::string_view_t) { throw json_exception("not an object"); }
virtual value& index(array::size_type) { throw json_exception("not an array"); }
- virtual const value& cnst_index(const utility::string_t&) const { throw json_exception("not an object"); }
+ virtual const value& cnst_index(utility::string_view_t) const { throw json_exception("not an object"); }
virtual const value& cnst_index(array::size_type) const { throw json_exception("not an array"); }
// Common function used for serialization to strings and streams.
@@ -1537,12 +1537,12 @@ class _String : public _Value
};
template
-_ASYNCRTIMP void append_escape_string(std::basic_string& str, const std::basic_string& escaped);
+_ASYNCRTIMP void append_escape_string(std::basic_string& str, utility::string_view escaped);
-void format_string(const utility::string_t& key, utility::string_t& str);
+void format_string(utility::string_view_t key, utility::string_t& str);
#if defined(_UTF16_STRINGS)
-void format_string(const utility::string_t& key, std::string& str);
+void format_string(utility::string_view_t key, std::string& str);
#endif
class _Object : public _Value
@@ -1559,9 +1559,9 @@ class _Object : public _Value
virtual json::value::value_type type() const { return json::value::Object; }
- virtual bool has_field(const utility::string_t&) const;
+ virtual bool has_field(utility::string_view_t) const;
- virtual json::value& index(const utility::string_t& key);
+ virtual json::value& index(utility::string_view_t key);
bool is_equal(const _Object* other) const
{
@@ -1752,7 +1752,7 @@ inline size_t json::value::size() const { return m_value->size(); }
///
/// The name of the field
/// True if the field exists, false otherwise.
-inline bool json::value::has_field(const utility::string_t& key) const { return m_value->has_field(key); }
+inline bool json::value::has_field(utility::string_view_t key) const { return m_value->has_field(key); }
///
/// Access a field of a JSON object.
diff --git a/Release/include/cpprest/string_utils.h b/Release/include/cpprest/string_utils.h
index 0daaca8705..7929f9e66b 100644
--- a/Release/include/cpprest/string_utils.h
+++ b/Release/include/cpprest/string_utils.h
@@ -42,35 +42,35 @@ namespace conversions
///
/// A two byte character UTF-16 string.
/// A single byte character UTF-8 string.
-_ASYNCRTIMP std::string __cdecl utf16_to_utf8(const utf16string& w);
+_ASYNCRTIMP std::string __cdecl utf16_to_utf8(utf16string_view w);
///
/// Converts a UTF-8 string to a UTF-16
///
/// A single byte character UTF-8 string.
/// A two byte character UTF-16 string.
-_ASYNCRTIMP utf16string __cdecl utf8_to_utf16(const std::string& s);
+_ASYNCRTIMP utf16string __cdecl utf8_to_utf16(utility::nstring_view_t s);
///
/// Converts a ASCII (us-ascii) string to a UTF-16 string.
///
/// A single byte character us-ascii string.
/// A two byte character UTF-16 string.
-_ASYNCRTIMP utf16string __cdecl usascii_to_utf16(const std::string& s);
+_ASYNCRTIMP utf16string __cdecl usascii_to_utf16(utility::nstring_view_t s);
///
/// Converts a Latin1 (iso-8859-1) string to a UTF-16 string.
///
/// A single byte character UTF-8 string.
/// A two byte character UTF-16 string.
-_ASYNCRTIMP utf16string __cdecl latin1_to_utf16(const std::string& s);
+_ASYNCRTIMP utf16string __cdecl latin1_to_utf16(utility::nstring_view_t s);
///
/// Converts a Latin1 (iso-8859-1) string to a UTF-8 string.
///
/// A single byte character UTF-8 string.
/// A single byte character UTF-8 string.
-_ASYNCRTIMP utf8string __cdecl latin1_to_utf8(const std::string& s);
+_ASYNCRTIMP utf8string __cdecl latin1_to_utf8(utility::nstring_view_t s);
///
/// Converts to a platform dependent Unicode string type.
@@ -99,9 +99,18 @@ _ASYNCRTIMP utility::string_t __cdecl to_string_t(utf16string&& s);
/// A single byte character UTF-8 string.
/// A platform dependent string type.
#ifdef _UTF16_STRINGS
-_ASYNCRTIMP utility::string_t __cdecl to_string_t(const std::string& s);
+_ASYNCRTIMP utility::string_t __cdecl to_string_t(utility::nstring_view_t s);
#else
inline const utility::string_t& to_string_t(const std::string& s) { return s; }
+#if CPPREST_USE_STRING_VIEWS
+inline utility::string_view_t to_string_t(utility::nstring_view_t s) { return s; }
+#endif
+#endif
+
+#if CPPREST_USE_STRING_VIEWS
+// Provide precise overload for string literals to resolve ambiguity of other overloads.
+template
+inline auto to_string_t(const CharType * s) { return to_string_t(std::basic_string_view(s)); }
#endif
///
@@ -111,8 +120,11 @@ inline const utility::string_t& to_string_t(const std::string& s) { return s; }
/// A platform dependent string type.
#ifdef _UTF16_STRINGS
inline const utility::string_t& to_string_t(const utf16string& s) { return s; }
+#if CPPREST_USE_STRING_VIEWS
+inline utf16string_view to_string_t(utf16string_view s) { return s; }
+#endif
#else
-_ASYNCRTIMP utility::string_t __cdecl to_string_t(const utf16string& s);
+_ASYNCRTIMP utility::string_t __cdecl to_string_t(utf16string_view s);
#endif
///
@@ -120,7 +132,7 @@ _ASYNCRTIMP utility::string_t __cdecl to_string_t(const utf16string& s);
///
/// A single byte character UTF-8 string.
/// A two byte character UTF-16 string.
-_ASYNCRTIMP utf16string __cdecl to_utf16string(const std::string& value);
+_ASYNCRTIMP utf16string __cdecl to_utf16string(utility::nstring_view_t value);
///
/// Converts to a UTF-16 from string.
@@ -128,6 +140,9 @@ _ASYNCRTIMP utf16string __cdecl to_utf16string(const std::string& value);
/// A two byte character UTF-16 string.
/// A two byte character UTF-16 string.
inline const utf16string& to_utf16string(const utf16string& value) { return value; }
+#if CPPREST_USE_STRING_VIEWS
+inline utf16string_view to_utf16string(utf16string_view value) { return value; }
+#endif
///
/// Converts to a UTF-16 from string.
///
@@ -135,6 +150,12 @@ inline const utf16string& to_utf16string(const utf16string& value) { return valu
/// A two byte character UTF-16 string.
inline utf16string&& to_utf16string(utf16string&& value) { return std::move(value); }
+#if CPPREST_USE_STRING_VIEWS
+// Provide precise overload for string literals to resolve ambiguity of other overloads.
+template
+inline auto to_utf16string(const CharType * s) { return to_utf16string(std::basic_string_view(s)); }
+#endif
+
///
/// Converts to a UTF-8 string.
///
@@ -148,13 +169,22 @@ inline std::string&& to_utf8string(std::string&& value) { return std::move(value
/// A single byte character UTF-8 string.
/// A single byte character UTF-8 string.
inline const std::string& to_utf8string(const std::string& value) { return value; }
+#if CPPREST_USE_STRING_VIEWS
+inline utility::nstring_view_t to_utf8string(utility::nstring_view_t value) { return value; }
+#endif
///
/// Converts to a UTF-8 string.
///
/// A two byte character UTF-16 string.
/// A single byte character UTF-8 string.
-_ASYNCRTIMP std::string __cdecl to_utf8string(const utf16string& value);
+_ASYNCRTIMP std::string __cdecl to_utf8string(utf16string_view value);
+
+#if CPPREST_USE_STRING_VIEWS
+// Provide precise overload for string literals to resolve ambiguity of other overloads.
+template
+inline auto to_utf8string(const CharType * s) { return to_utf8string(std::basic_string_view(s)); }
+#endif
template
CASABLANCA_DEPRECATED("All locale-sensitive APIs will be removed in a future update. Use stringstreams directly if "
@@ -216,6 +246,9 @@ utility::string_t print_string(const Source& val)
}
inline const utility::string_t& print_string(const utility::string_t& val) { return val; }
+#if CPPREST_USE_STRING_VIEWS
+inline utility::string_view_t print_string(utility::string_view_t val) { return val; }
+#endif
template
utf8string print_utf8string(const Source& val)
@@ -363,7 +396,7 @@ inline bool __cdecl is_space(Elem ch) CPPREST_NOEXCEPT
/// First string to compare.
/// Second strong to compare.
/// true if the strings are equivalent, false otherwise
-_ASYNCRTIMP bool __cdecl str_iequal(const std::string& left, const std::string& right) CPPREST_NOEXCEPT;
+_ASYNCRTIMP bool __cdecl str_iequal(utility::nstring_view_t left, utility::nstring_view_t right) CPPREST_NOEXCEPT;
///
/// Cross platform utility function for performing case insensitive string equality comparison.
@@ -371,7 +404,7 @@ _ASYNCRTIMP bool __cdecl str_iequal(const std::string& left, const std::string&
/// First string to compare.
/// Second strong to compare.
/// true if the strings are equivalent, false otherwise
-_ASYNCRTIMP bool __cdecl str_iequal(const std::wstring& left, const std::wstring& right) CPPREST_NOEXCEPT;
+_ASYNCRTIMP bool __cdecl str_iequal(utility::wstring_view_t left, utility::wstring_view_t right) CPPREST_NOEXCEPT;
///
/// Cross platform utility function for performing case insensitive string less-than comparison.
@@ -380,7 +413,7 @@ _ASYNCRTIMP bool __cdecl str_iequal(const std::wstring& left, const std::wstring
/// Second strong to compare.
/// true if a lowercase view of left is lexicographically less than a lowercase view of right; otherwise,
/// false.
-_ASYNCRTIMP bool __cdecl str_iless(const std::string& left, const std::string& right) CPPREST_NOEXCEPT;
+_ASYNCRTIMP bool __cdecl str_iless(utility::nstring_view_t left, utility::nstring_view_t right) CPPREST_NOEXCEPT;
///
/// Cross platform utility function for performing case insensitive string less-than comparison.
@@ -389,7 +422,7 @@ _ASYNCRTIMP bool __cdecl str_iless(const std::string& left, const std::string& r
/// Second strong to compare.
/// true if a lowercase view of left is lexicographically less than a lowercase view of right; otherwise,
/// false.
-_ASYNCRTIMP bool __cdecl str_iless(const std::wstring& left, const std::wstring& right) CPPREST_NOEXCEPT;
+_ASYNCRTIMP bool __cdecl str_iless(utility::wstring_view_t left, utility::wstring_view_t right) CPPREST_NOEXCEPT;
///
/// Convert a string to lowercase in place.
diff --git a/Release/samples/SearchFile/searchfile.cpp b/Release/samples/SearchFile/searchfile.cpp
index 7200f05dc8..480fe96752 100644
--- a/Release/samples/SearchFile/searchfile.cpp
+++ b/Release/samples/SearchFile/searchfile.cpp
@@ -86,8 +86,8 @@ class type_parser
/// Function to create in data from a file and search for a given string writing all lines containing the string to
/// memory_buffer.
///
-static pplx::task find_matches_in_file(const string_t& fileName,
- const std::string& searchString,
+static pplx::task find_matches_in_file(utility::string_view_t fileName,
+ utility::nstring_view_t searchString,
basic_ostream results)
{
return file_stream::open_istream(fileName).then([=](basic_istream inFile) {
@@ -130,7 +130,7 @@ static pplx::task find_matches_in_file(const string_t& fileName,
///
/// Function to write out results from matched_lines type to file
///
-static pplx::task write_matches_to_file(const string_t& fileName, matched_lines results)
+static pplx::task write_matches_to_file(utility::string_view_t fileName, matched_lines results)
{
// Create a shared pointer to the matched_lines structure to copying repeatedly.
auto sharedResults = std::make_shared(std::move(results));
@@ -162,9 +162,9 @@ int main(int argc, char* args[])
printf("Usage: SearchFile.exe input_file search_string output_file\n");
return -1;
}
- const string_t inFileName = utility::conversions::to_string_t(args[1]);
- const std::string searchString = utility::conversions::to_utf8string(args[2]);
- const string_t outFileName = utility::conversions::to_string_t(args[3]);
+ const auto inFileName = utility::conversions::to_string_t(args[1]);
+ const auto searchString = utility::conversions::to_utf8string(args[2]);
+ const auto outFileName = utility::conversions::to_string_t(args[3]);
producer_consumer_buffer lineResultsBuffer;
// Find all matches in file.
diff --git a/Release/src/CMakeLists.txt b/Release/src/CMakeLists.txt
index 9d0fadde62..af31a9f2c4 100644
--- a/Release/src/CMakeLists.txt
+++ b/Release/src/CMakeLists.txt
@@ -48,6 +48,10 @@ target_include_directories(cpprest
pch
)
+if(CPPREST_USE_STRING_VIEWS)
+ target_compile_features(cpprest PUBLIC cxx_std_17)
+endif()
+
## Sub-components
# Websockets component
if(CPPREST_WEBSOCKETS_IMPL STREQUAL "none")
diff --git a/Release/src/json/json.cpp b/Release/src/json/json.cpp
index eee8db7cd6..70e227f197 100644
--- a/Release/src/json/json.cpp
+++ b/Release/src/json/json.cpp
@@ -196,7 +196,7 @@ web::json::value web::json::value::string(utility::string_t value, bool has_esca
}
#if defined(_UTF16_STRINGS)
-web::json::value web::json::value::string(const std::string& value)
+web::json::value web::json::value::string(utility::nstring_view_t value)
{
std::unique_ptr ptr =
utility::details::make_unique(utility::conversions::to_utf16string(value));
@@ -355,44 +355,44 @@ bool json::value::is_double() const
return m_value->is_double();
}
-json::value& web::json::details::_Object::index(const utility::string_t& key) { return m_object[key]; }
+json::value& web::json::details::_Object::index(utility::string_view_t key) { return m_object[key]; }
-bool web::json::details::_Object::has_field(const utility::string_t& key) const
+bool web::json::details::_Object::has_field(utility::string_view_t key) const
{
return m_object.find(key) != m_object.end();
}
-bool web::json::value::has_number_field(const utility::string_t& key) const
+bool web::json::value::has_number_field(utility::string_view_t key) const
{
return has_field(key) && at(key).is_number();
}
-bool web::json::value::has_integer_field(const utility::string_t& key) const
+bool web::json::value::has_integer_field(utility::string_view_t key) const
{
return has_field(key) && at(key).is_integer();
}
-bool web::json::value::has_double_field(const utility::string_t& key) const
+bool web::json::value::has_double_field(utility::string_view_t key) const
{
return has_field(key) && at(key).is_double();
}
-bool web::json::value::has_boolean_field(const utility::string_t& key) const
+bool web::json::value::has_boolean_field(utility::string_view_t key) const
{
return has_field(key) && at(key).is_boolean();
}
-bool web::json::value::has_string_field(const utility::string_t& key) const
+bool web::json::value::has_string_field(utility::string_view_t key) const
{
return has_field(key) && at(key).is_string();
}
-bool web::json::value::has_array_field(const utility::string_t& key) const
+bool web::json::value::has_array_field(utility::string_view_t key) const
{
return has_field(key) && at(key).is_array();
}
-bool web::json::value::has_object_field(const utility::string_t& key) const
+bool web::json::value::has_object_field(utility::string_view_t key) const
{
return has_field(key) && at(key).is_object();
}
@@ -428,18 +428,18 @@ bool json::value::operator==(const json::value& other) const
void web::json::value::erase(size_t index) { return this->as_array().erase(index); }
-void web::json::value::erase(const utility::string_t& key) { return this->as_object().erase(key); }
+void web::json::value::erase(utility::string_view_t key) { return this->as_object().erase(key); }
// at() overloads
web::json::value& web::json::value::at(size_t index) { return this->as_array().at(index); }
const web::json::value& web::json::value::at(size_t index) const { return this->as_array().at(index); }
-web::json::value& web::json::value::at(const utility::string_t& key) { return this->as_object().at(key); }
+web::json::value& web::json::value::at(utility::string_view_t key) { return this->as_object().at(key); }
-const web::json::value& web::json::value::at(const utility::string_t& key) const { return this->as_object().at(key); }
+const web::json::value& web::json::value::at(utility::string_view_t key) const { return this->as_object().at(key); }
-web::json::value& web::json::value::operator[](const utility::string_t& key)
+web::json::value& web::json::value::operator[](utility::string_view_t key)
{
if (this->is_null())
{
diff --git a/Release/src/json/json_parsing.cpp b/Release/src/json/json_parsing.cpp
index 2e0d71e6d3..e5719d3494 100644
--- a/Release/src/json/json_parsing.cpp
+++ b/Release/src/json/json_parsing.cpp
@@ -46,7 +46,7 @@ __declspec(noreturn)
#else
__attribute__((noreturn))
#endif
- void CreateException(const Token& tk, const utility::string_t& message)
+ void CreateException(const Token& tk, utility::string_view_t message)
{
std::string str("* Line ");
str += std::to_string(tk.start.m_line);
@@ -211,7 +211,7 @@ template
class JSON_StringParser : public JSON_Parser
{
public:
- JSON_StringParser(const std::basic_string& string) : m_position(&string[0])
+ JSON_StringParser(utility::string_view string) : m_position(string.data())
{
m_startpos = m_position;
m_endpos = m_position + string.size();
@@ -1223,7 +1223,7 @@ static web::json::value _parse_narrow_stream(std::istream& stream, std::error_co
}
#endif
-web::json::value web::json::value::parse(const utility::string_t& str)
+web::json::value web::json::value::parse(utility::string_view_t str)
{
web::json::details::JSON_StringParser parser(str);
web::json::details::JSON_Parser::Token tkn;
@@ -1247,7 +1247,7 @@ web::json::value web::json::value::parse(const utility::string_t& str)
return value;
}
-web::json::value web::json::value::parse(const utility::string_t& str, std::error_code& error)
+web::json::value web::json::value::parse(utility::string_view_t str, std::error_code& error)
{
web::json::details::JSON_StringParser parser(str);
web::json::details::JSON_Parser::Token tkn;
diff --git a/Release/src/json/json_serialization.cpp b/Release/src/json/json_serialization.cpp
index 83c1086e1f..9652bc23db 100644
--- a/Release/src/json/json_serialization.cpp
+++ b/Release/src/json/json_serialization.cpp
@@ -56,7 +56,7 @@ void web::json::value::format(std::basic_string& string) const { m_value->
template
void web::json::details::append_escape_string(std::basic_string& str,
- const std::basic_string& escaped)
+ utility::string_view escaped)
{
for (const auto& ch : escaped)
{
@@ -112,18 +112,18 @@ void web::json::details::append_escape_string(std::basic_string& str,
}
}
-void web::json::details::format_string(const utility::string_t& key, utility::string_t& str)
+void web::json::details::format_string(utility::string_view_t key, utility::string_t& str)
{
str.push_back('"');
- append_escape_string(str, key);
+ append_escape_string(str, key);
str.push_back('"');
}
#if defined(_UTF16_STRINGS)
-void web::json::details::format_string(const utility::string_t& key, std::string& str)
+void web::json::details::format_string(utility::string_view_t key, std::string& str)
{
str.push_back('"');
- append_escape_string(str, utility::conversions::to_utf8string(key));
+ append_escape_string(str, utility::conversions::to_utf8string(key));
str.push_back('"');
}
#endif
@@ -134,7 +134,7 @@ void web::json::details::_String::format(std::basic_string& str) const
if (m_has_escape_char)
{
- append_escape_string(str, utility::conversions::to_utf8string(m_string));
+ append_escape_string(str, utility::conversions::to_utf8string(m_string));
}
else
{
@@ -198,7 +198,7 @@ void web::json::details::_String::format(std::basic_string& str) const
if (m_has_escape_char)
{
- append_escape_string(str, m_string);
+ append_escape_string(str, m_string);
}
else
{
diff --git a/Release/src/streams/fileio_win32.cpp b/Release/src/streams/fileio_win32.cpp
index 129fd991de..82657d61bd 100644
--- a/Release/src/streams/fileio_win32.cpp
+++ b/Release/src/streams/fileio_win32.cpp
@@ -228,7 +228,11 @@ bool __cdecl _open_fsb_str(_In_ _filestream_callback* callback,
_ASSERTE(callback != nullptr);
_ASSERTE(filename != nullptr);
- std::wstring name = conversions::to_utf16string(filename);
+ std::wstring name(
+#if defined(CPPREST_FORCE_NARROW_STRINGS)
+ conversions::to_utf16string
+#endif
+ (filename));
pplx::create_task([=]() {
DWORD dwDesiredAccess, dwCreationDisposition, dwShareMode;
diff --git a/Release/src/utilities/base64.cpp b/Release/src/utilities/base64.cpp
index 89ccf43674..db419d5ec9 100644
--- a/Release/src/utilities/base64.cpp
+++ b/Release/src/utilities/base64.cpp
@@ -16,10 +16,10 @@
using namespace utility;
-std::vector _from_base64(const utility::string_t& str);
+std::vector _from_base64(utility::string_view_t str);
utility::string_t _to_base64(const unsigned char* ptr, size_t size);
-std::vector __cdecl conversions::from_base64(const utility::string_t& str) { return _from_base64(str); }
+std::vector __cdecl conversions::from_base64(utility::string_view_t str) { return _from_base64(str); }
utility::string_t __cdecl conversions::to_base64(const std::vector& input)
{
@@ -29,7 +29,7 @@ utility::string_t __cdecl conversions::to_base64(const std::vector _from_base64(const utility::string_t& input)
+std::vector _from_base64(utility::string_view_t input)
{
std::vector result;
@@ -127,7 +127,7 @@ std::vector _from_base64(const utility::string_t& input)
}
auto size = input.size();
- const char_t* ptr = &input[0];
+ const char_t* ptr = input.data();
auto outsz = (size / 4) * 3;
outsz -= padding;
diff --git a/Release/src/utilities/string_utils.cpp b/Release/src/utilities/string_utils.cpp
index 51751f224d..03f94f5e32 100644
--- a/Release/src/utilities/string_utils.cpp
+++ b/Release/src/utilities/string_utils.cpp
@@ -68,22 +68,22 @@ namespace utility
{
namespace details
{
-_ASYNCRTIMP bool __cdecl str_iequal(const std::string& left, const std::string& right) CPPREST_NOEXCEPT
+_ASYNCRTIMP bool __cdecl str_iequal(utility::nstring_view_t left, utility::nstring_view_t right) CPPREST_NOEXCEPT
{
return left.size() == right.size() && std::equal(left.cbegin(), left.cend(), right.cbegin(), eq_lower_ch);
}
-_ASYNCRTIMP bool __cdecl str_iequal(const std::wstring& left, const std::wstring& right) CPPREST_NOEXCEPT
+_ASYNCRTIMP bool __cdecl str_iequal(utility::wstring_view_t left, utility::wstring_view_t right) CPPREST_NOEXCEPT
{
return left.size() == right.size() && std::equal(left.cbegin(), left.cend(), right.cbegin(), eq_lower_ch);
}
-_ASYNCRTIMP bool __cdecl str_iless(const std::string& left, const std::string& right) CPPREST_NOEXCEPT
+_ASYNCRTIMP bool __cdecl str_iless(utility::nstring_view_t left, utility::nstring_view_t right) CPPREST_NOEXCEPT
{
return std::lexicographical_compare(left.cbegin(), left.cend(), right.cbegin(), right.cend(), lt_lower_ch);
}
-_ASYNCRTIMP bool __cdecl str_iless(const std::wstring& left, const std::wstring& right) CPPREST_NOEXCEPT
+_ASYNCRTIMP bool __cdecl str_iless(utility::wstring_view_t left, utility::wstring_view_t right) CPPREST_NOEXCEPT
{
return std::lexicographical_compare(left.cbegin(), left.cend(), right.cbegin(), right.cend(), lt_lower_ch);
}
@@ -228,7 +228,7 @@ scoped_c_thread_locale::~scoped_c_thread_locale()
// or unsigned.
using UtilCharInternal_t = signed char;
-inline size_t count_utf8_to_utf16(const std::string& s)
+inline size_t count_utf8_to_utf16(utility::nstring_view_t s)
{
const size_t sSize = s.size();
auto const sData = reinterpret_cast(s.data());
@@ -313,7 +313,7 @@ inline size_t count_utf8_to_utf16(const std::string& s)
return result;
}
-utf16string __cdecl conversions::utf8_to_utf16(const std::string& s)
+utf16string __cdecl conversions::utf8_to_utf16(utility::nstring_view_t s)
{
// Save repeated heap allocations, use the length of resulting sequence.
const size_t srcSize = s.size();
@@ -384,9 +384,9 @@ utf16string __cdecl conversions::utf8_to_utf16(const std::string& s)
return dest;
}
-inline size_t count_utf16_to_utf8(const utf16string& w)
+inline size_t count_utf16_to_utf8(utf16string_view w)
{
- const utf16string::value_type* const srcData = &w[0];
+ const utf16string::value_type* const srcData = w.data();
const size_t srcSize = w.size();
size_t destSize(srcSize);
for (size_t index = 0; index < srcSize; ++index)
@@ -425,10 +425,10 @@ inline size_t count_utf16_to_utf8(const utf16string& w)
return destSize;
}
-std::string __cdecl conversions::utf16_to_utf8(const utf16string& w)
+std::string __cdecl conversions::utf16_to_utf8(utf16string_view w)
{
const size_t srcSize = w.size();
- const utf16string::value_type* const srcData = &w[0];
+ const utf16string::value_type* const srcData = w.data();
std::string dest(count_utf16_to_utf8(w), '\0');
std::string::value_type* const destData = &dest[0];
size_t destIndex(0);
@@ -481,13 +481,13 @@ std::string __cdecl conversions::utf16_to_utf8(const utf16string& w)
return dest;
}
-utf16string __cdecl conversions::usascii_to_utf16(const std::string& s)
+utf16string __cdecl conversions::usascii_to_utf16(utility::nstring_view_t s)
{
// Ascii is a subset of UTF-8 so just convert to UTF-16
return utf8_to_utf16(s);
}
-utf16string __cdecl conversions::latin1_to_utf16(const std::string& s)
+utf16string __cdecl conversions::latin1_to_utf16(utility::nstring_view_t s)
{
// Latin1 is the first 256 code points in Unicode.
// In UTF-16 encoding each of these is represented as exactly the numeric code point.
@@ -502,7 +502,7 @@ utf16string __cdecl conversions::latin1_to_utf16(const std::string& s)
return dest;
}
-utf8string __cdecl conversions::latin1_to_utf8(const std::string& s) { return utf16_to_utf8(latin1_to_utf16(s)); }
+utf8string __cdecl conversions::latin1_to_utf8(utility::nstring_view_t s) { return utf16_to_utf8(latin1_to_utf16(s)); }
#ifndef _UTF16_STRINGS
utility::string_t __cdecl conversions::to_string_t(utf16string&& s) { return utf16_to_utf8(std::move(s)); }
@@ -513,15 +513,15 @@ utility::string_t __cdecl conversions::to_string_t(std::string&& s) { return utf
#endif
#ifndef _UTF16_STRINGS
-utility::string_t __cdecl conversions::to_string_t(const utf16string& s) { return utf16_to_utf8(s); }
+utility::string_t __cdecl conversions::to_string_t(utf16string_view s) { return utf16_to_utf8(s); }
#endif
#ifdef _UTF16_STRINGS
-utility::string_t __cdecl conversions::to_string_t(const std::string& s) { return utf8_to_utf16(s); }
+utility::string_t __cdecl conversions::to_string_t(utility::nstring_view_t s) { return utf8_to_utf16(s); }
#endif
-std::string __cdecl conversions::to_utf8string(const utf16string& value) { return utf16_to_utf8(value); }
+std::string __cdecl conversions::to_utf8string(utf16string_view value) { return utf16_to_utf8(value); }
-utf16string __cdecl conversions::to_utf16string(const std::string& value) { return utf8_to_utf16(value); }
+utf16string __cdecl conversions::to_utf16string(utility::nstring_view_t value) { return utf8_to_utf16(value); }
} // namespace utility
diff --git a/Release/src/utilities/web_utilities.cpp b/Release/src/utilities/web_utilities.cpp
index 67d15a343b..2096396e47 100644
--- a/Release/src/utilities/web_utilities.cpp
+++ b/Release/src/utilities/web_utilities.cpp
@@ -47,14 +47,14 @@ void winrt_secure_zero_buffer(Windows::Storage::Streams::IBuffer ^ buffer)
}
}
-winrt_encryption::winrt_encryption(const ::utility::string_t& data)
+winrt_encryption::winrt_encryption(utility::string_view_t data)
{
auto provider = ref new Windows::Security::Cryptography::DataProtection::DataProtectionProvider(
ref new Platform::String(L"Local=user"));
// Create buffer containing plain text password.
Platform::ArrayReference arrayref(
- reinterpret_cast(const_cast<::utility::string_t::value_type*>(data.c_str())),
+ reinterpret_cast(const_cast<::utility::string_t::value_type*>(data.data())),
static_cast(data.size()) * sizeof(::utility::string_t::value_type));
Windows::Storage::Streams::IBuffer ^ plaintext =
Windows::Security::Cryptography::CryptographicBuffer::CreateFromByteArray(arrayref);
@@ -91,7 +91,7 @@ plaintext_string winrt_encryption::decrypt() const
#else // ^^^ __cplusplus_winrt ^^^ // vvv !__cplusplus_winrt vvv
-win32_encryption::win32_encryption(const ::utility::string_t& data) : m_numCharacters(data.size())
+win32_encryption::win32_encryption(::utility::string_view_t data) : m_numCharacters(data.size())
{
// Early return because CryptProtectMemory crashes with empty string
if (m_numCharacters == 0)
@@ -113,7 +113,7 @@ win32_encryption::win32_encryption(const ::utility::string_t& data) : m_numChara
assert((dataNumBytes % CRYPTPROTECTMEMORY_BLOCK_SIZE) == 0);
assert(dataNumBytes >= dataSizeDword);
m_buffer.resize(dataNumBytes);
- memcpy_s(m_buffer.data(), m_buffer.size(), data.c_str(), dataNumBytes);
+ memcpy_s(m_buffer.data(), m_buffer.size(), data.data(), dataNumBytes);
if (!CryptProtectMemory(m_buffer.data(), dataNumBytes, CRYPTPROTECTMEMORY_SAME_PROCESS))
{
throw ::utility::details::create_system_error(GetLastError());
diff --git a/Release/tests/functional/utils/win32_encryption_tests.cpp b/Release/tests/functional/utils/win32_encryption_tests.cpp
index a2be7cde5a..8b77d18988 100644
--- a/Release/tests/functional/utils/win32_encryption_tests.cpp
+++ b/Release/tests/functional/utils/win32_encryption_tests.cpp
@@ -26,7 +26,7 @@ SUITE(win32_encryption)
{
TEST(win32_encryption_random_string)
{
- utility::string_t rndStr = utility::conversions::to_string_t("random string");
+ const auto rndStr = utility::conversions::to_string_t("random string");
web::details::win32_encryption enc(rndStr);
VERIFY_ARE_EQUAL(*enc.decrypt(), rndStr);
@@ -34,7 +34,7 @@ SUITE(win32_encryption)
TEST(win32_encryption_empty_string)
{
- utility::string_t emptyStr = utility::conversions::to_string_t("");
+ const auto emptyStr = utility::conversions::to_string_t("");
web::details::win32_encryption enc(emptyStr);
VERIFY_ARE_EQUAL(*enc.decrypt(), emptyStr);
diff --git a/azure-devops/build-windows.yml b/azure-devops/build-windows.yml
index 45ea392a82..bbfa5bb465 100644
--- a/azure-devops/build-windows.yml
+++ b/azure-devops/build-windows.yml
@@ -2,6 +2,7 @@ parameters:
name: 'Windows_VS2019_x86'
targetPlatform: 'x86'
image: 'windows-latest'
+ useStringViews: 'ON'
jobs:
- job: ${{ parameters.name }}
@@ -30,7 +31,7 @@ jobs:
cmakeBuildType: 'Debug'
useVcpkgToolchainFile: true
buildDirectory: $(Build.ArtifactStagingDirectory)/${{ parameters.targetPlatform }}_Debug
- cmakeAppendedArgs: '-DCPPREST_EXCLUDE_BROTLI=OFF'
+ cmakeAppendedArgs: '-DCPPREST_EXCLUDE_BROTLI=OFF -DCPPREST_USE_STRING_VIEWS=${{ parameters.useStringViews }}'
- script: |
cd $(Build.ArtifactStagingDirectory)\${{ parameters.targetPlatform }}_Debug\Release\Binaries
.\test_runner.exe *testd.dll
@@ -43,7 +44,7 @@ jobs:
cmakeBuildType: 'Release'
useVcpkgToolchainFile: true
buildDirectory: $(Build.ArtifactStagingDirectory)/${{ parameters.targetPlatform }}_Release
- cmakeAppendedArgs: '-DCPPREST_EXCLUDE_BROTLI=OFF'
+ cmakeAppendedArgs: '-DCPPREST_EXCLUDE_BROTLI=OFF -DCPPREST_USE_STRING_VIEWS=${{ parameters.useStringViews }}'
- script: |
cd $(Build.ArtifactStagingDirectory)\${{ parameters.targetPlatform }}_Release\Release\Binaries
.\test_runner.exe *test.dll
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 55f7683b3a..1eb56eaa8b 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -26,11 +26,13 @@ jobs:
name: 'Windows_VS2015_x86'
targetPlatform: x86
image: 'vs2015-win2012r2'
+ useStringViews: 'OFF'
- template: azure-devops/build-windows.yml
parameters:
name: 'Windows_VS2015_x64'
targetPlatform: x64
image: 'vs2015-win2012r2'
+ useStringViews: 'OFF'
- job: Windows_VS2019_UWP
pool:
vmImage: 'windows-latest'
@@ -44,7 +46,7 @@ jobs:
- task: CMake@1
inputs:
workingDirectory: 'build.common'
- cmakeArgs: '-A x64 -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0 ..'
+ cmakeArgs: '-A x64 -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0 -DCPPREST_USE_STRING_VIEWS=ON ..'
- task: MSBuild@1
inputs:
solution: 'build.common/ALL_BUILD.vcxproj'