diff --git a/docs/rfl_ref.md b/docs/rfl_ref.md index 60bc7a93..02ea28f5 100644 --- a/docs/rfl_ref.md +++ b/docs/rfl_ref.md @@ -138,6 +138,16 @@ This will result in the following JSON string: {"leafOrNode":{"type":"Node","criticalValue":10.0,"lesser":{"leafOrNode":{"type":"Leaf","value":3.0}},"greater":{"leafOrNode":{"type":"Leaf","value":5.0}}}} ``` +You can also initialize `rfl::Box` from a `std::unique_ptr`: + +```cpp +auto ptr = std::make_unique("Hello World!"); +const rfl::Result> box = rfl::make_box(std::move(ptr)); +``` + +Note that `box` is wrapped in a `Result`. That is, because we cannot guarantee at compile time +that `ptr` is not `nullptr`, therefore we need to account for that. + If you want to use reference-counted pointers, instead of unique pointers, you can use `rfl::Ref`. `rfl::Ref` is the same concept as `rfl::Box`, but using `std::shared_ptr` under-the-hood. diff --git a/include/rfl/Box.hpp b/include/rfl/Box.hpp index c6eb806d..e3063246 100644 --- a/include/rfl/Box.hpp +++ b/include/rfl/Box.hpp @@ -4,6 +4,8 @@ #include #include +#include "Result.hpp" + namespace rfl { /// The Box class behaves very similarly to the unique_ptr, but unlike the @@ -20,6 +22,15 @@ class Box { return Box(std::make_unique(std::forward(_args)...)); } + /// You can generate them from unique_ptrs as well, in which case it will + /// return an Error, if the unique_ptr is not set. + static Result> make(std::unique_ptr&& _ptr) { + if (!_ptr) { + return Error("std::unique_ptr was a nullptr."); + } + return Box(std::move(_ptr)); + } + Box() : ptr_(std::make_unique()) {} Box(const Box& _other) = delete; @@ -77,7 +88,7 @@ class Box { /// Generates a new Ref. template -Box make_box(Args&&... _args) { +auto make_box(Args&&... _args) { return Box::make(std::forward(_args)...); } diff --git a/include/rfl/Ref.hpp b/include/rfl/Ref.hpp index e65217a7..e59379af 100644 --- a/include/rfl/Ref.hpp +++ b/include/rfl/Ref.hpp @@ -4,6 +4,8 @@ #include #include +#include "Result.hpp" + namespace rfl { /// The Ref class behaves very similarly to the shared_ptr, but unlike the @@ -20,6 +22,24 @@ class Ref { return Ref(std::make_shared(std::forward(_args)...)); } + /// You can generate them from shared_ptrs as well, in which case it will + /// return an Error, if the shared_ptr is not set. + static Result> make(std::shared_ptr&& _ptr) { + if (!_ptr) { + return Error("std::shared_ptr was a nullptr."); + } + return Ref(std::move(_ptr)); + } + + /// You can generate them from shared_ptrs as well, in which case it will + /// return an Error, if the shared_ptr is not set. + static Result> make(const std::shared_ptr& _ptr) { + if (!_ptr) { + return Error("std::shared_ptr was a nullptr."); + } + return Ref(_ptr); + } + Ref() : ptr_(std::make_shared()) {} Ref(const Ref& _other) = default; @@ -87,7 +107,7 @@ class Ref { /// Generates a new Ref. template -Ref make_ref(Args&&... _args) { +auto make_ref(Args&&... _args) { return Ref::make(std::forward(_args)...); } diff --git a/tests/json/test_box2.cpp b/tests/json/test_box2.cpp new file mode 100644 index 00000000..5733948f --- /dev/null +++ b/tests/json/test_box2.cpp @@ -0,0 +1,27 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "test_box.hpp" + +namespace test_box2 { + +void test() { + std::cout << std::source_location::current().function_name() << std::endl; + + auto ptr = std::make_unique("Hello World!"); + const rfl::Result> box = + rfl::make_box(std::move(ptr)); + + if (box) { + std::cout << "OK" << std::endl << std::endl; + } else { + std::cout << "Expected the result to be successful." << std::endl + << std::endl; + } +} +} // namespace test_box2 diff --git a/tests/json/test_box2.hpp b/tests/json/test_box2.hpp new file mode 100644 index 00000000..63c3c303 --- /dev/null +++ b/tests/json/test_box2.hpp @@ -0,0 +1,4 @@ +namespace test_box2 { +void test(); +} + diff --git a/tests/json/tests.cpp b/tests/json/tests.cpp index bd82b48c..3dca4d97 100644 --- a/tests/json/tests.cpp +++ b/tests/json/tests.cpp @@ -10,6 +10,7 @@ #include "test_as2.hpp" #include "test_as_flatten.hpp" #include "test_box.hpp" +#include "test_box2.hpp" #include "test_c_array_class1.hpp" #include "test_c_array_class2.hpp" #include "test_c_array_class3.hpp" @@ -98,6 +99,7 @@ int main() { test_field_variant::test(); test_ref::test(); test_box::test(); + test_box2::test(); test_array::test(); test_timestamp::test(); test_flatten::test();