-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Seamlessly support non-default-constructable custom class deserialization #1087
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
mzoll
wants to merge
17
commits into
jbeder:master
Choose a base branch
from
mzoll:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
abc841d
get this all compiling; currently with a pair notation; should be a s…
7a984e2
return to single arg returns
8783c5e
fixes
e40fa44
fixes
4d77eee
fixes of introduced bug
92559b8
push push tutorial
5f5b183
simplify life a little bit
6bd373f
a single copy of this exception is enough
7371173
add a Node::ContainsKey function for quick checking of subordinated
0bfa7a7
Merge remote-tracking branch 'origin/master'
8120c0c
fix this test by making a convert description
0bb0428
slip of hand: or >>> ||
5c05c68
Merge branch 'jbeder:master' into master
mzoll 433689e
a working formulation integrating a new API for non-default construct…
b46d569
a working formulation integrating a new API for non-default construct…
cc2018e
Merge remote-tracking branch 'origin/merge_amalgam' into merge_amalgam
6f79903
slightly better structure; remove id-constexpr all together in favour…
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -178,11 +178,12 @@ struct convert<Vec3> { | |||||||||||||
| return node; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| static bool decode(const Node& node, Vec3& rhs) { | ||||||||||||||
| static Vec3 decode(const Node& node) { | ||||||||||||||
| if(!node.IsSequence() || node.size() != 3) { | ||||||||||||||
| return false; | ||||||||||||||
| throw YAML::conversion::DecodeException(""); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| Vec3 rhs; | ||||||||||||||
| rhs.x = node[0].as<double>(); | ||||||||||||||
| rhs.y = node[1].as<double>(); | ||||||||||||||
| rhs.z = node[2].as<double>(); | ||||||||||||||
|
|
@@ -197,5 +198,50 @@ Then you could use `Vec3` wherever you could use any other type: | |||||||||||||
| ```cpp | ||||||||||||||
| YAML::Node node = YAML::Load("start: [1, 3, 0]"); | ||||||||||||||
| Vec3 v = node["start"].as<Vec3>(); | ||||||||||||||
| node["end"] = Vec3(2, -1, 0); | ||||||||||||||
| ``` | ||||||||||||||
| node["end"] = Vec3{2, -1, 0}; | ||||||||||||||
| ``` | ||||||||||||||
|
|
||||||||||||||
| Observe that in the above example the custom type is, decalred as | ||||||||||||||
| a struct, explicit default constructable and all its members are | ||||||||||||||
| exposed. For non default constructable types like | ||||||||||||||
|
|
||||||||||||||
| ```cpp | ||||||||||||||
| class NonDefCtorVec3 : public Vec3 { | ||||||||||||||
| using Vec3::x; | ||||||||||||||
| using Vec3::y; | ||||||||||||||
| using Vec3::z; | ||||||||||||||
|
Comment on lines
+210
to
+212
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using statements are not required.
Suggested change
|
||||||||||||||
| public: | ||||||||||||||
| NonDefCtorVec3(double x, double y, double z) | ||||||||||||||
| : Vec3() { this->x=x; this->y=y; this->z=z; | ||||||||||||||
| }; | ||||||||||||||
|
Comment on lines
+214
to
+216
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Proper initialization of variables:
Suggested change
|
||||||||||||||
| }; | ||||||||||||||
| ``` | ||||||||||||||
| a new API is available, that freshens up the signature of the 'convert<T>::decode' | ||||||||||||||
| method and introduces the abortion of the deserialization process by throwing | ||||||||||||||
| an `DecodeException`. | ||||||||||||||
|
|
||||||||||||||
| ```cpp | ||||||||||||||
| namespace YAML { | ||||||||||||||
| template <> | ||||||||||||||
| struct convert<NonDefCtorVec3> { | ||||||||||||||
| static Node encode(const NonDefCtorVec3& rhs) { | ||||||||||||||
| return convert<Vec3>::encode(rhs); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| static NonDefCtorVec3 decode(const Node& node) { | ||||||||||||||
| if (!node.IsSequence() || node.size() != 3) { | ||||||||||||||
| throw YAML::conversion::DecodeException(); | ||||||||||||||
| } | ||||||||||||||
| return {node[0].as<double>(), node[1].as<double>(), node[2].as<double>()}; | ||||||||||||||
| } | ||||||||||||||
| }; | ||||||||||||||
| } | ||||||||||||||
| ``` | ||||||||||||||
|
|
||||||||||||||
| The behavior is exactly the same | ||||||||||||||
|
|
||||||||||||||
| ```cpp | ||||||||||||||
| YAML::Node node = YAML::Load("start: [1, 3, 0]"); | ||||||||||||||
| NonDefCtorVec3 v = node["start"].as<NonDefCtorVec3>(); | ||||||||||||||
| node["end"] = NonDefCtorVec3(2, -1, 0); | ||||||||||||||
| ``` | ||||||||||||||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| // | ||
| // Created by marcel on 3/3/22. | ||
| // | ||
|
|
||
| #ifndef YAML_CPP_API_SWITCH_H | ||
| #define YAML_CPP_API_SWITCH_H | ||
|
|
||
| #if defined(_MSC_VER) || \ | ||
| (defined(__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || \ | ||
| (__GNUC__ >= 4)) // GCC supports "pragma once" correctly since 3.4 | ||
| #pragma once | ||
| #endif | ||
|
|
||
| #include "yaml-cpp/node/node.h" | ||
| #include "yaml-cpp/exceptions.h" | ||
| #include <type_traits> | ||
|
|
||
| namespace YAML{ | ||
| namespace detail { | ||
|
|
||
| //detect the method of the new api | ||
| template <typename> | ||
| std::false_type has_decode_new_api(long); | ||
|
|
||
| template <typename T> | ||
| auto has_decode_new_api(int) | ||
| -> decltype( T::decode(std::declval<const Node&>()), std::true_type{}); | ||
|
|
||
| template <bool AorB> | ||
| struct static_api_switch; | ||
|
|
||
| template<> //new api call-path | ||
| struct static_api_switch<true> { | ||
| template<class T> | ||
| static T decode(const Node& node) { | ||
| return convert<T>::decode(node); | ||
| } | ||
| }; | ||
|
|
||
| template<> //old api call-path | ||
| struct static_api_switch<false> { | ||
| template<class T> | ||
| static T decode(const Node& node) { | ||
| T t; | ||
| if (convert<T>::decode(node, t)) | ||
| return t; | ||
| throw conversion::DecodeException(); | ||
| } | ||
| }; | ||
| } | ||
| } | ||
|
|
||
| #endif // YAML_CPP_API_SWITCH_H |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor typo: