FMT 0.9.8
Forest management tools for forest planning
Loading...
Searching...
No Matches
FMTlist.hpp
Go to the documentation of this file.
1/*
2Copyright (c) 2019 Gouvernement du Québec
3
4SPDX-License-Identifier: LiLiQ-R-1.1
5License-Filename: LICENSES/EN/LiLiQ-R11unicode.txt
6*/
7
8#ifndef FMTlist_H_INCLUDED
9#define FMTlist_H_INCLUDED
10
11#include <boost/unordered_map.hpp>
12#include <functional>
13#include <vector>
14#include <utility>
15
16#include "FMTmask.hpp"
17#include "FMTmaskfilter.hpp"
18#include <boost/serialization/version.hpp>
19#include <boost/serialization/serialization.hpp>
20#include <boost/serialization/hash_collections_save_imp.hpp>
21#include <boost/serialization/hash_collections_load_imp.hpp>
22#include <boost/serialization/split_member.hpp>
23#include <boost/serialization/unordered_map.hpp>
24#include <boost/serialization/vector.hpp>
25#include <boost/serialization/nvp.hpp>
26#include <boost/serialization/export.hpp>
28#include "FMTobject.hpp"
29#include <iterator>
30#include <memory>
31#include "FMTyieldhandler.hpp"
32#include "FMTtheme.hpp"
33
34
35namespace Core
36{
37 // DocString: FMTlist
44 template<typename T>
45 class FMTlist: public FMTobject
46 {
47 public:
48 // DocString: FMTlist::operator+=
55 {
56 try {
57 if (!this->canshrink()||!OtherList.canshrink())
58 {
59 _exhandler->raise(Exception::FMTexc::FMTinvalid_action, "Cant append list together",
60 "FMTlist::operator::+=", __LINE__, __FILE__);
61 }
62 for (const std::pair<FMTmask, T>& Object : OtherList.data)
63 {
64 push_back(Object.first, Object.second);
65 }
66 }catch (...) {
67 _exhandler->raisefromcatch("", "FMTlist::operator::+=", __LINE__, __FILE__);
68
69 }
70 return *this;
71 }
72
73 // DocString: FMTlist::swap
78 {
79 data.swap(rhs.data);
80 filter.swap(rhs.filter);
81 fastpass.swap(rhs.fastpass);
82 }
83 // DocString: FMTlist::getunion
87 FMTmask getunion(const std::vector<FMTtheme>& themes) const
88 {
89 Core::FMTmask testedmask(std::string(this->begin()->first), themes);
90 for (const auto& object : *this)
91 {
92 const Core::FMTmask specificiermask(std::string(object.first), themes);
93 testedmask = testedmask.getunion(specificiermask);
94 }
95 return testedmask;
96 }
97 // DocString: FMTlist()
102 FMTobject(),
103 data(),
104 filter(),
105 fastpass() {};
106 // DocString: FMTlist(const FMTlist&)
110 FMTlist(const FMTlist<T>& rhs) :
111 FMTobject(rhs),
112 data(),
113 filter(rhs.filter),
114 fastpass(rhs.fastpass)
115 {
116 copydata(rhs);
117 }
118 // DocString: FMTlist::operator=
123 {
124 if (this != &rhs)
125 {
127 copydata(rhs);
128 filter = rhs.filter;
129 fastpass = rhs.fastpass;
130 }
131 return *this;
132 }
133 // DocString: FMTlist::operator==
137 bool operator == (const FMTlist<T>& rhs) const
138 {
139 return (data == rhs.data);
140 }
141 // DocString: ~FMTlist()
145 ~FMTlist() = default;
146 // DocString: FMTlist::empty
150 bool empty() const
151 {
152 return data.empty();
153 }
154 // DocString: FMTlist::canshrink
158 bool canshrink() const
159 {
160 return filter.empty();
161 }
162 // DocString: FMTlist::clearcache
166 virtual void clearcache()
167 {
168 boost::unordered_map<FMTmask, std::vector<int>>().swap(fastpass);
169 }
170 // DocString: FMTlist::size
174 size_t size() const
175 {
176 return data.size();
177 }
178 // DocString: FMTlist::findsets
183 std::vector<const T*> findsets(const FMTmask& mask) const
184 {
185 const FMTmask newkey = filter.filter(mask);
186 return findsetswithfiltered(newkey);
187 }
188 // DocString: FMTlist::findsetswithfiltered
193 std::vector<const T*> findsetswithfiltered(const FMTmask& newkey) const
194 {
195 std::vector<const T*>allhits;
196 boost::unordered_map<FMTmask, std::vector<int>>::const_iterator fast_it = fastpass.find(newkey);
197 if (fast_it != fastpass.end())
198 {
199 allhits.reserve(fast_it->second.size());
200 for (const int& location : fast_it->second)
201 {
202 allhits.push_back(&data.at(location).second);
203 }
204 }
205 else {
206 fastpass[newkey] = std::vector<int>();
207 int location = 0;
208 for (const std::pair<FMTmask, T>& object : data)
209 {
210 if (newkey.issubsetof(object.first))
211 {
212 fastpass[newkey].push_back(location);
213 allhits.push_back(&object.second);
214 }
215 ++location;
216 }
217 fastpass[newkey].shrink_to_fit();
218 }
219 return allhits;
220 }
221 // DocString: FMTlist::filtermask
225 inline FMTmask filtermask(const FMTmask& basemask) const
226 {
227 return filter.filter(basemask);
228 }
229 // DocString: FMTlist::shrink
233 void shrink()
234 {
235 try {
236 fastpass.clear();
237 std::vector<Core::FMTmask> filteredmasks;
238 for (const std::pair<FMTmask, T>& object : data)
239 {
240 filteredmasks.push_back(object.first);
241 }
242 if (filteredmasks.empty())
243 {
244 _exhandler->raise(Exception::FMTexc::FMTinvalid_maskrange, "Empty mask", "FMTactionparser::shrink", __LINE__, __FILE__);
245 }
246 filter = Core::FMTmaskfilter(filteredmasks);
247 for (std::pair<FMTmask, T>& object : data)
248 {
249 object.first = filter.filter(object.first);
250 }
251 data.shrink_to_fit();
252 }
253 catch (...) {
254
255 _exhandler->raisefromcatch("", "FMTlist::shrink", __LINE__, __FILE__);
256
257 }
258 }
259 // DocString: FMTlist::unshrink
263 void unshrink(const std::vector<FMTtheme>& themes)
264 {
265 fastpass.clear();
266 filter = Core::FMTmaskfilter();
267 for (std::pair<FMTmask, T>& object : data)
268 {
269 object.first = FMTmask(std::string(object.first), themes);
270 }
271 }
272 // DocString: FMTlist::APIpush_back
276 void APIpush_back(const FMTmask& mask, const T& value)
277 {
278 push_back(mask, value);
279 }
280 // DocString: FMTlist::push_back
284 void push_back(const FMTmask& mask, const T& value)
285 {
286 data.emplace_back(mask, value);
287 }
288 // DocString: FMTlist::update
292 virtual void update()
293 {
294 if (canshrink())
295 {
296 shrink();
297 }
298 }
299 // DocString: FMTlist::push_back
303 void push_back(const FMTlist<T>& rhs)
304 {
305 if (this->canshrink() && rhs.canshrink())
306 {
307 copydata(rhs);
308 this->shrink();
309 }
310 }
311 // DocString: FMTlist::push_front
315 void push_front(const FMTmask& mask, const T& value)
316 {
317 insert(0, mask, value);
318 }
319 // DocString: FMTlist::pop_back
323 void pop_back()
324 {
325 data.pop_back();
326 }
327 // DocString: FMTlist::erase
331 void erase(const size_t& location)
332 {
333 data.erase(data.begin() + location);
334 }
335 // DocString: FMTlist::insert
339 void insert(const size_t& location, const FMTmask& mask, const T& value)
340 {
341 data.insert(data.begin() + location, std::pair<FMTmask, T>(mask, value));
342 }
343 // DocString: FMTlist::value_type
345 typedef typename std::vector<std::pair<FMTmask, T>>::value_type value_type;
346 // DocString: FMTlist::iterator
348 typedef typename std::vector<std::pair<FMTmask, T>>::iterator iterator;
349 // DocString: FMTlist::const_iterator
351 typedef typename std::vector<std::pair<FMTmask, T>>::const_iterator const_iterator;
352 // DocString: FMTlist::begin
357 {
358 return data.begin();
359 }
360 // DocString: FMTlist::begin
365 {
366 return data.begin();
367 }
368 // DocString: FMTlist::end
373 {
374 return data.end();
375 }
376 // DocString: FMTlist::end
381 {
382 return data.end();
383 }
384 protected:
385 // DocString: FMTlist::compressmasks
391 void compressmasks(std::vector<FMTtheme>& newthemes)
392 {
393 try {
394 if (size()==1)
395 {
396 return;
397 }
398 unshrink(newthemes);
399 size_t thstart = 0;
400 for (FMTtheme& theme : newthemes)
401 {
402 std::vector<std::pair<FMTmask, T>>newvecdata;
403 std::list<std::pair<FMTmask, T>>newdata(data.begin(), data.end());
404 boost::dynamic_bitset<>selectedbits;
405 selectedbits.resize(data.begin()->first.size(), true);
406 for (size_t loc = thstart;loc < (theme.size()+ thstart);++loc)
407 {
408 selectedbits[loc] = false;
409 }
410 while (!newdata.empty())
411 {
412 typename std::list<std::pair<FMTmask, T>>::iterator baseit = newdata.begin();
413 typename std::list<std::pair<FMTmask, T>>::iterator datait = newdata.begin();
414 ++datait;
415 std::vector<typename std::list<std::pair<FMTmask, T>>::iterator>toremove;
416 Core::FMTmask basemask(baseit->first);
417 const boost::dynamic_bitset<> selecinter = selectedbits & baseit->first.getbitsetreference();
418 boost::dynamic_bitset<> reverselect(selecinter);
419 for (size_t loc = thstart; loc < (theme.size() + thstart); ++loc)
420 {
421 reverselect[loc] = true;
422 }
423 /*Core::FMTmask testmask(baseit->first);
424 testmask.set(theme, "?");*/
425 while (datait!=newdata.end())
426 {
427 /*Core::FMTmask datamask(datait->first);
428 datamask.set(theme, "?");*/
429 const boost::dynamic_bitset<>&dataref = datait->first.getbitsetreference();
430 if (dataref.is_subset_of(reverselect))
431 {
432 const boost::dynamic_bitset<> datainter = selectedbits & dataref;
433 if (datainter == selecinter &&
434 baseit->second == datait->second)
435 {
436 basemask = basemask.getunion(datait->first);
437 toremove.push_back(datait);
438 }
439 }
440 ++datait;
441 }
442 std::pair<FMTmask, T>newelement(basemask,baseit->second);
443 newdata.erase(newdata.begin());
444 for (typename std::list<std::pair<FMTmask, T>>::iterator remove : toremove)
445 {
446 newdata.erase(remove);
447 }
448 if(!toremove.empty())//aggregation done set new aggregate and refresh mask
449 {
450 std::string newmask;
451 for (const FMTtheme& subtheme : newthemes)
452 {
453 if (subtheme==theme)
454 {
455 newmask +=theme.updatefrommask(basemask) + " ";
456 }else {
457 newmask += basemask.get(subtheme) + " ";
458 }
459 }
460 newmask.pop_back();
461 newelement.first = Core::FMTmask(newmask, newthemes);
462 }
463 newvecdata.push_back(newelement);
464 }
465 thstart += theme.size();
466 data.swap(newvecdata);
467 }
468 shrink();
469 }catch (...)
470 {
471 _exhandler->raisefromcatch("", "compressmasks", __LINE__, __FILE__);
472 }
473 }
474 // DocString: FMTlist::presolvelist
483 void presolvelist(const FMTmaskfilter& filter,
484 const std::vector<FMTtheme>& originalthemes,
485 const std::vector<FMTtheme>& newthemes)
486 {
487 try {
488 if (!canshrink())
489 {
490 unshrink(originalthemes);
491 }
492 const std::vector<FMTtheme>maskthemes = filter.getselectedthemes(originalthemes);
493 std::vector<std::pair<FMTmask, T>>newdata;
494 for (const std::pair<FMTmask, T>& object : data)
495 {
496 if (filter.canpresolve(object.first,maskthemes))
497 {
498 FMTmask mskkey = object.first;
499 if (!filter.emptyflipped())
500 {
501 mskkey = mskkey.presolve(filter, newthemes);
502 }
503 pushtodata(newdata, mskkey, object.second);
504 }
505 }
506 data.swap(newdata);
508 data.shrink_to_fit();
509 }catch (...)
510 {
511 _exhandler->raisefromcatch("","FMTlist::presolvelist", __LINE__, __FILE__);
512 }
513 }
514 void copydata(const Core::FMTlist<T>& rhs)
515 {
516 data = rhs.data;
517 }
518 private:
519 // DocString: FMTlist::save
524 template<class Archive>
525 void save(Archive& ar, const unsigned int version) const
526 {
527 try {
528 ar& boost::serialization::make_nvp("FMTobject", boost::serialization::base_object<FMTobject>(*this));
529 ar& BOOST_SERIALIZATION_NVP(data);
530 ar& BOOST_SERIALIZATION_NVP(filter);
531 std::vector<std::pair<FMTmask, std::vector<int>>>vecfastpass(fastpass.begin(), fastpass.end());
532 ar& BOOST_SERIALIZATION_NVP(vecfastpass);
533 }
534 catch (...)
535 {
536 _exhandler->printexceptions("", "FMTlist::save", __LINE__, __FILE__);
537 }
538 }
539 // DocString: FMTlist::load
543 template<class Archive>
544 void load(Archive& ar, const unsigned int version)
545 {
546 ar& BOOST_SERIALIZATION_NVP(data);
547 ar& BOOST_SERIALIZATION_NVP(filter);
548 std::vector<std::pair<FMTmask, std::vector<int>>>vecfastpass;
549 ar& BOOST_SERIALIZATION_NVP(vecfastpass);
550 for (const std::pair<FMTmask, std::vector<int>>& values : vecfastpass)
551 {
552 fastpass[values.first] = values.second;
553 }
554 }
555 BOOST_SERIALIZATION_SPLIT_MEMBER()
556 // DocString: FMTlist::data
558 std::vector<std::pair<FMTmask, T>>data;
559 // DocString: FMTlist::filter
561 FMTmaskfilter filter;
562 // DocString: FMTlist::fastpass
564 mutable boost::unordered_map<FMTmask, std::vector<int>>fastpass;
565 // DocString: FMTlist::pushtodata
569 void pushtodata(std::vector<std::pair<FMTmask, T>>& datavector,
570 const FMTmask& mask, const T& maskdata) const
571 {
572 datavector.push_back(std::pair<FMTmask, T>(mask, maskdata));
573 }
574
575 };
576
577 template<> inline void FMTlist<std::unique_ptr<Core::FMTyieldhandler>>::compressmasks(std::vector<FMTtheme>& newthemes)
578 {
579
580 }
581
582
583 template<> inline void FMTlist<std::unique_ptr<Core::FMTyieldhandler>>::insert(const size_t& location, const FMTmask& mask, const std::unique_ptr<Core::FMTyieldhandler>& value)
584 {
585 std::pair<Core::FMTmask, std::unique_ptr<Core::FMTyieldhandler>> newobject = std::make_pair(mask, std::move(value->clone()));
586 data.insert(data.begin() + location, std::move(newobject));
587 }
588
589 template<> inline void FMTlist<std::unique_ptr<Core::FMTyieldhandler>>::pushtodata(std::vector<std::pair<FMTmask, std::unique_ptr<Core::FMTyieldhandler>>>& datavector,
590 const FMTmask& mask, const std::unique_ptr<Core::FMTyieldhandler>& maskdata) const
591 {
592 std::pair<Core::FMTmask, std::unique_ptr<Core::FMTyieldhandler>> newobject = std::make_pair(mask, std::move(maskdata->clone()));
593 datavector.push_back(std::move(newobject));
594 }
595
596 template<> inline void FMTlist<std::unique_ptr<Core::FMTyieldhandler>>::push_back(const FMTmask& mask, const std::unique_ptr<Core::FMTyieldhandler>& value)
597 {
598 pushtodata(data, mask, value);
599 }
600
601 template<> inline void FMTlist<std::unique_ptr<Core::FMTyieldhandler>>::copydata(const FMTlist<std::unique_ptr<Core::FMTyieldhandler>>& rhs)
602 {
603 data.clear();
604 data.reserve(rhs.data.size());
605 for (const std::pair<Core::FMTmask, std::unique_ptr<Core::FMTyieldhandler>>& object : rhs.data)
606 {
607 pushtodata(data, object.first, object.second);
608 }
609 }
610
611
612}
613
614
615#endif
Definition: FMTlist.hpp:46
FMTlist()
Definition: FMTlist.hpp:101
const_iterator begin() const
Definition: FMTlist.hpp:364
~FMTlist()=default
size_t size() const
Definition: FMTlist.hpp:174
std::vector< std::pair< FMTmask, T > >::value_type value_type
Value typedef of the FMTlist.
Definition: FMTlist.hpp:345
Core::FMTlist< T > & operator+=(const Core::FMTlist< T > &OtherList)
append OtherList to this list actions both list had to be non shrinked, will throw exception if shrin...
Definition: FMTlist.hpp:54
void erase(const size_t &location)
Definition: FMTlist.hpp:331
void presolvelist(const FMTmaskfilter &filter, const std::vector< FMTtheme > &originalthemes, const std::vector< FMTtheme > &newthemes)
Definition: FMTlist.hpp:483
void APIpush_back(const FMTmask &mask, const T &value)
Definition: FMTlist.hpp:276
void shrink()
Definition: FMTlist.hpp:233
void push_back(const FMTlist< T > &rhs)
Definition: FMTlist.hpp:303
void pop_back()
Definition: FMTlist.hpp:323
void swap(Core::FMTlist< T > &rhs)
Definition: FMTlist.hpp:77
std::vector< std::pair< FMTmask, T > >::iterator iterator
Iterator typedef of the FMTlist.
Definition: FMTlist.hpp:348
FMTlist(const FMTlist< T > &rhs)
Definition: FMTlist.hpp:110
iterator end()
Definition: FMTlist.hpp:372
void compressmasks(std::vector< FMTtheme > &newthemes)
Definition: FMTlist.hpp:391
void unshrink(const std::vector< FMTtheme > &themes)
Definition: FMTlist.hpp:263
bool operator==(const FMTlist< T > &rhs) const
Definition: FMTlist.hpp:137
FMTmask getunion(const std::vector< FMTtheme > &themes) const
Definition: FMTlist.hpp:87
virtual void update()
Definition: FMTlist.hpp:292
std::vector< std::pair< FMTmask, T > >::const_iterator const_iterator
Const_Iterator typedef of the FMTlist.
Definition: FMTlist.hpp:351
friend class boost::serialization::access
Definition: FMTlist.hpp:523
void insert(const size_t &location, const FMTmask &mask, const T &value)
Definition: FMTlist.hpp:339
bool canshrink() const
Definition: FMTlist.hpp:158
FMTlist & operator=(const FMTlist< T > &rhs)
Definition: FMTlist.hpp:122
FMTmask filtermask(const FMTmask &basemask) const
Definition: FMTlist.hpp:225
std::vector< const T * > findsetswithfiltered(const FMTmask &newkey) const
Definition: FMTlist.hpp:193
virtual void clearcache()
Definition: FMTlist.hpp:166
bool empty() const
Definition: FMTlist.hpp:150
std::vector< const T * > findsets(const FMTmask &mask) const
Definition: FMTlist.hpp:183
void push_front(const FMTmask &mask, const T &value)
Definition: FMTlist.hpp:315
void copydata(const Core::FMTlist< T > &rhs)
Definition: FMTlist.hpp:514
const_iterator end() const
Definition: FMTlist.hpp:380
void push_back(const FMTmask &mask, const T &value)
Definition: FMTlist.hpp:284
iterator begin()
Definition: FMTlist.hpp:356
Definition: FMTmask.hpp:96
std::string get(const std::vector< FMTtheme > &themes) const
FMTmask presolve(const FMTmaskfilter &filter, const std::vector< FMTtheme > &presolvedthemes) const
FMTmask getunion(const FMTmask &rhs) const
bool issubsetof(const boost::dynamic_bitset<> &rhs) const
Definition: FMTmask.hpp:352
Definition: FMTmaskfilter.hpp:27
bool canpresolve(const FMTmask &mask, const std::vector< Core::FMTtheme > &themes) const
bool emptyflipped() const
Definition: FMTmaskfilter.hpp:58
FMTmask filter(const FMTmask &devmask) const
bool empty() const
Definition: FMTmaskfilter.hpp:62
std::vector< Core::FMTtheme > getselectedthemes(const std::vector< Core::FMTtheme > &themes) const
void swap(FMTmaskfilter &rhs)
Definition: FMTobject.hpp:50
FMTobject & operator=(const FMTobject &rhs)
static std::shared_ptr< Exception::FMTexceptionhandler > _exhandler
A shared pointer to the exception handler.
Definition: FMTobject.hpp:66
Definition: FMTtheme.hpp:47
The Core namespace provides classes for simulating stands/strata growth/harvest through time.
Definition: FMTaction.hpp:31
@ FMTinvalid_action
Definition: FMTexception.hpp:51
@ FMTinvalid_maskrange
Definition: FMTexception.hpp:49
Definition: FMTaction.hpp:364