Directory: | ./ |
---|---|
File: | include/ndcurves/serialization/archive.hpp |
Date: | 2025-03-05 17:18:30 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 49 | 63 | 77.8% |
Branches: | 32 | 92 | 34.8% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright (c) 2015-2018, CNRS | ||
2 | // Authors: Justin Carpentier <jcarpent@laas.fr> | ||
3 | |||
4 | #ifndef __curves_serialization_archive_hpp__ | ||
5 | #define __curves_serialization_archive_hpp__ | ||
6 | #include <boost/archive/binary_iarchive.hpp> | ||
7 | #include <boost/archive/binary_oarchive.hpp> | ||
8 | #include <boost/archive/text_iarchive.hpp> | ||
9 | #include <boost/archive/text_oarchive.hpp> | ||
10 | #include <boost/archive/xml_iarchive.hpp> | ||
11 | #include <boost/archive/xml_oarchive.hpp> | ||
12 | #include <boost/serialization/version.hpp> | ||
13 | #include <fstream> | ||
14 | #include <stdexcept> | ||
15 | #include <string> | ||
16 | |||
17 | /* Define the current version number for the serialization | ||
18 | * Must be increased everytime the save() method of a class is modified | ||
19 | * Or when a change is made to register_types() | ||
20 | * */ | ||
21 | const unsigned int CURVES_API_VERSION = 1; | ||
22 | |||
23 | #define SINGLE_ARG(...) \ | ||
24 | __VA_ARGS__ // Macro used to be able to put comma in the following macro | ||
25 | // arguments | ||
26 | // Macro used to define the serialization version of a templated class | ||
27 | #define DEFINE_CLASS_TEMPLATE_VERSION(Template, Type) \ | ||
28 | namespace boost { \ | ||
29 | namespace serialization { \ | ||
30 | template <Template> \ | ||
31 | struct version<Type> { \ | ||
32 | static constexpr unsigned int value = CURVES_API_VERSION; \ | ||
33 | }; \ | ||
34 | template <Template> \ | ||
35 | constexpr unsigned int version<Type>::value; \ | ||
36 | } \ | ||
37 | } | ||
38 | |||
39 | namespace ndcurves { | ||
40 | namespace serialization { | ||
41 | struct Serializable { | ||
42 | private: | ||
43 | template <class Derived> | ||
44 | 129 | Derived& derived() { | |
45 | 129 | return *static_cast<Derived*>(this); | |
46 | } | ||
47 | template <class Derived> | ||
48 | 129 | const Derived& derived() const { | |
49 | 129 | return *static_cast<const Derived*>(this); | |
50 | } | ||
51 | |||
52 | public: | ||
53 | /// \brief Loads a Derived object from a text file. | ||
54 | template <class Derived> | ||
55 | 69 | void loadFromText(const std::string& filename) { | |
56 |
1/2✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
|
69 | std::ifstream ifs(filename.c_str()); |
57 |
2/4✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 36 times.
✗ Branch 4 not taken.
|
69 | if (ifs) { |
58 |
1/2✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
|
69 | boost::archive::text_iarchive ia(ifs); |
59 |
1/2✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
|
69 | ia >> derived<Derived>(); |
60 | 69 | } else { | |
61 | ✗ | const std::string exception_message(filename + | |
62 | " does not seem to be a valid file."); | ||
63 | ✗ | throw std::invalid_argument(exception_message); | |
64 | } | ||
65 | 69 | } | |
66 | |||
67 | /// \brief Saved a Derived object as a text file. | ||
68 | template <class Derived> | ||
69 | 69 | void saveAsText(const std::string& filename) const { | |
70 |
1/2✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
|
69 | std::ofstream ofs(filename.c_str()); |
71 |
2/4✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 36 times.
✗ Branch 4 not taken.
|
69 | if (ofs) { |
72 |
1/2✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
|
69 | boost::archive::text_oarchive oa(ofs); |
73 |
1/2✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
|
69 | oa << derived<Derived>(); |
74 | 69 | } else { | |
75 | ✗ | const std::string exception_message(filename + | |
76 | " does not seem to be a valid file."); | ||
77 | ✗ | throw std::invalid_argument(exception_message); | |
78 | } | ||
79 | 69 | } | |
80 | |||
81 | /// \brief Loads a Derived object from an XML file. | ||
82 | template <class Derived> | ||
83 | 29 | void loadFromXML(const std::string& filename, const std::string& tag_name) { | |
84 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
|
29 | if (tag_name.empty()) { |
85 | ✗ | throw std::invalid_argument("tag_name cannot be empty."); | |
86 | } | ||
87 |
1/2✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
|
29 | std::ifstream ifs(filename.c_str()); |
88 |
2/4✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
29 | if (ifs) { |
89 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
29 | boost::archive::xml_iarchive ia(ifs); |
90 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
29 | ia >> |
91 | 29 | boost::serialization::make_nvp(tag_name.c_str(), derived<Derived>()); | |
92 | 29 | } else { | |
93 | ✗ | const std::string exception_message(filename + | |
94 | " does not seem to be a valid file."); | ||
95 | ✗ | throw std::invalid_argument(exception_message); | |
96 | } | ||
97 | 29 | } | |
98 | |||
99 | /// \brief Saved a Derived object as an XML file. | ||
100 | template <class Derived> | ||
101 | 29 | void saveAsXML(const std::string& filename, | |
102 | const std::string& tag_name) const { | ||
103 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
|
29 | if (tag_name.empty()) { |
104 | ✗ | throw std::invalid_argument("tag_name cannot be empty."); | |
105 | } | ||
106 |
1/2✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
|
29 | std::ofstream ofs(filename.c_str()); |
107 |
2/4✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
29 | if (ofs) { |
108 |
1/2✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
|
29 | boost::archive::xml_oarchive oa(ofs); |
109 |
1/2✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
|
29 | oa << boost::serialization::make_nvp(tag_name.c_str(), |
110 | derived<Derived>()); | ||
111 | 29 | } else { | |
112 | ✗ | const std::string exception_message(filename + | |
113 | " does not seem to be a valid file."); | ||
114 | ✗ | throw std::invalid_argument(exception_message); | |
115 | } | ||
116 | 29 | } | |
117 | |||
118 | /// \brief Loads a Derived object from an binary file. | ||
119 | template <class Derived> | ||
120 | 31 | void loadFromBinary(const std::string& filename) { | |
121 |
1/2✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
|
31 | std::ifstream ifs(filename.c_str()); |
122 |
2/4✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
✗ Branch 4 not taken.
|
31 | if (ifs) { |
123 |
1/2✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
31 | boost::archive::binary_iarchive ia(ifs); |
124 |
1/2✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
|
31 | ia >> derived<Derived>(); |
125 | 31 | } else { | |
126 | ✗ | const std::string exception_message(filename + | |
127 | " does not seem to be a valid file."); | ||
128 | ✗ | throw std::invalid_argument(exception_message); | |
129 | } | ||
130 | 31 | } | |
131 | |||
132 | /// \brief Saved a Derived object as an binary file. | ||
133 | template <class Derived> | ||
134 | 31 | void saveAsBinary(const std::string& filename) const { | |
135 |
1/2✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
|
31 | std::ofstream ofs(filename.c_str()); |
136 |
2/4✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
✗ Branch 4 not taken.
|
31 | if (ofs) { |
137 |
1/2✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
|
31 | boost::archive::binary_oarchive oa(ofs); |
138 |
1/2✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
|
31 | oa << derived<Derived>(); |
139 | 31 | } else { | |
140 | ✗ | const std::string exception_message(filename + | |
141 | " does not seem to be a valid file."); | ||
142 | ✗ | throw std::invalid_argument(exception_message); | |
143 | } | ||
144 | 31 | } | |
145 | }; // End struct Serializable | ||
146 | |||
147 | } // namespace serialization | ||
148 | |||
149 | } // namespace ndcurves | ||
150 | |||
151 | #endif // ifndef __multicontact_api_serialization_archive_hpp__ | ||
152 |