diff --git a/doc/ref/corelib/basic_json.md b/doc/ref/corelib/basic_json.md
index 8ab66e4976..c72108bed2 100644
--- a/doc/ref/corelib/basic_json.md
+++ b/doc/ref/corelib/basic_json.md
@@ -206,6 +206,10 @@ for their storage, otherwise attempts to return a default constructed allocator.
at at_or_null |
Return the specified value. |
+
+ at at_or_null |
+ Attempts to convert a basic_json value to a value of a type if it matches, otherwise a default value. |
+
get_value_or |
Return the specified value if available, otherwise a default value. |
diff --git a/doc/ref/corelib/json/as.md b/doc/ref/corelib/json/as.md
index 13b7034868..25ec0494a2 100644
--- a/doc/ref/corelib/json/as.md
+++ b/doc/ref/corelib/json/as.md
@@ -55,7 +55,7 @@ Output:
(1) 2147483647
(2) -2147483648
(3) 2147483648
-(4) ÷
+(4) �
(5) 4294967286
(6) 10
(7) 10.5
diff --git a/doc/ref/corelib/json/as_or.md b/doc/ref/corelib/json/as_or.md
new file mode 100644
index 0000000000..0c2079fb15
--- /dev/null
+++ b/doc/ref/corelib/json/as_or.md
@@ -0,0 +1,55 @@
+### jsoncons::basic_json::as_or
+
+```cpp
+template
+T as_or(U&& default_value) const;
+```
+
+Checks the value of the json value with the template value using [json_type_traits](../json_type_traits.md), and converts if it matches, or returns a default value if it doesn't.
+
+See [as](as.md) for details on the value returned.
+
+### Type requirements
+
+- `U` must be convertible to `T`
+
+### Examples
+
+#### Return a value if the type matches, or a default value otherwise
+
+```cpp
+#include
+
+int main()
+{
+ json j = json::parse("\"Hello World\"");
+
+ std::cout << j.as_or(-1) << "\n";
+ std::cout << j.as_or("null") << "\n";
+}
+```
+Output:
+```
+-1
+Hello World
+```
+
+#### Return a value if it exists and the type matches, or a default value otherwise
+
+```cpp
+#include
+
+int main()
+{
+ json j(json_object_arg, {{"author","Evelyn Waugh"},{"title","Sword of Honour"},{"id","0"}});
+ std::cout << j.at_or_null("author").as_or("unknown") << "\n";
+ std::cout << j.at_or_null("category").as_or("fiction") << "\n";
+ std::cout << j.at_or_null("id").as_or(-1) << "\n";
+}
+```
+Output:
+```
+Evelyn Waugh
+fiction
+-1
+```
diff --git a/doc/ref/corelib/json/get_value_or.md b/doc/ref/corelib/json/get_value_or.md
index bc07b86187..b6cfa583df 100644
--- a/doc/ref/corelib/json/get_value_or.md
+++ b/doc/ref/corelib/json/get_value_or.md
@@ -1,7 +1,7 @@
### jsoncons::basic_json::get_value_or
```cpp
-template
+template
T get_value_or(const string_view_type& name, U&& default_value) const;
```
diff --git a/include/jsoncons/basic_json.hpp b/include/jsoncons/basic_json.hpp
index ff271dc2f9..e6c7ec1b18 100644
--- a/include/jsoncons/basic_json.hpp
+++ b/include/jsoncons/basic_json.hpp
@@ -3699,6 +3699,24 @@ namespace jsoncons {
}
}
+ template
+ typename std::enable_if::value,T>::type
+ as_or(U&& default_value) const
+ {
+ static_assert(std::is_convertible::value,
+ "as_or: U must be convertible to T");
+ using T_type_traits = json_type_traits;
+ if (T_type_traits::is(*this))
+ {
+ T val = T_type_traits::as(*this);
+ return val;
+ }
+ else
+ {
+ return static_cast(std::forward(default_value));
+ }
+ }
+
const basic_json& at_or_null(const string_view_type& key) const
{
switch (storage_kind())
diff --git a/test/corelib/src/json_object_tests.cpp b/test/corelib/src/json_object_tests.cpp
index 0dbf70981e..5838b55fa6 100644
--- a/test/corelib/src/json_object_tests.cpp
+++ b/test/corelib/src/json_object_tests.cpp
@@ -297,6 +297,40 @@ TEST_CASE("test_empty_object_move_assignment")
CHECK(c.is_object());
}
+TEST_CASE("as_or test")
+{
+ json a = json::parse(R"(
+ {
+ "key1" : "value1",
+ "key2" : "3.7",
+ "key3" : 1.5,
+ "key4" : 1
+ }
+ )");
+
+ std::string s1 = a.as_or("null");
+ std::string s2 = a["key1"].as_or("null");
+ std::string s3 = a["key2"].as_or("null");
+ std::string s4 = a["key3"].as_or("null");
+ int i1 = a["key1"].as_or(-1);
+ int i2 = a["key3"].as_or(-1);
+ int i3 = a["key4"].as_or(-1);
+ double d1 = a["key2"].as_or(-1.0);
+ double d2 = a["key3"].as_or(-1.0);
+ double d3 = a["key4"].as_or(-1.0);
+
+ CHECK(s1 == std::string("null"));
+ CHECK(s2 == std::string("value1"));
+ CHECK(s3 == std::string("3.7"));
+ CHECK(s4 == std::string("null"));
+ CHECK(i1 == -1);
+ CHECK(i2 == -1);
+ CHECK(i3 == 1);
+ CHECK(d1 == -1.0);
+ CHECK(d2 == 1.5);
+ CHECK(d3 == -1.0);
+}
+
TEST_CASE("at_or_null test")
{
json a = json::parse(R"(