diff --git a/.github/workflows/iwyu.yml b/.github/workflows/iwyu.yml
index dd6d10278ec..e796155c544 100644
--- a/.github/workflows/iwyu.yml
+++ b/.github/workflows/iwyu.yml
@@ -2,7 +2,10 @@
# Environment reference https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners
name: include-what-you-use
-on: workflow_dispatch
+on:
+ schedule:
+ - cron: '0 0 * * 0'
+ workflow_dispatch:
permissions:
contents: read
diff --git a/AUTHORS b/AUTHORS
index 442ad24f44a..a3a02656e08 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -76,6 +76,7 @@ Changkyoon Kim
Chris Lalancette
Christian Ehrlicher
Christian Franke
+Christoph GrĂ¼ninger
Christoph Schmidt
Christoph Strehle
Chuck Larson
diff --git a/Makefile b/Makefile
index 9153bf4b300..d4e8ad837fa 100644
--- a/Makefile
+++ b/Makefile
@@ -518,7 +518,7 @@ $(libcppdir)/checkfunctions.o: lib/checkfunctions.cpp lib/addoninfo.h lib/astuti
$(libcppdir)/checkinternal.o: lib/checkinternal.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkinternal.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkinternal.cpp
-$(libcppdir)/checkio.o: lib/checkio.cpp lib/addoninfo.h lib/check.h lib/checkio.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h
+$(libcppdir)/checkio.o: lib/checkio.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkio.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkio.cpp
$(libcppdir)/checkleakautovar.o: lib/checkleakautovar.cpp lib/addoninfo.h lib/astutils.h lib/check.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h
@@ -758,7 +758,7 @@ test/testfunctions.o: test/testfunctions.cpp lib/addoninfo.h lib/check.h lib/che
test/testgarbage.o: test/testgarbage.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testgarbage.cpp
-test/testimportproject.o: test/testimportproject.cpp lib/addoninfo.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h
+test/testimportproject.o: test/testimportproject.cpp lib/addoninfo.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h test/redirect.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testimportproject.cpp
test/testincompletestatement.o: test/testincompletestatement.cpp lib/addoninfo.h lib/check.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
@@ -887,7 +887,7 @@ test/testvaarg.o: test/testvaarg.cpp lib/addoninfo.h lib/check.h lib/checkvaarg.
test/testvalueflow.o: test/testvalueflow.cpp lib/addoninfo.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvalueflow.cpp
-test/testvarid.o: test/testvarid.cpp lib/addoninfo.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h
+test/testvarid.o: test/testvarid.cpp lib/addoninfo.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvarid.cpp
externals/simplecpp/simplecpp.o: externals/simplecpp/simplecpp.cpp externals/simplecpp/simplecpp.h
diff --git a/cfg/posix.cfg b/cfg/posix.cfg
index 25712fcebdd..73197fad4c1 100644
--- a/cfg/posix.cfg
+++ b/cfg/posix.cfg
@@ -6268,6 +6268,7 @@ The function 'mktemp' is considered to be dangerous due to race conditions and s
openat
socket
close
+ fdopen
opendir
diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp
index dc8a9006337..df9bd320428 100644
--- a/cli/cmdlineparser.cpp
+++ b/cli/cmdlineparser.cpp
@@ -198,6 +198,10 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[])
assert(!(!pathnamesRef.empty() && !fileSettingsRef.empty()));
if (!fileSettingsRef.empty()) {
+ // TODO: handle ignored?
+
+ // TODO: de-duplicate
+
std::list fileSettings;
if (!mSettings.fileFilters.empty()) {
// filter only for the selected filenames from all project files
@@ -244,6 +248,19 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[])
}
}
+ // de-duplicate files
+ {
+ auto it = filesResolved.begin();
+ while (it != filesResolved.end()) {
+ const std::string& name = it->first;
+ // TODO: log if duplicated files were dropped
+ filesResolved.erase(std::remove_if(std::next(it), filesResolved.end(), [&](const std::pair& entry) {
+ return entry.first == name;
+ }), filesResolved.end());
+ ++it;
+ }
+ }
+
std::list> files;
if (!mSettings.fileFilters.empty()) {
std::copy_if(filesResolved.cbegin(), filesResolved.cend(), std::inserter(files, files.end()), [&](const decltype(filesResolved)::value_type& entry) {
diff --git a/createrelease b/createrelease
index f0aecf27c13..a2de51afd2b 100755
--- a/createrelease
+++ b/createrelease
@@ -29,7 +29,9 @@
# Create 2.8.x branch
# git checkout -b 2.8.x ; git push -u origin 2.8.x
#
-# Empty the releasenotes.txt in main branch
+# Release notes:
+# - ensure safety critical issues are listed properly
+# - empty the releasenotes.txt in main branch
#
# Update version numbers in:
# sed -i -r "s/version 2[.][0-9]+([.]99)*/version 2.9/" cli/main.cpp
diff --git a/externals/picojson/picojson.h b/externals/picojson/picojson.h
index 48bb64e6723..76742fe06ac 100644
--- a/externals/picojson/picojson.h
+++ b/externals/picojson/picojson.h
@@ -32,6 +32,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -39,972 +40,1161 @@
#include
#include
#include
+#include
// for isnan/isinf
-#if __cplusplus>=201103L
-# include
+#if __cplusplus >= 201103L
+#include
#else
extern "C" {
-# ifdef _MSC_VER
-# include
-# elif defined(__INTEL_COMPILER)
-# include
-# else
-# include
-# endif
+#ifdef _MSC_VER
+#include
+#elif defined(__INTEL_COMPILER)
+#include
+#else
+#include
+#endif
}
#endif
+#ifndef PICOJSON_USE_RVALUE_REFERENCE
+#if (defined(__cpp_rvalue_references) && __cpp_rvalue_references >= 200610) || (defined(_MSC_VER) && _MSC_VER >= 1600)
+#define PICOJSON_USE_RVALUE_REFERENCE 1
+#else
+#define PICOJSON_USE_RVALUE_REFERENCE 0
+#endif
+#endif // PICOJSON_USE_RVALUE_REFERENCE
+
+#ifndef PICOJSON_NOEXCEPT
+#if PICOJSON_USE_RVALUE_REFERENCE
+#define PICOJSON_NOEXCEPT noexcept
+#else
+#define PICOJSON_NOEXCEPT throw()
+#endif
+#endif
+
// experimental support for int64_t (see README.mkdn for detail)
#ifdef PICOJSON_USE_INT64
-# define __STDC_FORMAT_MACROS
-# include
-# include
+#define __STDC_FORMAT_MACROS
+#include
+#if __cplusplus >= 201103L
+#include
+#else
+extern "C" {
+#include
+}
+#endif
#endif
// to disable the use of localeconv(3), set PICOJSON_USE_LOCALE to 0
#ifndef PICOJSON_USE_LOCALE
-# define PICOJSON_USE_LOCALE 1
+#define PICOJSON_USE_LOCALE 1
#endif
#if PICOJSON_USE_LOCALE
extern "C" {
-# include
+#include
}
#endif
#ifndef PICOJSON_ASSERT
-# define PICOJSON_ASSERT(e) do { if (! (e)) throw std::runtime_error(#e); } while (0)
+#define PICOJSON_ASSERT(e) \
+ do { \
+ if (!(e)) \
+ throw std::runtime_error(#e); \
+ } while (0)
#endif
#ifdef _MSC_VER
- #define SNPRINTF _snprintf_s
- #pragma warning(push)
- #pragma warning(disable : 4244) // conversion from int to char
- #pragma warning(disable : 4127) // conditional expression is constant
- #pragma warning(disable : 4702) // unreachable code
+#define SNPRINTF _snprintf_s
+#pragma warning(push)
+#pragma warning(disable : 4244) // conversion from int to char
+#pragma warning(disable : 4127) // conditional expression is constant
+#pragma warning(disable : 4702) // unreachable code
+#pragma warning(disable : 4706) // assignment within conditional expression
#else
- #define SNPRINTF snprintf
+#define SNPRINTF snprintf
#endif
namespace picojson {
-
- enum {
- null_type,
- boolean_type,
- number_type,
- string_type,
- array_type,
- object_type
+
+enum {
+ null_type,
+ boolean_type,
+ number_type,
+ string_type,
+ array_type,
+ object_type
#ifdef PICOJSON_USE_INT64
- , int64_type
+ ,
+ int64_type
#endif
- };
-
- enum {
- INDENT_WIDTH = 2
- };
+};
- struct null {};
-
- class value {
- public:
- typedef std::vector array;
- typedef std::map object;
- union _storage {
- bool boolean_;
- double number_;
-#ifdef PICOJSON_USE_INT64
- int64_t int64_;
-#endif
- std::string* string_;
- array* array_;
- object* object_;
- };
- protected:
- int type_;
- _storage u_;
- public:
- value();
- value(int type, bool);
- explicit value(bool b);
+enum { INDENT_WIDTH = 2, DEFAULT_MAX_DEPTHS = 100 };
+
+struct null {};
+
+class value {
+public:
+ typedef std::vector array;
+ typedef std::map object;
+ union _storage {
+ bool boolean_;
+ double number_;
#ifdef PICOJSON_USE_INT64
- explicit value(int64_t i);
-#endif
- explicit value(double n);
- explicit value(const std::string& s);
- explicit value(const array& a);
- explicit value(const object& o);
- explicit value(const char* s);
- value(const char* s, size_t len);
- ~value();
- value(const value& x);
- value& operator=(const value& x);
- void swap(value& x);
- template bool is() const;
- template const T& get() const;
- template T& get();
- bool evaluate_as_boolean() const;
- const value& get(size_t idx) const;
- const value& get(const std::string& key) const;
- value& get(size_t idx);
- value& get(const std::string& key);
-
- bool contains(size_t idx) const;
- bool contains(const std::string& key) const;
- std::string to_str() const;
- template void serialize(Iter os, bool prettify = false) const;
- std::string serialize(bool prettify = false) const;
- private:
- template value(const T*); // intentionally defined to block implicit conversion of pointer to bool
- template static void _indent(Iter os, int indent);
- template void _serialize(Iter os, int indent) const;
- std::string _serialize(int indent) const;
+ int64_t int64_;
+#endif
+ std::string *string_;
+ array *array_;
+ object *object_;
};
-
- typedef value::array array;
- typedef value::object object;
-
- inline value::value() : type_(null_type) {}
-
- inline value::value(int type, bool) : type_(type) {
- switch (type) {
-#define INIT(p, v) case p##type: u_.p = v; break
- INIT(boolean_, false);
- INIT(number_, 0.0);
+
+protected:
+ int type_;
+ _storage u_;
+
+public:
+ value();
+ value(int type, bool);
+ explicit value(bool b);
#ifdef PICOJSON_USE_INT64
- INIT(int64_, 0);
+ explicit value(int64_t i);
+#endif
+ explicit value(double n);
+ explicit value(const std::string &s);
+ explicit value(const array &a);
+ explicit value(const object &o);
+#if PICOJSON_USE_RVALUE_REFERENCE
+ explicit value(std::string &&s);
+ explicit value(array &&a);
+ explicit value(object &&o);
+#endif
+ explicit value(const char *s);
+ value(const char *s, size_t len);
+ ~value();
+ value(const value &x);
+ value &operator=(const value &x);
+#if PICOJSON_USE_RVALUE_REFERENCE
+ value(value &&x) PICOJSON_NOEXCEPT;
+ value &operator=(value &&x) PICOJSON_NOEXCEPT;
#endif
- INIT(string_, new std::string());
- INIT(array_, new array());
- INIT(object_, new object());
+ void swap(value &x) PICOJSON_NOEXCEPT;
+ template bool is() const;
+ template const T &get() const;
+ template T &get();
+ template void set(const T &);
+#if PICOJSON_USE_RVALUE_REFERENCE
+ template void set(T &&);
+#endif
+ bool evaluate_as_boolean() const;
+ const value &get(const size_t idx) const;
+ const value &get(const std::string &key) const;
+ value &get(const size_t idx);
+ value &get(const std::string &key);
+
+ bool contains(const size_t idx) const;
+ bool contains(const std::string &key) const;
+ std::string to_str() const;
+ template void serialize(Iter os, bool prettify = false) const;
+ std::string serialize(bool prettify = false) const;
+
+private:
+ template value(const T *); // intentionally defined to block implicit conversion of pointer to bool
+ template static void _indent(Iter os, int indent);
+ template void _serialize(Iter os, int indent) const;
+ std::string _serialize(int indent) const;
+ void clear();
+};
+
+typedef value::array array;
+typedef value::object object;
+
+inline value::value() : type_(null_type), u_() {
+}
+
+inline value::value(int type, bool) : type_(type), u_() {
+ switch (type) {
+#define INIT(p, v) \
+ case p##type: \
+ u_.p = v; \
+ break
+ INIT(boolean_, false);
+ INIT(number_, 0.0);
+#ifdef PICOJSON_USE_INT64
+ INIT(int64_, 0);
+#endif
+ INIT(string_, new std::string());
+ INIT(array_, new array());
+ INIT(object_, new object());
#undef INIT
- default: break;
- }
- }
-
- inline value::value(bool b) : type_(boolean_type) {
- u_.boolean_ = b;
+ default:
+ break;
}
+}
+
+inline value::value(bool b) : type_(boolean_type), u_() {
+ u_.boolean_ = b;
+}
#ifdef PICOJSON_USE_INT64
- inline value::value(int64_t i) : type_(int64_type) {
- u_.int64_ = i;
- }
+inline value::value(int64_t i) : type_(int64_type), u_() {
+ u_.int64_ = i;
+}
#endif
- inline value::value(double n) : type_(number_type) {
- if (
+inline value::value(double n) : type_(number_type), u_() {
+ if (
#ifdef _MSC_VER
- ! _finite(n)
-#elif __cplusplus>=201103L || !(defined(isnan) && defined(isinf))
- std::isnan(n) || std::isinf(n)
+ !_finite(n)
+#elif __cplusplus >= 201103L
+ std::isnan(n) || std::isinf(n)
#else
- isnan(n) || isinf(n)
+ isnan(n) || isinf(n)
#endif
- ) {
- throw std::overflow_error("");
- }
- u_.number_ = n;
- }
-
- inline value::value(const std::string& s) : type_(string_type) {
- u_.string_ = new std::string(s);
- }
-
- inline value::value(const array& a) : type_(array_type) {
- u_.array_ = new array(a);
- }
-
- inline value::value(const object& o) : type_(object_type) {
- u_.object_ = new object(o);
- }
-
- inline value::value(const char* s) : type_(string_type) {
- u_.string_ = new std::string(s);
- }
-
- inline value::value(const char* s, size_t len) : type_(string_type) {
- u_.string_ = new std::string(s, len);
- }
-
- inline value::~value() {
- switch (type_) {
-#define DEINIT(p) case p##type: delete u_.p; break
- DEINIT(string_);
- DEINIT(array_);
- DEINIT(object_);
+ ) {
+ throw std::overflow_error("");
+ }
+ u_.number_ = n;
+}
+
+inline value::value(const std::string &s) : type_(string_type), u_() {
+ u_.string_ = new std::string(s);
+}
+
+inline value::value(const array &a) : type_(array_type), u_() {
+ u_.array_ = new array(a);
+}
+
+inline value::value(const object &o) : type_(object_type), u_() {
+ u_.object_ = new object(o);
+}
+
+#if PICOJSON_USE_RVALUE_REFERENCE
+inline value::value(std::string &&s) : type_(string_type), u_() {
+ u_.string_ = new std::string(std::move(s));
+}
+
+inline value::value(array &&a) : type_(array_type), u_() {
+ u_.array_ = new array(std::move(a));
+}
+
+inline value::value(object &&o) : type_(object_type), u_() {
+ u_.object_ = new object(std::move(o));
+}
+#endif
+
+inline value::value(const char *s) : type_(string_type), u_() {
+ u_.string_ = new std::string(s);
+}
+
+inline value::value(const char *s, size_t len) : type_(string_type), u_() {
+ u_.string_ = new std::string(s, len);
+}
+
+inline void value::clear() {
+ switch (type_) {
+#define DEINIT(p) \
+ case p##type: \
+ delete u_.p; \
+ break
+ DEINIT(string_);
+ DEINIT(array_);
+ DEINIT(object_);
#undef DEINIT
- default: break;
- }
+ default:
+ break;
}
-
- inline value::value(const value& x) : type_(x.type_) {
- switch (type_) {
-#define INIT(p, v) case p##type: u_.p = v; break
- INIT(string_, new std::string(*x.u_.string_));
- INIT(array_, new array(*x.u_.array_));
- INIT(object_, new object(*x.u_.object_));
+}
+
+inline value::~value() {
+ clear();
+}
+
+inline value::value(const value &x) : type_(x.type_), u_() {
+ switch (type_) {
+#define INIT(p, v) \
+ case p##type: \
+ u_.p = v; \
+ break
+ INIT(string_, new std::string(*x.u_.string_));
+ INIT(array_, new array(*x.u_.array_));
+ INIT(object_, new object(*x.u_.object_));
#undef INIT
- default:
- u_ = x.u_;
- break;
- }
+ default:
+ u_ = x.u_;
+ break;
}
-
- inline value& value::operator=(const value& x) {
- if (this != &x) {
- value t(x);
- swap(t);
- }
- return *this;
- }
-
- inline void value::swap(value& x) {
- std::swap(type_, x.type_);
- std::swap(u_, x.u_);
+}
+
+inline value &value::operator=(const value &x) {
+ if (this != &x) {
+ value t(x);
+ swap(t);
}
-
-#define IS(ctype, jtype) \
- template <> inline bool value::is() const { \
- return type_ == jtype##_type; \
+ return *this;
+}
+
+#if PICOJSON_USE_RVALUE_REFERENCE
+inline value::value(value &&x) PICOJSON_NOEXCEPT : type_(null_type), u_() {
+ swap(x);
+}
+inline value &value::operator=(value &&x) PICOJSON_NOEXCEPT {
+ swap(x);
+ return *this;
+}
+#endif
+inline void value::swap(value &x) PICOJSON_NOEXCEPT {
+ std::swap(type_, x.type_);
+ std::swap(u_, x.u_);
+}
+
+#define IS(ctype, jtype) \
+ template <> inline bool value::is() const { \
+ return type_ == jtype##_type; \
}
- IS(null, null)
- IS(bool, boolean)
+IS(null, null)
+IS(bool, boolean)
#ifdef PICOJSON_USE_INT64
- IS(int64_t, int64)
+IS(int64_t, int64)
#endif
- IS(std::string, string)
- IS(array, array)
- IS(object, object)
+IS(std::string, string)
+IS(array, array)
+IS(object, object)
#undef IS
- template <> inline bool value::is() const {
- return type_ == number_type
+template <> inline bool value::is() const {
+ return type_ == number_type
#ifdef PICOJSON_USE_INT64
- || type_ == int64_type
+ || type_ == int64_type
#endif
;
+}
+
+#define GET(ctype, var) \
+ template <> inline const ctype &value::get() const { \
+ PICOJSON_ASSERT("type mismatch! call is() before get()" && is()); \
+ return var; \
+ } \
+ template <> inline ctype &value::get() { \
+ PICOJSON_ASSERT("type mismatch! call is() before get()" && is()); \
+ return var; \
}
-
-#define GET(ctype, var) \
- template <> inline const ctype& value::get() const { \
- PICOJSON_ASSERT("type mismatch! call is() before get()" \
- && is()); \
- return var; \
- } \
- template <> inline ctype& value::get() { \
- PICOJSON_ASSERT("type mismatch! call is() before get()" \
- && is()); \
- return var; \
- }
- GET(bool, u_.boolean_)
- GET(std::string, *u_.string_)
- GET(array, *u_.array_)
- GET(object, *u_.object_)
+GET(bool, u_.boolean_)
+GET(std::string, *u_.string_)
+GET(array, *u_.array_)
+GET(object, *u_.object_)
#ifdef PICOJSON_USE_INT64
- GET(double, (type_ == int64_type && (const_cast(this)->type_ = number_type, const_cast(this)->u_.number_ = u_.int64_), u_.number_))
- GET(int64_t, u_.int64_)
+GET(double,
+ (type_ == int64_type && (const_cast(this)->type_ = number_type, (const_cast(this)->u_.number_ = u_.int64_)),
+ u_.number_))
+GET(int64_t, u_.int64_)
#else
- GET(double, u_.number_)
+GET(double, u_.number_)
#endif
#undef GET
-
- inline bool value::evaluate_as_boolean() const {
- switch (type_) {
- case null_type:
- return false;
- case boolean_type:
- return u_.boolean_;
- case number_type:
- return u_.number_ != 0;
- case string_type:
- return ! u_.string_->empty();
- default:
- return true;
- }
- }
-
- inline const value& value::get(size_t idx) const {
- static value s_null;
- PICOJSON_ASSERT(is());
- return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null;
- }
- inline value& value::get(size_t idx) {
- static value s_null;
- PICOJSON_ASSERT(is());
- return idx < u_.array_->size() ? (*u_.array_)[idx] : s_null;
+#define SET(ctype, jtype, setter) \
+ template <> inline void value::set(const ctype &_val) { \
+ clear(); \
+ type_ = jtype##_type; \
+ setter \
}
+SET(bool, boolean, u_.boolean_ = _val;)
+SET(std::string, string, u_.string_ = new std::string(_val);)
+SET(array, array, u_.array_ = new array(_val);)
+SET(object, object, u_.object_ = new object(_val);)
+SET(double, number, u_.number_ = _val;)
+#ifdef PICOJSON_USE_INT64
+SET(int64_t, int64, u_.int64_ = _val;)
+#endif
+#undef SET
- inline const value& value::get(const std::string& key) const {
- static value s_null;
- PICOJSON_ASSERT(is