lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] master fb65723 09/12: Serialize pairs to and from xm


From: Greg Chicares
Subject: [lmi-commits] [lmi] master fb65723 09/12: Serialize pairs to and from xml
Date: Sat, 24 Oct 2020 16:51:36 -0400 (EDT)

branch: master
commit fb6572368a4c8d2f6ea99d96b1c0f5d380ae720e
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>

    Serialize pairs to and from xml
---
 xml_serialize.hpp      | 44 ++++++++++++++++++++++++++++++++++++++++++++
 xml_serialize_test.cpp | 25 +++++++++++++++++++------
 2 files changed, 63 insertions(+), 6 deletions(-)

diff --git a/xml_serialize.hpp b/xml_serialize.hpp
index a18f5d8..49d1822 100644
--- a/xml_serialize.hpp
+++ b/xml_serialize.hpp
@@ -25,6 +25,7 @@
 #include "config.hpp"
 
 #include "assert_lmi.hpp"
+#include "ssize_lmi.hpp"
 #include "value_cast.hpp"
 #include "xml_lmi.hpp"
 
@@ -32,6 +33,7 @@
 
 #include <string>
 #include <type_traits>
+#include <utility>                      // pair
 #include <vector>
 
 /// Serialization to and from xml.
@@ -69,6 +71,48 @@ struct xml_io
     }
 };
 
+/// Serialization for std::pair.
+
+template<typename P>
+struct xml_pair_io
+{
+    using T1 = typename P::first_type;
+    using T2 = typename P::second_type;
+
+    static_assert(std::is_same<P,std::pair<T1,T2>>::value);
+
+    static void to_xml(xml::element& parent, P const& p)
+    {
+        parent.clear();
+
+        // This is equivalent to calling set_element(), except that
+        // the parent element has imperatively been cleared.
+        xml::element e1("first");
+        xml_io<T1>::to_xml(e1, p.first);
+        parent.push_back(e1);
+
+        xml::element e2("second");
+        xml_io<T2>::to_xml(e2, p.second);
+        parent.push_back(e2);
+    }
+
+    static void from_xml(xml::element const& parent, P& p)
+    {
+        auto const& view_first {parent.elements("first")};
+        LMI_ASSERT(1 == lmi::ssize(view_first));
+        xml_io<T1>::from_xml(*view_first.begin(), p.first);
+
+        auto const& view_second {parent.elements("second")};
+        LMI_ASSERT(1 == lmi::ssize(view_second));
+        xml_io<T2>::from_xml(*view_second.begin(), p.second);
+    }
+};
+
+template<typename T1, typename T2>
+struct xml_io<std::pair<T1,T2>>
+  :public xml_pair_io<std::pair<T1,T2>>
+{};
+
 /// Serialization for sequence containers.
 ///
 /// Derive publicly from this to use its implementation when
diff --git a/xml_serialize_test.cpp b/xml_serialize_test.cpp
index 1ebe87c..d5f79fe 100644
--- a/xml_serialize_test.cpp
+++ b/xml_serialize_test.cpp
@@ -28,6 +28,7 @@
 #include "timer.hpp"
 
 #include <string>
+#include <utility>                      // pair
 #include <vector>
 
 // All /write.*/ functions save xml to this string.
@@ -41,13 +42,15 @@ int const number_of_elements = 20;
 // /[dsv]0/: constant values for /write.*/ functions.
 // /[dsv]1/: variables for /read.*/ functions.
 
-double           const d0(2.718281828459045235360);
-std::string      const s0("string with ampersand & embedded spaces");
-std::vector<int> const v0 {10, 2, 4}; // Be a pepper...
+double             const d0(2.718281828459045235360);
+std::string        const s0("string with ampersand & embedded spaces");
+std::pair<int,int> const p0 {17, 19};
+std::vector<int>   const v0 {10, 2, 4}; // Be a pepper...
 
-double                 d1;
-std::string            s1;
-std::vector<int>       v1;
+double                   d1;
+std::string              s1;
+std::pair<int,int>       p1;
+std::vector<int>         v1;
 
 void write()
 {
@@ -55,6 +58,7 @@ void write()
     xml::element& root = document.root_node();
     xml_serialize::set_element(root, "d", d0);
     xml_serialize::set_element(root, "s", s0);
+    xml_serialize::set_element(root, "p", p0);
     xml_serialize::set_element(root, "v", v0);
     dom_string = document.str();
 }
@@ -65,6 +69,7 @@ void read()
     xml::element const& root = parser.root_node("eraseme");
     xml_serialize::get_element(root, "d", d1);
     xml_serialize::get_element(root, "s", s1);
+    xml_serialize::get_element(root, "p", p1);
     xml_serialize::get_element(root, "v", v1);
 }
 
@@ -84,6 +89,7 @@ void read_erroneous()
     xml::element const& root = parser.root_node("eraseme");
     xml_serialize::get_element(root, "d", d1);
     xml_serialize::get_element(root, "s", s1);
+    xml_serialize::get_element(root, "p", p1);
     xml_serialize::get_element(root, "v", v1);
     xml_serialize::get_element(root, "f", f1); // Error: no <f> element.
 }
@@ -140,6 +146,9 @@ void mete_read_d()  {mete_read ("d", d1);}
 void mete_write_s() {mete_write("s", s0);}
 void mete_read_s()  {mete_read ("s", s1);}
 
+void mete_write_p() {mete_write("p", p0);}
+void mete_read_p()  {mete_read ("p", p1);}
+
 void mete_write_v() {mete_write("v", v0);}
 void mete_read_v()  {mete_read ("v", v1);}
 
@@ -160,6 +169,8 @@ int test_main(int, char*[])
     // BOOST_TEST_EQUAL() inserts unequal values into an ostream, so
     // it can only be used with streamable types (as above).
 
+    BOOST_TEST(p0 == p1);
+
     // For Containers, test both
     //   P: c0 == c1
     //   Q: c0.size() == c1.size()
@@ -183,6 +194,8 @@ int test_main(int, char*[])
     std::cout << "  Read  d     : " << TimeAnAliquot(mete_read_d ) << '\n';
     std::cout << "  Write s     : " << TimeAnAliquot(mete_write_s) << '\n';
     std::cout << "  Read  s     : " << TimeAnAliquot(mete_read_s ) << '\n';
+    std::cout << "  Write p     : " << TimeAnAliquot(mete_write_p) << '\n';
+    std::cout << "  Read  p     : " << TimeAnAliquot(mete_read_p ) << '\n';
     std::cout << "  Write v     : " << TimeAnAliquot(mete_write_v) << '\n';
     std::cout << "  Read  v     : " << TimeAnAliquot(mete_read_v ) << '\n';
     std::cout << std::endl;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]