mirror of
https://github.com/gentoo-mirror/guru.git
synced 2026-07-09 15:13:31 -04:00
dev-cpp/cpprestsdk: patch for llvm up to 20
Llvm has previously required sizes/implementation of objects used in containers and std::unique_ptr for more methods than gcc. Also in later llvms like 19 and 20 unsigned types are not possible to use with the std::char_traits. Cpprestsdk does use a lot of unsigned types with C++ streams and while that seems to be fine with MSVC and at least gcc up until some point, it does not work at all with llvm 19 and 20. Signed-off-by: Jan-Espen Oversand <sigsegv@radiotube.org>
This commit is contained in:
@@ -0,0 +1,429 @@
|
||||
--- a/Release/include/cpprest/streams.h (revision 0b1ce318a757bbfb89bdb0fffb61ca4e38dc3b33)
|
||||
+++ b/Release/include/cpprest/streams.h (revision 32b322b564e5e540ff02393ffe3bd3bade8d299c)
|
||||
@@ -16,6 +16,7 @@
|
||||
#define CASA_STREAMS_H
|
||||
|
||||
#include "cpprest/astreambuf.h"
|
||||
+#include "cpprest/details/char_traits.h"
|
||||
#include <iosfwd>
|
||||
#include <cstdio>
|
||||
|
||||
@@ -60,30 +61,95 @@
|
||||
concurrency::streams::streambuf<CharType> m_buffer;
|
||||
};
|
||||
|
||||
-template<typename CharType>
|
||||
+template<typename CharType, class Traits = typename utility::CanUseStdCharTraits<CharType>::TraitsType>
|
||||
struct Value2StringFormatter
|
||||
{
|
||||
+ struct SanitizeInput
|
||||
+ {
|
||||
+ const std::basic_string<char> &operator () (const std::basic_string<char> &input)
|
||||
+ {
|
||||
+ return input;
|
||||
+ }
|
||||
+ template <class InputTraits> std::basic_string<char> operator () (const std::basic_string<unsigned char, InputTraits> &input)
|
||||
+ {
|
||||
+ return {reinterpret_cast<const char *>(input.c_str()), input.size()};
|
||||
+ }
|
||||
+ const char *operator () (const char *input) {
|
||||
+ return input;
|
||||
+ }
|
||||
+ const char *operator () (const unsigned char *input)
|
||||
+ {
|
||||
+ return reinterpret_cast<const char *>(input);
|
||||
+ }
|
||||
+ template <class T> T operator () (T input)
|
||||
+ {
|
||||
+ return input;
|
||||
+ }
|
||||
+ };
|
||||
+ struct GenerateFormatOutput
|
||||
+ {
|
||||
+ std::basic_string<CharType,Traits> &&operator() (std::basic_string<CharType,Traits> &&result)
|
||||
+ {
|
||||
+ return std::move(result);
|
||||
+ }
|
||||
+ std::basic_string<CharType,Traits> operator() (const std::basic_string<char> &intermediate)
|
||||
+ {
|
||||
+ return {reinterpret_cast<const CharType *>(intermediate.c_str()), intermediate.size()};
|
||||
+ }
|
||||
+ };
|
||||
template<typename T>
|
||||
- static std::basic_string<CharType> format(const T& val)
|
||||
+ static std::basic_string<CharType, Traits> format(const T& val)
|
||||
{
|
||||
- std::basic_ostringstream<CharType> ss;
|
||||
+ typename std::conditional<
|
||||
+ sizeof(CharType) == 1,
|
||||
+ std::basic_ostringstream<char>,
|
||||
+ std::basic_ostringstream<typename std::make_signed<CharType>::type>
|
||||
+ >::type ss;
|
||||
+ SanitizeInput sanitizer;
|
||||
+ ss << sanitizer(val);
|
||||
+ typename std::conditional<
|
||||
+ sizeof(CharType) == 1,
|
||||
+ std::basic_string<char>,
|
||||
+ std::basic_string<typename std::make_signed<CharType>::type>
|
||||
+ >::type str = ss.str();
|
||||
+ GenerateFormatOutput generateFormatOutput;
|
||||
+ return generateFormatOutput(std::move(str));
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+template<class Traits, typename T>
|
||||
+struct Value2StringFormatterUint8Format
|
||||
+{
|
||||
+ std::basic_string<uint8_t, Traits> operator () (const T& val)
|
||||
+ {
|
||||
+ std::basic_ostringstream<char> ss;
|
||||
ss << val;
|
||||
- return ss.str();
|
||||
+ return reinterpret_cast<const uint8_t*>(ss.str().c_str());
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+template <class Traits>
|
||||
+struct Value2StringFormatterUint8Format<Traits, std::basic_string<uint8_t,Traits>>
|
||||
+{
|
||||
+ std::basic_string<uint8_t, Traits> operator () (
|
||||
+ const std::basic_string<uint8_t, typename utility::CanUseStdCharTraits<uint8_t>::TraitsType>& val)
|
||||
+ {
|
||||
+ Value2StringFormatterUint8Format<Traits,std::basic_string<char>> format;
|
||||
+ return format(reinterpret_cast<const std::basic_string<char>&>(val));
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct Value2StringFormatter<uint8_t>
|
||||
{
|
||||
- template<typename T>
|
||||
- static std::basic_string<uint8_t> format(const T& val)
|
||||
+ template <typename T, class Traits = typename utility::CanUseStdCharTraits<uint8_t>::TraitsType>
|
||||
+ static std::basic_string<uint8_t, Traits> format(const T& val)
|
||||
{
|
||||
- std::basic_ostringstream<char> ss;
|
||||
- ss << val;
|
||||
- return reinterpret_cast<const uint8_t*>(ss.str().c_str());
|
||||
+ Value2StringFormatterUint8Format<Traits, T> format;
|
||||
+ return format(val);
|
||||
}
|
||||
|
||||
- static std::basic_string<uint8_t> format(const utf16string& val)
|
||||
+ static std::basic_string<uint8_t, typename utility::CanUseStdCharTraits<uint8_t>::TraitsType> format(const utf16string& val)
|
||||
{
|
||||
return format(utility::conversions::utf16_to_utf8(val));
|
||||
}
|
||||
@@ -262,7 +328,7 @@
|
||||
/// Write the specified string to the output stream.
|
||||
/// </summary>
|
||||
/// <param name="str">Input string.</param>
|
||||
- pplx::task<size_t> print(const std::basic_string<CharType>& str) const
|
||||
+ pplx::task<size_t> print(const std::basic_string<CharType,traits>& str) const
|
||||
{
|
||||
pplx::task<size_t> result;
|
||||
if (!_verify_and_return_task(details::_out_stream_msg, result)) return result;
|
||||
@@ -273,7 +339,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
- auto sharedStr = std::make_shared<std::basic_string<CharType>>(str);
|
||||
+ auto sharedStr = std::make_shared<std::basic_string<CharType,traits>>(str);
|
||||
return helper()->m_buffer.putn_nocopy(sharedStr->c_str(), sharedStr->size()).then([sharedStr](size_t size) {
|
||||
return size;
|
||||
});
|
||||
@@ -294,7 +360,7 @@
|
||||
if (!_verify_and_return_task(details::_out_stream_msg, result)) return result;
|
||||
// TODO in the future this could be improved to have Value2StringFormatter avoid another unnecessary copy
|
||||
// by putting the string on the heap before calling the print string overload.
|
||||
- return print(details::Value2StringFormatter<CharType>::format(val));
|
||||
+ return print(details::Value2StringFormatter<CharType, traits>::format(val));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
--- a/Release/include/cpprest/astreambuf.h (revision d17f091b5a753b33fb455e92b590fc9f4e921119)
|
||||
+++ b/Release/include/cpprest/astreambuf.h (revision 4188ad89b2cf2e8de3cc3513adcf400fbfdc5ce7)
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "cpprest/asyncrt_utils.h"
|
||||
#include "cpprest/details/basic_types.h"
|
||||
+#include "cpprest/details/char_traits.h"
|
||||
#include "pplx/pplxtasks.h"
|
||||
#include <atomic>
|
||||
#include <cstring>
|
||||
@@ -56,55 +57,28 @@
|
||||
/// <typeparam name="_CharType">
|
||||
/// The data type of the basic element of the stream.
|
||||
/// </typeparam>
|
||||
+namespace detail
|
||||
+{
|
||||
template<typename _CharType>
|
||||
-struct char_traits : std::char_traits<_CharType>
|
||||
+struct char_traits : utility::CanUseStdCharTraits<_CharType>::TraitsType
|
||||
{
|
||||
/// <summary>
|
||||
/// Some synchronous functions will return this value if the operation
|
||||
/// requires an asynchronous call in a given situation.
|
||||
/// </summary>
|
||||
/// <returns>An <c>int_type</c> value which implies that an asynchronous call is required.</returns>
|
||||
- static typename std::char_traits<_CharType>::int_type requires_async()
|
||||
+ static typename utility::CanUseStdCharTraits<_CharType>::TraitsType::int_type requires_async()
|
||||
{
|
||||
- return std::char_traits<_CharType>::eof() - 1;
|
||||
+ return utility::CanUseStdCharTraits<_CharType>::TraitsType::eof() - 1;
|
||||
}
|
||||
+};
|
||||
+}
|
||||
+template<typename _CharType> struct char_traits : detail::char_traits<_CharType> {
|
||||
};
|
||||
#if !defined(_WIN32)
|
||||
-template<>
|
||||
-struct char_traits<unsigned char> : private std::char_traits<char>
|
||||
-{
|
||||
-public:
|
||||
- typedef unsigned char char_type;
|
||||
-
|
||||
- using std::char_traits<char>::eof;
|
||||
- using std::char_traits<char>::int_type;
|
||||
- using std::char_traits<char>::off_type;
|
||||
- using std::char_traits<char>::pos_type;
|
||||
-
|
||||
- static size_t length(const unsigned char* str)
|
||||
- {
|
||||
- return std::char_traits<char>::length(reinterpret_cast<const char*>(str));
|
||||
- }
|
||||
-
|
||||
- static void assign(unsigned char& left, const unsigned char& right) { left = right; }
|
||||
- static unsigned char* assign(unsigned char* left, size_t n, unsigned char value)
|
||||
- {
|
||||
- return reinterpret_cast<unsigned char*>(
|
||||
- std::char_traits<char>::assign(reinterpret_cast<char*>(left), n, static_cast<char>(value)));
|
||||
- }
|
||||
-
|
||||
- static unsigned char* copy(unsigned char* left, const unsigned char* right, size_t n)
|
||||
- {
|
||||
- return reinterpret_cast<unsigned char*>(
|
||||
- std::char_traits<char>::copy(reinterpret_cast<char*>(left), reinterpret_cast<const char*>(right), n));
|
||||
- }
|
||||
-
|
||||
- static unsigned char* move(unsigned char* left, const unsigned char* right, size_t n)
|
||||
- {
|
||||
- return reinterpret_cast<unsigned char*>(
|
||||
- std::char_traits<char>::move(reinterpret_cast<char*>(left), reinterpret_cast<const char*>(right), n));
|
||||
- }
|
||||
-
|
||||
+template <> struct char_traits<unsigned char> : detail::char_traits<unsigned char> {
|
||||
+ typedef typename std::char_traits<char>::int_type int_type;
|
||||
+ static int_type eof() { return std::char_traits<char>::eof(); }
|
||||
static int_type requires_async() { return eof() - 1; }
|
||||
};
|
||||
#endif
|
||||
new file mode 100644
|
||||
--- /dev/null (revision 4188ad89b2cf2e8de3cc3513adcf400fbfdc5ce7)
|
||||
+++ b/Release/include/cpprest/details/char_traits.h (revision 4188ad89b2cf2e8de3cc3513adcf400fbfdc5ce7)
|
||||
@@ -0,0 +1,102 @@
|
||||
+//
|
||||
+// Created by sigsegv on 6/28/25.
|
||||
+//
|
||||
+
|
||||
+#ifndef CPPRESTSDK_ROOT_CHAR_TRAITS_H
|
||||
+#define CPPRESTSDK_ROOT_CHAR_TRAITS_H
|
||||
+
|
||||
+#include <type_traits>
|
||||
+#include <string>
|
||||
+
|
||||
+namespace utility {
|
||||
+
|
||||
+namespace detail {
|
||||
+
|
||||
+template <typename T> struct IntTypeFor {
|
||||
+ typedef typename std::conditional<std::is_unsigned<T>::value, unsigned long long int, long long int>::type type;
|
||||
+};
|
||||
+template <> struct IntTypeFor<char> {
|
||||
+ typedef typename std::char_traits<char>::int_type type;
|
||||
+};
|
||||
+template <> struct IntTypeFor<unsigned char> {
|
||||
+ typedef typename std::make_unsigned<typename std::char_traits<char>::int_type>::type type;
|
||||
+};
|
||||
+
|
||||
+template <typename T> class DetailCharTraits
|
||||
+{
|
||||
+public:
|
||||
+ using char_type = T;
|
||||
+ using int_type = typename IntTypeFor<T>::type;
|
||||
+ using off_type = std::streamoff;
|
||||
+ using pos_type = std::streampos;
|
||||
+ using state_type = mbstate_t;
|
||||
+
|
||||
+ static void assign(char_type& r, const char_type& a) noexcept { r = a; }
|
||||
+ static char_type to_char_type(int_type c) noexcept { return char_type(c); }
|
||||
+ static int_type to_int_type(char_type c) noexcept { return c; }
|
||||
+ static bool eq(char_type a, char_type b) noexcept { return a == b; }
|
||||
+ static bool lt(char_type a, char_type b) noexcept { return a < b; }
|
||||
+ static int compare(const char_type* s1,const char_type* s2,size_t n){
|
||||
+ for (; n--; ++s1, ++s2) {
|
||||
+ if (!eq(*s1, *s2))
|
||||
+ return lt(*s1,*s2)?-1:1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+ }
|
||||
+ static size_t length(const char_type* s){
|
||||
+ const char_type* p = s;
|
||||
+ while (*p)
|
||||
+ ++p;
|
||||
+ return size_t(p - s);
|
||||
+ }
|
||||
+ static const char_type* find(const char_type* s,size_t n,const char_type& a){
|
||||
+ for (; n--; ++s)
|
||||
+ {
|
||||
+ if (eq(*s, a))
|
||||
+ return s;
|
||||
+ return nullptr;
|
||||
+ }
|
||||
+ }
|
||||
+ static char_type* move (char_type* r,const char_type* s,size_t n){
|
||||
+ return (char_type*)memmove(r, s, n * sizeof(char_type));
|
||||
+ }
|
||||
+ static char_type* copy (char_type* r,const char_type* s,size_t n){
|
||||
+ return (char_type*)memcpy (r, s, n * sizeof(char_type));
|
||||
+ }
|
||||
+ static char_type* assign(char_type* r,size_t n,char_type a){
|
||||
+ if (sizeof(char_type) == 1)
|
||||
+ {
|
||||
+ return (char_type*)memset(r, a, n);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ for (char_type *s = r; n--; ++s)
|
||||
+ {
|
||||
+ *s = a;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ static int_type eof() noexcept { return ~0u; }
|
||||
+ static int_type not_eof(int_type c) noexcept { return c == eof() ? 0 : c; }
|
||||
+};
|
||||
+
|
||||
+template <typename T, typename = bool> struct CanUseStdCharTraits : public std::false_type
|
||||
+{
|
||||
+public:
|
||||
+ typedef DetailCharTraits<T> TraitsType;
|
||||
+};
|
||||
+
|
||||
+template <typename T> struct CanUseStdCharTraits<T, decltype(std::char_traits<T>::eq(std::declval<T>(), std::declval<T>()))> : public std::true_type
|
||||
+{
|
||||
+public:
|
||||
+ typedef std::char_traits<T> TraitsType;
|
||||
+};
|
||||
+
|
||||
+}
|
||||
+
|
||||
+template <typename T> struct CanUseStdCharTraits : detail::CanUseStdCharTraits<typename std::remove_const<typename std::remove_reference<T>::type>::type> {
|
||||
+};
|
||||
+
|
||||
+}
|
||||
+
|
||||
+#endif // CPPRESTSDK_ROOT_CHAR_TRAITS_H
|
||||
--- a/Release/tests/functional/streams/memstream_tests.cpp (revision d17f091b5a753b33fb455e92b590fc9f4e921119)
|
||||
+++ b/Release/tests/functional/streams/memstream_tests.cpp (revision 6df13a8c0417ef700c0f164bcd0686ad46f66fd9)
|
||||
@@ -8,6 +8,7 @@
|
||||
*
|
||||
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
****/
|
||||
+#include "cpprest/details/char_traits.h"
|
||||
#include "stdafx.h"
|
||||
#if defined(__cplusplus_winrt)
|
||||
#include <wrl.h>
|
||||
@@ -32,7 +33,7 @@
|
||||
{
|
||||
VERIFY_IS_TRUE(wbuf.can_write());
|
||||
|
||||
- std::basic_string<typename StreamBufferType::char_type> s;
|
||||
+ std::basic_string<typename StreamBufferType::char_type,typename utility::CanUseStdCharTraits<typename StreamBufferType::char_type>::TraitsType> s;
|
||||
s.push_back((typename StreamBufferType::char_type)0);
|
||||
s.push_back((typename StreamBufferType::char_type)1);
|
||||
s.push_back((typename StreamBufferType::char_type)2);
|
||||
@@ -137,7 +138,7 @@
|
||||
{
|
||||
VERIFY_IS_TRUE(wbuf.can_write());
|
||||
|
||||
- std::basic_string<typename StreamBufferType::char_type> s;
|
||||
+ std::basic_string<typename StreamBufferType::char_type,typename utility::CanUseStdCharTraits<typename StreamBufferType::char_type>::TraitsType> s;
|
||||
s.push_back((typename StreamBufferType::char_type)0);
|
||||
s.push_back((typename StreamBufferType::char_type)1);
|
||||
s.push_back((typename StreamBufferType::char_type)2);
|
||||
@@ -169,7 +170,7 @@
|
||||
|
||||
typedef concurrency::streams::rawptr_buffer<CharType> StreamBufferType;
|
||||
|
||||
- std::basic_string<CharType> s;
|
||||
+ std::basic_string<CharType,typename CanUseStdCharTraits<CharType>::TraitsType> s;
|
||||
s.push_back((CharType)0);
|
||||
s.push_back((CharType)1);
|
||||
s.push_back((CharType)2);
|
||||
@@ -198,7 +199,7 @@
|
||||
typedef concurrency::streams::container_buffer<CollectionType> StreamBufferType;
|
||||
typedef typename concurrency::streams::container_buffer<CollectionType>::char_type CharType;
|
||||
|
||||
- std::basic_string<CharType> s;
|
||||
+ std::basic_string<CharType, typename utility::CanUseStdCharTraits<CharType>::TraitsType> s;
|
||||
s.push_back((CharType)0);
|
||||
s.push_back((CharType)1);
|
||||
s.push_back((CharType)2);
|
||||
@@ -553,7 +554,7 @@
|
||||
VERIFY_IS_TRUE(rwbuf.can_read());
|
||||
VERIFY_IS_TRUE(rwbuf.can_write());
|
||||
VERIFY_IS_FALSE(rwbuf.is_eof());
|
||||
- std::basic_string<typename StreamBufferType::char_type> s;
|
||||
+ std::basic_string<typename StreamBufferType::char_type, typename utility::CanUseStdCharTraits<typename StreamBufferType::char_type>::TraitsType> s;
|
||||
s.push_back((typename StreamBufferType::char_type)0);
|
||||
s.push_back((typename StreamBufferType::char_type)1);
|
||||
s.push_back((typename StreamBufferType::char_type)2);
|
||||
@@ -684,7 +685,7 @@
|
||||
VERIFY_IS_TRUE(rwbuf.can_write());
|
||||
|
||||
// Write 4 characters
|
||||
- std::basic_string<typename StreamBufferType::char_type> s;
|
||||
+ std::basic_string<typename StreamBufferType::char_type, typename utility::CanUseStdCharTraits<typename StreamBufferType::char_type>::TraitsType> s;
|
||||
s.push_back((typename StreamBufferType::char_type)0);
|
||||
s.push_back((typename StreamBufferType::char_type)1);
|
||||
s.push_back((typename StreamBufferType::char_type)2);
|
||||
@@ -726,7 +727,7 @@
|
||||
VERIFY_IS_TRUE(rwbuf.can_write());
|
||||
|
||||
// Write 4 characters
|
||||
- std::basic_string<typename StreamBufferType::char_type> s;
|
||||
+ std::basic_string<typename StreamBufferType::char_type, typename utility::CanUseStdCharTraits<typename StreamBufferType::char_type>::TraitsType> s;
|
||||
s.push_back((typename StreamBufferType::char_type)0);
|
||||
s.push_back((typename StreamBufferType::char_type)1);
|
||||
s.push_back((typename StreamBufferType::char_type)2);
|
||||
--- a/Release/tests/functional/streams/stdstream_tests.cpp (revision d17f091b5a753b33fb455e92b590fc9f4e921119)
|
||||
+++ b/Release/tests/functional/streams/stdstream_tests.cpp (revision 6df13a8c0417ef700c0f164bcd0686ad46f66fd9)
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "cpprest/filestream.h"
|
||||
#include "cpprest/producerconsumerstream.h"
|
||||
#include "cpprest/rawptrstream.h"
|
||||
+#include "cpprest/details/char_traits.h"
|
||||
|
||||
#if (!defined(_WIN32) || !defined(CPPREST_EXCLUDE_WEBSOCKETS)) && !defined(__cplusplus_winrt)
|
||||
#include <boost/interprocess/streams/bufferstream.hpp>
|
||||
@@ -303,7 +304,8 @@
|
||||
|
||||
const std::streamsize iterations = 100;
|
||||
|
||||
- const std::string the_alphabet("abcdefghijklmnopqrstuvwxyz");
|
||||
+ const char *the_alphabet_characters = "abcdefghijklmnopqrstuvwxyz";
|
||||
+ const std::basic_string<uint8_t,typename utility::CanUseStdCharTraits<uint8_t>::TraitsType> the_alphabet(reinterpret_cast<const uint8_t *>(the_alphabet_characters));
|
||||
|
||||
auto writer = pplx::create_task([ostream, iterations, the_alphabet]() {
|
||||
auto os = ostream;
|
||||
@@ -341,7 +343,8 @@
|
||||
|
||||
const std::streamsize iterations = 100;
|
||||
|
||||
- const std::string the_alphabet("abcdefghijklmnopqrstuvwxyz");
|
||||
+ const char *the_alphabet_chars = "abcdefghijklmnopqrstuvwxyz";
|
||||
+ const std::basic_string<uint8_t,typename CanUseStdCharTraits<uint8_t>::TraitsType> the_alphabet(reinterpret_cast<const uint8_t *>(the_alphabet_chars));
|
||||
|
||||
auto writer = pplx::create_task([ostream, iterations, the_alphabet]() {
|
||||
auto os = ostream;
|
||||
@@ -0,0 +1,216 @@
|
||||
--- a/Release/include/cpprest/json.h
|
||||
+++ b/Release/include/cpprest/json.h
|
||||
@@ -737,12 +737,10 @@
|
||||
_ASYNCRTIMP void format(std::basic_string<char>& string) const;
|
||||
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
- explicit value(std::unique_ptr<details::_Value> v, value_type kind) : m_value(std::move(v)), m_kind(kind)
|
||||
+ explicit value(std::unique_ptr<details::_Value> v, value_type kind);
|
||||
#else
|
||||
- explicit value(std::unique_ptr<details::_Value> v) : m_value(std::move(v))
|
||||
+ explicit value(std::unique_ptr<details::_Value> v);
|
||||
#endif
|
||||
- {
|
||||
- }
|
||||
|
||||
std::unique_ptr<details::_Value> m_value;
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
@@ -831,9 +829,9 @@
|
||||
typedef storage_type::size_type size_type;
|
||||
|
||||
private:
|
||||
- array() : m_elements() {}
|
||||
- array(size_type size) : m_elements(size) {}
|
||||
- array(storage_type elements) : m_elements(std::move(elements)) {}
|
||||
+ array();
|
||||
+ array(size_type size);
|
||||
+ array(storage_type elements);
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
@@ -915,20 +913,13 @@
|
||||
/// <returns>Iterator to the new location of the element following the erased element.</returns>
|
||||
/// <remarks>GCC doesn't support erase with const_iterator on vector yet. In the future this should be
|
||||
/// changed.</remarks>
|
||||
- iterator erase(iterator position) { return m_elements.erase(position); }
|
||||
+ iterator erase(iterator position);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the element at an index of the JSON array.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the element to delete.</param>
|
||||
- void erase(size_type index)
|
||||
- {
|
||||
- if (index >= m_elements.size())
|
||||
- {
|
||||
- throw json_exception("index out of bounds");
|
||||
- }
|
||||
- m_elements.erase(m_elements.begin() + index);
|
||||
- }
|
||||
+ void erase(size_type index);
|
||||
|
||||
/// <summary>
|
||||
/// Accesses an element of a JSON array. Throws when index out of bounds.
|
||||
@@ -959,15 +950,7 @@
|
||||
/// </summary>
|
||||
/// <param name="index">The index of an element in the JSON array.</param>
|
||||
/// <returns>A reference to the value kept in the field.</returns>
|
||||
- json::value& operator[](size_type index)
|
||||
- {
|
||||
- msl::safeint3::SafeInt<size_type> nMinSize(index);
|
||||
- nMinSize += 1;
|
||||
- msl::safeint3::SafeInt<size_type> nlastSize(m_elements.size());
|
||||
- if (nlastSize < nMinSize) m_elements.resize((size_type)nMinSize);
|
||||
-
|
||||
- return m_elements[index];
|
||||
- }
|
||||
+ json::value& operator[](size_type index);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of elements of the array.
|
||||
@@ -998,14 +981,8 @@
|
||||
typedef storage_type::size_type size_type;
|
||||
|
||||
private:
|
||||
- object(bool keep_order = false) : m_elements(), m_keep_order(keep_order) {}
|
||||
- object(storage_type elements, bool keep_order = false) : m_elements(std::move(elements)), m_keep_order(keep_order)
|
||||
- {
|
||||
- if (!keep_order)
|
||||
- {
|
||||
- sort(m_elements.begin(), m_elements.end(), compare_pairs);
|
||||
- }
|
||||
- }
|
||||
+ object(bool keep_order = false);
|
||||
+ object(storage_type elements, bool keep_order = false);
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
@@ -1087,22 +1064,13 @@
|
||||
/// <returns>Iterator to the new location of the element following the erased element.</returns>
|
||||
/// <remarks>GCC doesn't support erase with const_iterator on vector yet. In the future this should be
|
||||
/// changed.</remarks>
|
||||
- iterator erase(iterator position) { return m_elements.erase(position); }
|
||||
+ iterator erase(iterator position);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes an element of the JSON object. If the key doesn't exist, this method throws.
|
||||
/// </summary>
|
||||
/// <param name="key">The key of an element in the JSON object.</param>
|
||||
- void erase(const utility::string_t& key)
|
||||
- {
|
||||
- auto iter = find_by_key(key);
|
||||
- if (iter == m_elements.end())
|
||||
- {
|
||||
- throw web::json::json_exception("Key not found");
|
||||
- }
|
||||
-
|
||||
- m_elements.erase(iter);
|
||||
- }
|
||||
+ void erase(const utility::string_t& key);
|
||||
|
||||
/// <summary>
|
||||
/// Accesses an element of a JSON object. If the key doesn't exist, this method throws.
|
||||
@@ -1142,17 +1110,7 @@
|
||||
/// <param name="key">The key of an element in the JSON object.</param>
|
||||
/// <returns>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.</returns>
|
||||
- json::value& operator[](const utility::string_t& key)
|
||||
- {
|
||||
- auto iter = find_insert_location(key);
|
||||
-
|
||||
- if (iter == m_elements.end() || key != iter->first)
|
||||
- {
|
||||
- return m_elements.insert(iter, std::pair<utility::string_t, value>(key, value()))->second;
|
||||
- }
|
||||
-
|
||||
- return iter->second;
|
||||
- }
|
||||
+ json::value& operator[](const utility::string_t& key);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an iterator to an element of a JSON object.
|
||||
--- a/Release/src/json/json.cpp
|
||||
+++ b/Release/src/json/json.cpp
|
||||
@@ -135,6 +135,14 @@
|
||||
{
|
||||
}
|
||||
|
||||
+#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
+web::json::value::value(std::unique_ptr<details::_Value> v, value_type kind) : m_value(std::move(v)), m_kind(kind)
|
||||
+#else
|
||||
+web::json::value::value(std::unique_ptr<details::_Value> v) : m_value(std::move(v))
|
||||
+#endif
|
||||
+{
|
||||
+}
|
||||
+
|
||||
web::json::value::value(const value& other)
|
||||
: m_value(other.m_value->_copy_value())
|
||||
#ifdef ENABLE_JSON_VALUE_VISUALIZER
|
||||
@@ -495,3 +503,67 @@
|
||||
#endif
|
||||
return instance;
|
||||
}
|
||||
+
|
||||
+web::json::array::array() : m_elements() {}
|
||||
+web::json::array::array(size_type size) : m_elements(size) {}
|
||||
+web::json::array::array(storage_type elements) : m_elements(std::move(elements)) {}
|
||||
+
|
||||
+web::json::array::iterator web::json::array::erase(web::json::array::iterator position)
|
||||
+{
|
||||
+ return m_elements.erase(position);
|
||||
+}
|
||||
+
|
||||
+void web::json::array::erase(web::json::array::size_type index)
|
||||
+{
|
||||
+ if (index >= m_elements.size())
|
||||
+ {
|
||||
+ throw json_exception("index out of bounds");
|
||||
+ }
|
||||
+ m_elements.erase(m_elements.begin() + index);
|
||||
+}
|
||||
+
|
||||
+json::value& web::json::array::operator[](web::json::array::size_type index)
|
||||
+{
|
||||
+ msl::safeint3::SafeInt<size_type> nMinSize(index);
|
||||
+ nMinSize += 1;
|
||||
+ msl::safeint3::SafeInt<size_type> nlastSize(m_elements.size());
|
||||
+ if (nlastSize < nMinSize) m_elements.resize((size_type)nMinSize);
|
||||
+
|
||||
+ return m_elements[index];
|
||||
+}
|
||||
+
|
||||
+web::json::object::object(bool keep_order) : m_elements(), m_keep_order(keep_order) {}
|
||||
+web::json::object::object(storage_type elements, bool keep_order) : m_elements(std::move(elements)), m_keep_order(keep_order)
|
||||
+{
|
||||
+ if (!keep_order)
|
||||
+ {
|
||||
+ sort(m_elements.begin(), m_elements.end(), compare_pairs);
|
||||
+ }
|
||||
+}
|
||||
+web::json::object::iterator web::json::object::erase(iterator position)
|
||||
+{
|
||||
+ return m_elements.erase(position);
|
||||
+}
|
||||
+
|
||||
+void web::json::object::erase(const utility::string_t& key)
|
||||
+{
|
||||
+ auto iter = find_by_key(key);
|
||||
+ if (iter == m_elements.end())
|
||||
+ {
|
||||
+ throw web::json::json_exception("Key not found");
|
||||
+ }
|
||||
+
|
||||
+ m_elements.erase(iter);
|
||||
+}
|
||||
+
|
||||
+json::value& web::json::object::operator[](const utility::string_t& key)
|
||||
+{
|
||||
+ auto iter = find_insert_location(key);
|
||||
+
|
||||
+ if (iter == m_elements.end() || key != iter->first)
|
||||
+ {
|
||||
+ return m_elements.insert(iter, std::pair<utility::string_t, value>(key, value()))->second;
|
||||
+ }
|
||||
+
|
||||
+ return iter->second;
|
||||
+}
|
||||
Reference in New Issue
Block a user