FMT 1.2.0
Forest management tools for forest planning
Loading...
Searching...
No Matches
FMTMask.h
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 FMTMASK_Hm_included
9#define FMTMASK_Hm_included
10
11#ifndef BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS
12#define BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS
13#endif
14
15#include <boost/dynamic_bitset.hpp>
16#include <boost/unordered_map.hpp>
17#include <boost/algorithm/string.hpp>
18#include <boost/algorithm/string/join.hpp>
19#include <boost/functional/hash.hpp>
20#include <boost/serialization/serialization.hpp>
21#include <boost/serialization/split_free.hpp>
22#include <boost/serialization/nvp.hpp>
23#include <boost/serialization/export.hpp>
24#include <boost/serialization/string.hpp>
25#include <boost/functional/hash.hpp>
26#include <boost/serialization/vector.hpp>
27#include <boost/dynamic_bitset/serialization.hpp>
28#include "FMTException.h"
29#include <vector>
30#include <string>
31
32
33
34
35#if (BOOST_VERSION / 100 % 1000) < 71
39namespace boost {
40 namespace serialization {
41
42 template <typename Ar, typename Block, typename Alloc>
43 void save(Ar& ar, dynamic_bitset<Block, Alloc> const& bs, unsigned) {
44 size_t num_bits = bs.size();
45 std::vector<Block> blocks(bs.num_blocks());
46 to_block_range(bs, blocks.begin());
47
48 ar& BOOST_SERIALIZATION_NVP(num_bits);
49 ar& BOOST_SERIALIZATION_NVP(blocks);
50 }
51
52 template <typename Ar, typename Block, typename Alloc>
53 void load(Ar& ar, dynamic_bitset<Block, Alloc>& bs, unsigned) {
54 size_t num_bits;
55 std::vector<Block> blocks;
56 ar& BOOST_SERIALIZATION_NVP(num_bits);
57 ar& BOOST_SERIALIZATION_NVP(blocks);
58
59 bs.resize(num_bits);
60 from_block_range(blocks.begin(), blocks.end(), bs);
61 bs.resize(num_bits);
62 }
63
64 template <typename Ar, typename Block, typename Alloc>
65 void serialize(Ar& ar, dynamic_bitset<Block, Alloc>& bs, unsigned version) {
66 split_free(ar, bs, version);
67 }
68
69 }
70}
74namespace boost {
75 template <typename Block, typename Alloc>
76 std::size_t hash_value(const boost::dynamic_bitset<Block, Alloc>& bs)
77 {
78 std::size_t hash = hash_value(bs.m_num_bits);
79 boost::hash_combine(hash, bs.m_bits);
80 return hash;
81 }
82}
83#endif
84
85namespace Core
86{
87
88class FMTTheme;
89class FMTMaskFilter;
90// DocString: FMTMask
96 {
97
98 public:
99 // DocString: FMTMask::(FMTMask&& rhs)
104 FMTMask(FMTMask&& rhs) noexcept;
105 // DocString: FMTMask::operator=(FMTMask&& rhs)
111 FMTMask& operator=(FMTMask&& rhs) noexcept;
112 // DocString: swap()
117 void swap(FMTMask& rhs);
118 // DocString: FMTMask()
123 // DocString: FMTMask(const FMTMask&)
128 FMTMask(const FMTMask& rhs);
129 // DocString: ~FMTMask()
133 virtual ~FMTMask()=default;
134 // DocString: FMTMask(const boost::dynamic_bitset<uint8_t>&)
139 FMTMask(const boost::dynamic_bitset<uint8_t>& bits);
140 // DocString: FMTMask::operator bool
145 explicit operator bool() const;
146 // DocString: FMTMask(const std::string&,const boost::dynamic_bitset<uint8_t>&)
152 FMTMask(const std::string& mask,const boost::dynamic_bitset<uint8_t>& bits);
153 // DocString: FMTMask(const std::string&,const std::vector<FMTTheme>&)
159 FMTMask(const std::string& mask,const std::vector<FMTTheme>& themes);
160 // DocString: FMTMask(const std::vector<std::string>&,const std::vector<FMTTheme>&)
166 FMTMask(const std::vector<std::string>& values,const std::vector<FMTTheme>& themes);
167 // DocString: FMTMask(const std::vector<FMTTheme>&,const std::vector<FMTTheme>&)
172 FMTMask(const std::vector<FMTTheme>& themes);
173 // DocString: FMTMask::clear
177 void clear();
178 // DocString: FMTMask::size
183 size_t size() const;
184 // DocString: FMTMask::count
189 size_t count() const;
190 // DocString: FMTMask::get
196 std::string get(const std::vector<FMTTheme>& themes) const;
197 // DocString: FMTMask::get
203 std::string get(const FMTTheme& theme) const;
204 // DocString: FMTMask::getAttribute
210 const std::string& getAttribute(const FMTTheme& p_theme) const;
211 // DocString: FMTMask::getSubsetCount
217 size_t getSubsetCount(const FMTTheme& theme) const;
218 // DocString: FMTMask::set
224 void set(const std::vector<FMTTheme>& themes,const std::string& value);
225 // DocString: FMTMask::setExclusiveBits
231 void setExclusiveBits(const FMTMask& p_mask,const FMTTheme& p_theme);
232 // DocString: FMTMask::getNonFullBlocks
237 std::vector<size_t>getNonFullBlocks() const;
238 // DocString: FMTMask::isSubsetOf
245 bool isSubsetOf(const FMTMask& p_mask,const std::vector<size_t>& p_subset) const;
246 // DocString: FMTMask::set
252 void set(const FMTTheme& theme, const std::string& value);
253 // DocString: FMTMask::getStaticThemes
259 std::vector<const Core::FMTTheme*>getStaticThemes(const std::vector<const Core::FMTTheme*>& themes) const;
260 // DocString: FMTMask::getSelectedThemes
266 std::vector<const Core::FMTTheme*> getSelectedThemes(const std::vector<Core::FMTTheme>& themes) const;
267 // DocString: FMTMask::isNotThemesSubset
274 bool isNotThemesSubset(const FMTMask& rhs, const std::vector<const Core::FMTTheme*>& themes) const;
275 // DocString: FMTMask::isNotThemesSubset
282 bool isNotThemesSubset(const FMTMask& rhs, const std::vector<Core::FMTTheme>& themes) const;
283 // DocString: FMTMask::removeAggregates
290 FMTMask removeAggregates(const std::vector<FMTTheme>& themes,bool questionmarkonly=false) const;
291 // DocString: FMTMask::empty
296 bool empty() const;
297 // DocString: FMTMask::update
302 void update(const std::vector<FMTTheme>& themes);
303 // DocString: FMTMask::decompose
309 std::vector<FMTMask>decompose(const FMTTheme &theme) const;
310 // DocString: FMTMask::append
315 void append(const boost::dynamic_bitset<uint8_t> &bits);
316
317 // DocString: FMTMask::binarizedAppend
323 template <class typetobinarize>
324 void binarizedAppend(const typetobinarize& element)
325 {
326 size_t location = m_data.size();
327 m_data.resize(m_data.size() + (sizeof(typetobinarize) * 8));
328 const char* charelements = reinterpret_cast<const char*>(&element);
329 for (size_t charit = 0; charit < sizeof(typetobinarize); ++charit)
330 {
331 const char value = charelements[charit];
332 for (int i = 7; i >= 0; --i)
333 {
334 m_data[location] = ((value & (1 << i)));
335 ++location;
336 }
337 }
338 }
339 // DocString: FMTMask::unionWith
344 void unionWith(const FMTMask& rhs);
345 // DocString: FMTMask::getUnion
351 FMTMask getUnion(const FMTMask& rhs) const;
352 // DocString: FMTMask::getIntersect
358 FMTMask getIntersect(const FMTMask& rhs) const;
359 // DocString: FMTMask::setIntersect
364 void setIntersect(const FMTMask& rhs);
365 // DocString: FMTMask::getBitsetIntersect
371 boost::dynamic_bitset<uint8_t> getBitsetIntersect(const FMTMask& rhs) const;
372 // DocString: FMTMask::operator=
378 FMTMask& operator = (const FMTMask& rhs);
379 // DocString: FMTMask::operator!=
385 bool operator != (const FMTMask& rhs) const;
386 // DocString: FMTMask::operator==
392 bool operator == (const FMTMask& rhs) const;
393 // DocString: FMTMask::operator<
399 bool operator < (const FMTMask& rhs) const;
400 // DocString: FMTMask::resume
406 FMTMask resume(const boost::dynamic_bitset<uint8_t>& rhs) const;
407 // DocString: FMTMask::resume
413 FMTMask resume(const std::vector<size_t>& indexes) const;
414 // DocString: FMTMask::hash
419 inline size_t hash() const
420 {
421 return boost::hash<boost::dynamic_bitset<uint8_t>>()(m_data);
422 }
423 // DocString: FMTMask::getBitsString
428 std::string getBitsString() const;
429 // DocString: FMTMask::operator std::string
434 inline operator std::string() const
435 {
436 return m_name;
437 }
438 // DocString: FMTMask::isSubsetOf
444 bool isSubsetOf(const FMTMask& p_rhs) const;
445 // DocString: FMTMask::getBitsetReference
450 inline const boost::dynamic_bitset<uint8_t>& getBitsetReference() const
451 {
452 return m_data;
453 }
454 // DocString: FMTMask::getStringReference
459 inline const std::string& getStringReference() const
460 {
461 return m_name;
462 }
463 // DocString: FMTMask::reserve
468 void reserve(size_t p_size);
469 // DocString: FMTMask::refine
476 FMTMask refine(const FMTMask& mask, const std::vector<FMTTheme>& themes) const;
477 // DocString: FMTMask::getPostSolveMask
484 FMTMask getPostSolveMask(const FMTMask& mask,const std::vector<FMTTheme>& themes) const;
485 // DocString: FMTMask::preSolve
492 FMTMask preSolve(const FMTMaskFilter& filter,const std::vector<FMTTheme>&presolvedthemes) const;
493 // DocString: FMTMask::preSolveRef
500 void preSolveRef(const FMTMaskFilter& p_filter, const std::vector<FMTTheme>& p_presolvedThemes,bool p_allowReallocation = true);
501
502 // DocString: FMTMask::canPreSolve
509 bool canPreSolve(const FMTMaskFilter& p_filter, const std::vector<FMTTheme>& p_presolvedThemes) const;
510 // DocString: FMTMask::postSolve
517 FMTMask postSolve(const FMTMaskFilter& filter, const std::vector<FMTTheme>&basethemes) const;
518 private:
519 friend class FMTTheme;
520 // DocString: FMTMask::serialize
527 friend class boost::serialization::access;
528 template<class Archive>
529 void serialize(Archive& ar, const unsigned int version)
530 {
531 ar& boost::serialization::make_nvp("data", m_data);
532 ar& boost::serialization::make_nvp("name", m_name);
533 }
534 // DocString: FMTMask::_subset
540 boost::dynamic_bitset<uint8_t> _subset(const FMTTheme& theme) const;
541 // DocString: FMTMask::operator []
547 bool operator [](int i) const;
548 // DocString: FMTMask::_anyIntersect
555 bool _anyIntersect(const FMTMask& p_MASK, const FMTTheme& p_THEME) const;
556 // DocString: FMTMask::_countTheme
562 size_t _countTheme(const FMTTheme& p_Theme) const;
563 // DocString: FMTMask::_getPresolveMas
570 boost::dynamic_bitset<uint8_t> _getPreSolveMask(const FMTMaskFilter& p_filter,
571 const std::vector<FMTTheme>& p_presolvedThemes) const;
572 // DocString: FMTMask::_setSubset
578 void _setSubset(const FMTTheme& theme, const boost::dynamic_bitset<uint8_t>& subset);
579 // DocString: FMTMask::m_name
581 std::string m_name;
582 // DocString: FMTMask::m_data
584 boost::dynamic_bitset<uint8_t> m_data;
585 };
586
587
588template<> inline void FMTMask::binarizedAppend<std::string>(const std::string& element)
589 {
590 size_t location = m_data.size();
591 m_data.resize(m_data.size() + (element.size() * 8));
592 const char* charelements = element.c_str();
593 for (size_t charit = 0; charit < element.size(); ++charit)
594 {
595 const char value = charelements[charit];
596 for (int i = 7; i >= 0; --i)
597 {
598 m_data[location] = ((value & (1 << i)));
599 ++location;
600 }
601 }
602 }
603
604template<> inline void FMTMask::binarizedAppend<double>(const double& element)
605{
606 size_t location = m_data.size();
607 const int corrected = static_cast<int>(element*(1 / FMT_DBL_TOLERANCE));
608 m_data.resize(m_data.size() + (sizeof(int) * 8));
609 const char* charelements = reinterpret_cast<const char*>(&corrected);
610 for (size_t charit = 0; charit < sizeof(int); ++charit)
611 {
612 const char value = charelements[charit];
613 for (int i = 7; i >= 0; --i)
614 {
615 m_data[location] = ((value & (1 << i)));
616 ++location;
617 }
618 }
619}
620
621// DocString: FMTMaskComparator
626 {
627 public:
628 // DocString: FMTMaskComparator:(const FMTMask&)
633 FMTMaskComparator(const FMTMask& lbase_mask);
634 // DocString: FMTMaskComparator::operator()(const FMTAction&)
640 bool operator()(const FMTMask& mask) const;
641
642 private:
643 // DocString: FMTMaskComparator::m_baseMask
645 FMTMask m_baseMask;
646 };
647
648}
649
650namespace boost {
654 template <>
655 struct hash<Core::FMTMask>
656 {
657 std::size_t operator()(const Core::FMTMask& mask) const
658 {
659 return (mask.hash());
660 }
661 };
662
663}
664
665BOOST_CLASS_EXPORT_KEY(Core::FMTMask)
666
667#endif // FMTMASK_Hm_included
#define FMT_DBL_TOLERANCE
Definition: FMTutility.h:11
#define FMTEXPORT
Definition: FMTutility.h:125
Comparator used to check if a mask already exists in a std container.
Definition: FMTMask.h:626
FMTMaskComparator(const FMTMask &lbase_mask)
Construct the comparator from the mask to match.
bool operator()(const FMTMask &mask) const
Matching test operator for the comparator.
Filter built from masks used to preSolve and postsolve FMTMask objects.
Definition: FMTMaskFilter.h:31
Core class holding, as a boost dynamic bitset, which theme attributes are part of a mask.
Definition: FMTMask.h:96
size_t count() const
Return the number of bits set.
bool isNotThemesSubset(const FMTMask &rhs, const std::vector< Core::FMTTheme > &themes) const
Return true if this mask is not part of rhs based on the sorted themes.
FMTMask preSolve(const FMTMaskFilter &filter, const std::vector< FMTTheme > &presolvedthemes) const
Return a presolved mask with potentially less data using a filter and a subset of the original themes...
FMTMask resume(const boost::dynamic_bitset< uint8_t > &rhs) const
Return a mask with the selected name and data using a bitset.
void setExclusiveBits(const FMTMask &p_mask, const FMTTheme &p_theme)
Flip only the theme subset and clear the mask of the intersection with another mask.
void unionWith(const FMTMask &rhs)
Performs an in-place union with another mask.
std::vector< const Core::FMTTheme * > getSelectedThemes(const std::vector< Core::FMTTheme > &themes) const
Return the themes that have any bit set in the mask.
std::string getBitsString() const
Return the binary representation of the bitset as a string.
FMTMask(FMTMask &&rhs) noexcept
Move copy constructor.
std::string get(const FMTTheme &theme) const
Get the attribute of the mask for a given theme.
FMTMask getPostSolveMask(const FMTMask &mask, const std::vector< FMTTheme > &themes) const
Turn off the bits of themes that are still active on a base postsolve mask.
std::string get(const std::vector< FMTTheme > &themes) const
Get the string mask name based on the bitset data and sorted themes.
FMTMask removeAggregates(const std::vector< FMTTheme > &themes, bool questionmarkonly=false) const
Return a new mask with the bits of aggregates or question marks unset for the given themes.
void setIntersect(const FMTMask &rhs)
set the intersect with this mask using rhs mask.
boost::dynamic_bitset< uint8_t > getBitsetIntersect(const FMTMask &rhs) const
Return the bitset of the intersection of this mask and another mask.
bool empty() const
Return true if the data member is empty.
void swap(FMTMask &rhs)
Swap this mask with another.
void preSolveRef(const FMTMaskFilter &p_filter, const std::vector< FMTTheme > &p_presolvedThemes, bool p_allowReallocation=true)
Presolve this mask in place with potentially less data using a filter and a subset of the original th...
FMTMask postSolve(const FMTMaskFilter &filter, const std::vector< FMTTheme > &basethemes) const
Return a postsolved mask using a filter and the original themes.
FMTMask(const std::string &mask, const boost::dynamic_bitset< uint8_t > &bits)
Construct a mask from an already set bitset and a string mask used as name.
bool isSubsetOf(const FMTMask &p_mask, const std::vector< size_t > &p_subset) const
Check if this mask is a subset of another mask by looking at a block subset.
FMTMask resume(const std::vector< size_t > &indexes) const
Return a mask with the selected name and data using mask indexes.
virtual ~FMTMask()=default
Default virtual destructor for FMTMask.
void append(const boost::dynamic_bitset< uint8_t > &bits)
Append a bitset to the bitset data member of the mask.
void set(const std::vector< FMTTheme > &themes, const std::string &value)
Set the bitset data for some themes from a mask string.
FMTMask getIntersect(const FMTMask &rhs) const
Return the intersection of this mask and another mask.
std::vector< size_t > getNonFullBlocks() const
Return the indexes of the blocks that contain a 0.
void update(const std::vector< FMTTheme > &themes)
Update the name member from the bitset data using a sorted list of themes.
void clear()
Clear the data and name members.
const std::string & getStringReference() const
Return a const reference to the name string member.
Definition: FMTMask.h:459
void set(const FMTTheme &theme, const std::string &value)
Set the bitset data for a given theme from an attribute.
size_t getSubsetCount(const FMTTheme &theme) const
Return the number of bits set for the given theme subset.
FMTMask getUnion(const FMTMask &rhs) const
Return the union of this mask and another mask.
FMTMask & operator=(FMTMask &&rhs) noexcept
Move assignment operator for FMTMask.
bool isNotThemesSubset(const FMTMask &rhs, const std::vector< const Core::FMTTheme * > &themes) const
Return true if this mask is not part of rhs based on the sorted themes.
FMTMask(const std::string &mask, const std::vector< FMTTheme > &themes)
Construct a complete mask from a string and sorted themes.
void binarizedAppend(const typetobinarize &element)
Binarize an element and append it to the mask.
Definition: FMTMask.h:324
FMTMask(const FMTMask &rhs)
Copy constructor for FMTMask.
bool canPreSolve(const FMTMaskFilter &p_filter, const std::vector< FMTTheme > &p_presolvedThemes) const
Return true if the mask can be presolved with the given filter and themes.
const std::string & getAttribute(const FMTTheme &p_theme) const
When you deal with FMTDevelopment you can directly call this to get a reference to the attribute stri...
bool isSubsetOf(const FMTMask &p_rhs) const
Check if this mask is a subset of another mask.
size_t size() const
Return the size of the bitset data member.
FMTMask refine(const FMTMask &mask, const std::vector< FMTTheme > &themes) const
Return a new mask where the question marks are completed with the attributes of another mask.
FMTMask()
Default constructor for FMTMask.
FMTMask(const std::vector< FMTTheme > &themes)
Construct an empty mask sized for the given themes.
FMTMask(const boost::dynamic_bitset< uint8_t > &bits)
Construct a mask setting only the bitset data member.
FMTMask(const std::vector< std::string > &values, const std::vector< FMTTheme > &themes)
Construct a mask from a vector of attribute strings and sorted themes.
std::vector< const Core::FMTTheme * > getStaticThemes(const std::vector< const Core::FMTTheme * > &themes) const
Return the themes that only use aggregates or a question mark for the mask.
std::vector< FMTMask > decompose(const FMTTheme &theme) const
Disaggregate the attribute of a theme from the mask into a vector of masks, one per possible attribut...
const boost::dynamic_bitset< uint8_t > & getBitsetReference() const
Return a const reference to the bitset data member.
Definition: FMTMask.h:450
void reserve(size_t p_size)
reserve memory for the boost dynamicbitset.
size_t hash() const
Return the hash of the mask.
Definition: FMTMask.h:419
Class holding the attributes and aggregates of a single theme, describing a part of a FMTMask.
Definition: FMTTheme.h:47
The Core namespace provides classes for simulating stands/strata growth/harvest through time.
Definition: FMTAction.h:34
void load(Ar &ar, dynamic_bitset< Block, Alloc > &bs, unsigned)
Definition: FMTMask.h:53
void serialize(Ar &ar, dynamic_bitset< Block, Alloc > &bs, unsigned version)
Definition: FMTMask.h:65
void save(Ar &ar, dynamic_bitset< Block, Alloc > const &bs, unsigned)
Definition: FMTMask.h:43
Definition: FMTAction.h:463
std::size_t hash_value(const boost::dynamic_bitset< Block, Alloc > &bs)
Definition: FMTMask.h:76
std::size_t operator()(const Core::FMTMask &mask) const
Definition: FMTMask.h:657