libcrn  3.9.5
A document image processing library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CRNProtocols.h
Go to the documentation of this file.
1 /* Copyright 2006-2016 Yann LEYDIER, INSA-Lyon, ENS-Lyon
2  *
3  * This file is part of libcrn.
4  *
5  * libcrn is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * libcrn is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with libcrn. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * file: CRNProtocols.h
19  * \author Yann LEYDIER, Jean DUONG
20  */
21 
22 #ifndef CRNPROTOCOLS
23 #define CRNPROTOCOLS
24 
25 #include <CRNType.h>
26 #include <CRNObject.h>
27 #include <CRNMath/CRNMath.h>
28 #include <unordered_map>
29 #include <typeinfo>
30 #include <typeindex>
31 #include <CRNXml/CRNXml.h>
32 
35 namespace crn
36 {
37  class Serializer
38  {
39  public:
40  static void Deserialize(Object &obj, xml::Element &el)
41  {
42  const auto id = std::type_index{typeid(obj)};
43  const auto it = getInstance().serializers.find(id);
44  if (it == getInstance().serializers.end())
45  throw ExceptionProtocol{id.name() + StringUTF8(": not a serializable object.")};
46  it->second->deserialize(obj, el);
47  }
48  static xml::Element Serialize(const Object &obj, xml::Element &el)
49  {
50  const auto id = std::type_index{typeid(obj)};
51  const auto it = getInstance().serializers.find(id);
52  if (it == getInstance().serializers.end())
53  throw ExceptionProtocol{id.name() + StringUTF8(": not a serializable object.")};
54  return it->second->serialize(obj, el);
55  }
56  template<typename T> static void Register()
57  {
58  getInstance().serializers.emplace(typeid(T), std::make_unique<serializerImpl<T>>());
59  }
60  private:
61  Serializer() {}
62  static Serializer& getInstance();
63  struct serializer
64  {
65  virtual ~serializer() {}
66  virtual void deserialize(Object &obj, xml::Element &el) = 0;
67  virtual xml::Element serialize(const Object &obj, xml::Element &parent) = 0;
68  };
69  template<typename T> struct serializerImpl: public serializer
70  {
71  virtual void deserialize(Object &obj, xml::Element &el) override
72  {
73  static_cast<T&>(obj).Deserialize(el);
74  }
75  virtual xml::Element serialize(const Object &obj, xml::Element &parent) override
76  {
77  return static_cast<const T&>(obj).Serialize(parent);
78  }
79  };
80  std::unordered_map<std::type_index, std::unique_ptr<serializer>> serializers;
81  };
82 
83  class Cloner
84  {
85  public:
86  static UObject Clone(const Object &obj)
87  {
88  const auto id = std::type_index{typeid(obj)};
89  const auto it = getInstance().cloners.find(id);
90  if (it == getInstance().cloners.end())
91  throw ExceptionProtocol{id.name() + StringUTF8(": not a clonable object.")};
92  return it->second->clone(obj);
93  }
94  template<typename T> static void Register()
95  {
96  getInstance().cloners.emplace(typeid(T), std::make_unique<clonerImpl<T>>());
97  }
98 
99  static std::string GetClasses()
100  {
101  auto s = std::string{};
102  for (const auto &c : getInstance().cloners)
103  {
104  s += c.first.name();
105  s += " ";
106  }
107  return s;
108  }
109  private:
110  Cloner() {}
111  static Cloner& getInstance();
112  struct cloner
113  {
114  virtual ~cloner() {}
115  virtual UObject clone(const Object &o) const = 0;
116  };
117  template<typename T> struct clonerImpl: public cloner
118  {
119  virtual UObject clone(const Object &o) const override { return std::make_unique<T>(static_cast<const T&>(o)); }
120  };
121  std::unordered_map<std::type_index, std::unique_ptr<cloner>> cloners;
122  };
123 
124  class Ruler
125  {
126  public:
127  static double ComputeDistance(const Object &o1, const Object &o2)
128  {
129  const auto id1 = std::type_index{typeid(o1)};
130  const auto id2 = std::type_index{typeid(o2)};
131  if (id1 != id2)
132  throw ExceptionDomain{"Cannot compute distance between objects of different classes."};
133  const auto it = getInstance().rulers.find(id1);
134  if (it == getInstance().rulers.end())
135  throw ExceptionProtocol{id1.name() + StringUTF8(": not a metric object.")};
136  return it->second->distance(o1, o2);
137  }
138  template<typename T> static void Register()
139  {
140  getInstance().rulers.emplace(typeid(T), std::make_unique<rulerImpl<T>>());
141  }
142  private:
143  Ruler() {}
144  static Ruler& getInstance();
145  struct ruler
146  {
147  virtual ~ruler() {}
148  virtual double distance(const Object &o1, const Object &o2) const = 0;
149  };
150  template<typename T> struct rulerImpl: public ruler
151  {
152  virtual double distance(const Object &o1, const Object &o2) const override { return Distance(static_cast<const T&>(o1), static_cast<const T&>(o2)); }
153  };
154  std::unordered_map<std::type_index, std::unique_ptr<ruler>> rulers;
155  };
156 
157 }
159 #endif
160 
static xml::Element Serialize(const Object &obj, xml::Element &el)
Definition: CRNProtocols.h:48
XML element.
Definition: CRNXml.h:135
static void Register()
Definition: CRNProtocols.h:56
static void Register()
Definition: CRNProtocols.h:94
static void Deserialize(Object &obj, xml::Element &el)
Definition: CRNProtocols.h:40
A protocol is not implemented.
Definition: CRNException.h:143
A generic domain error.
Definition: CRNException.h:83
static std::string GetClasses()
Definition: CRNProtocols.h:99
static UObject Clone(const Object &obj)
Definition: CRNProtocols.h:86
static double ComputeDistance(const Object &o1, const Object &o2)
Definition: CRNProtocols.h:127
double Distance(const Int &i1, const Int &i2) noexcept
Definition: CRNInt.h:78
static void Register()
Definition: CRNProtocols.h:138
A character string class.
Definition: CRNStringUTF8.h:49