libcrn  3.9.5
A document image processing library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CRNVector.cpp
Go to the documentation of this file.
1 /* Copyright 2006-2016 Yann LEYDIER, INSA-Lyon, CoReNum, 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: CRNVector.cpp
19  * \author Yann LEYDIER
20  */
21 
22 #include <CRNData/CRNVector.h>
23 #include <CRNException.h>
24 #include <CRNIO/CRNIO.h>
25 #include <algorithm>
26 #include <CRNData/CRNMap.h>
27 #include <CRNData/CRNDataFactory.h>
28 #include <CRNi18n.h>
29 
30 using namespace crn;
31 
36 Vector::Vector() = default;
40 Vector::~Vector() = default;
41 
42 Vector::Vector(const Vector &other)
43 {
44  for (const auto &o : other)
45  data.push_back(Clone(*o));
46 }
47 
49 {
50  data.clear();
51  for (const auto &o : other)
52  data.push_back(Clone(*o));
53  return *this;
54 }
55 
61 void Vector::PushBack(const SObject &d)
62 {
63  data.push_back(d);
64 }
65 
72 bool Vector::Contains(const SCObject &o) const
73 {
74  for (const_iterator it = begin(); it != end(); ++it)
75  if (*it == o)
76  return true;
77  return false;
78 }
79 
86 Vector::const_iterator Vector::Find(const SCObject &o) const
87 {
88  for (const_iterator it = begin(); it != end(); ++it)
89  if (*it == o)
90  return it;
91  return end();
92 }
93 
100 Vector::iterator Vector::Find(const SCObject &o)
101 {
102  for (iterator it = begin(); it != end(); ++it)
103  if (*it == o)
104  return it;
105  return end();
106 }
107 
117 void Vector::Insert(const SObject &d, size_t pos)
118 {
119  if (pos < data.size())
120  {
121  data.insert(data.begin() + pos, d);
122  }
123  else if ((pos == data.size()) || (pos == 0))
124  {
125  data.push_back(d);
126  }
127  else
128  throw ExceptionDomain(_("Index out of bounds."));
129 }
130 
139 void Vector::ReorderFrom(const std::vector<size_t> &from)
140 {
141  if (from.size() != data.size())
142  {
143  throw ExceptionDimension(StringUTF8("void Vector::ReorderFrom(const std::vector<size_t> &from): ") +
144  _("bad changeset size."));
145  }
146  std::set<size_t> cont;
147  for (size_t i : from)
148  {
149  cont.insert(i);
150  }
151  if (cont.size() != data.size())
152  {
153  throw ExceptionLogic(StringUTF8("void Vector::ReorderFrom(const std::vector<size_t> &from): ") +
154  _("changeset contains duplicates."));
155  }
156  if ((*cont.begin() != 0) || (*cont.rbegin() != data.size() - 1))
157  {
158  throw ExceptionDomain(StringUTF8("void Vector::ReorderFrom(const std::vector<size_t> &from): ") +
159  _("changeset contains values out of bounds."));
160  }
161  std::vector<SObject> newdata;
162  for (size_t i : from)
163  {
164  newdata.push_back(data[i]);
165  }
166  data.swap(newdata);
167 }
168 
177 void Vector::ReorderTo(const std::vector<size_t> &to)
178 {
179  if (to.size() != data.size())
180  {
181  throw ExceptionDimension(StringUTF8("void Vector::ReorderTo(const std::vector<size_t> &to): ") +
182  _("bad changeset size."));
183  }
184  std::set<size_t> cont;
185  for (size_t i : to)
186  {
187  cont.insert(i);
188  }
189  if (cont.size() != data.size())
190  {
191  throw ExceptionLogic(StringUTF8("void Vector::ReorderTo(const std::vector<size_t> &to): ") +
192  _("changeset contains duplicates."));
193  }
194  if ((*cont.begin() != 0) || (*cont.rbegin() != data.size() - 1))
195  {
196  throw ExceptionDomain(StringUTF8("void Vector::ReorderTo(const std::vector<size_t> &to): ") +
197  _("changeset contains values out of bounds."));
198  }
199  std::vector<SObject> newdata(data.size());
200  for (size_t tmp = 0; tmp < to.size(); ++tmp)
201  {
202  newdata[to[tmp]] = data[tmp];
203  }
204  data.swap(newdata);
205 }
206 
213 void Vector::Remove(size_t index)
214 {
215  if (index >= data.size())
216  throw ExceptionDomain(_("Index out of bounds."));
217  data.erase(data.begin() + index);
218 }
219 
226 void Vector::Remove(const SCObject &obj)
227 {
228  for (auto it = data.begin(); it != data.end(); ++it)
229  if (*it == obj)
230  {
231  data.erase(it);
232  return;
233  }
234  throw ExceptionNotFound(_("Object not found."));
235 }
236 
241 void Vector::Remove(iterator it)
242 {
243  data.erase(it.it);
244 }
245 
251 void Vector::Remove(iterator begin, iterator end)
252 {
253  data.erase(begin.it, end.it);
254 }
255 
256 /*****************************************************************************/
268 {
269  if (el.GetValue() != getClassName())
270  {
271  throw ExceptionInvalidArgument(StringUTF8("void Vector::Deserialize(xml::Element &el): ") +
272  _("Wrong XML element."));
273  }
274  std::multimap<int, SObject> xmllist;
275  for (xml::Element te = el.BeginElement(); te != el.EndElement(); ++te)
276  {
277  SObject d(nullptr);
278  try
279  {
280  d = DataFactory::CreateData(te);
281  }
282  catch (crn::Exception &)
283  { // XXX throw?
284  CRNWarning(String(U"void Vector::Deserialize"
285  U"(xml::Element &el): ") + String(_("Unknown XML element: ")) +
286  te.GetValue());
287  }
288  if (!d)
289  continue;
290  int index;
291  try { index = te.GetAttribute<int>("vector_index", false); } catch (...) { index = int(xmllist.size()); }
292  xmllist.insert(std::make_pair(index, d));
293  }
294  Clear();
295  for (auto & elem : xmllist)
296  data.push_back(elem.second);
297  ShrinkToFit();
298 }
299 
300 /*****************************************************************************/
309 {
310  xml::Element el(parent.PushBackElement(getClassName()));
311 
312  for (size_t tmp = 0; tmp < data.size(); tmp++)
313  {
314  xml::Element item = crn::Serialize(*data[tmp], el);
315  item.SetAttribute("vector_index", int(tmp));
316  }
317 
318  return el;
319 }
320 
326 void Vector::Swap(Vector &other) noexcept
327 {
328  data.swap(other.data);
329 }
330 
333 {
334  std::vector<SObject> (data.begin(), data.end()).swap(data);
335 }
336 
342 double crn::Distance(const Vector &v1, const Vector &v2)
343 {
344  if (v1.Size() != v2.Size())
345  throw ExceptionDimension(StringUTF8("double Distance(const Vector&, const Vector&): ") + _("vectors have different sizes."));
346  auto d = 0.0;
347  for (auto tmp : Range(v1))
348  d += Distance(v1[tmp], v2[tmp]);
349  return d;
350 }
351 
354  Cloner::Register<Vector>();
355  Ruler::Register<Vector>();
357 
xml::Element Serialize(const Object &obj, xml::Element &parent)
Writes an object to XML if possible.
Definition: CRNObject.cpp:110
void Swap(Vector &other) noexcept
Swaps contents with another vector.
Definition: CRNVector.cpp:326
ScalarRange< T > Range(T b, T e)
Creates a range [[b, e[[.
Definition: CRNType.h:257
const_iterator Find(const SCObject &o) const
Finds an object in the container.
Definition: CRNVector.cpp:86
XML element.
Definition: CRNXml.h:135
#define _(String)
Definition: CRNi18n.h:51
void ShrinkToFit()
Optimizes the memory usage.
Definition: CRNVector.cpp:332
iterator begin()
Returns an iterator to the first element.
Definition: CRNVector.h:100
void Remove(size_t index)
Removes an element (safe)
Definition: CRNVector.cpp:213
static UObject CreateData(xml::Element &el)
Creates and initializes a SObject from an XML element.
#define CRNWarning(x)
Definition: CRNIO.h:145
virtual ~Vector() override
Destructor.
Element BeginElement()
Gets the first child element.
Definition: CRNXml.h:174
#define CRN_END_CLASS_CONSTRUCTOR(classname)
Defines a class constructor.
Definition: CRNObject.h:198
A generic logic error.
Definition: CRNException.h:71
Vector & operator=(const Vector &)
Definition: CRNVector.cpp:48
A UTF32 character string class.
Definition: CRNString.h:61
void Insert(const SObject &d, size_t pos)
Inserts an object at a given position.
Definition: CRNVector.cpp:117
A generic domain error.
Definition: CRNException.h:83
bool Contains(const SCObject &o) const
Checks of the object is in the vector.
Definition: CRNVector.cpp:72
#define CRN_DATA_FACTORY_REGISTER(elemname, classname)
Registers a class to the data factory.
virtual StringUTF8 GetValue() const
Gets the content of the node.
Definition: CRNXml.cpp:171
A dimension error.
Definition: CRNException.h:119
void SetAttribute(const StringUTF8 &name, const StringUTF8 &value)
Sets the value of an attribute.
Definition: CRNXml.cpp:595
void Clear() noexcept
Empties the vector.
Definition: CRNVector.h:96
double Distance(const Int &i1, const Int &i2) noexcept
Definition: CRNInt.h:78
Data vector class.
Definition: CRNVector.h:42
xml::Element Serialize(xml::Element &parent) const
Dumps to an XML node if applicable.
Definition: CRNVector.cpp:308
iterator end()
Returns a iterator to the end of the list.
Definition: CRNVector.h:102
Vector()
Default constructor.
void Deserialize(xml::Element &el)
Reads from an XML node if applicable.
Definition: CRNVector.cpp:267
void ReorderFrom(const std::vector< size_t > &from)
Reorders the elements.
Definition: CRNVector.cpp:139
A character string class.
Definition: CRNStringUTF8.h:49
void PushBack(const SObject &d)
Adds an object at the end of the vector.
Definition: CRNVector.cpp:61
UObject Clone(const Object &obj)
Clones an object if possible.
Definition: CRNObject.cpp:35
Base class for exceptions.
Definition: CRNException.h:39
Element PushBackElement(const StringUTF8 &name)
Adds an element at the end of the children list.
Definition: CRNXml.cpp:355
Element EndElement()
Gets a null node.
Definition: CRNXml.h:176
size_t Size() const noexcept
Returns the number of data objects in the vector.
Definition: CRNVector.h:56
void ReorderTo(const std::vector< size_t > &to)
Reorders the elements.
Definition: CRNVector.cpp:177
Invalid argument error (e.g.: nullptr pointer)
Definition: CRNException.h:107
#define CRN_BEGIN_CLASS_CONSTRUCTOR(classname)
Defines a class constructor.
Definition: CRNObject.h:185
An item was not found in a container.
Definition: CRNException.h:95