8#include <framework/datastore/SelectSubset.h>
9#include <framework/datastore/StoreArray.h>
10#include <framework/datastore/RelationsObject.h>
11#include <framework/datastore/RelationArray.h>
14#include <gtest/gtest.h>
21#include <unordered_map>
30 class SelectSubsetTest :
public ::testing::Test {
34 using KeyElementType = UInt_t;
38 static bool SelectionCriterium(
const KeyElementType a)
42 return (a % 2) != 0 && (a % 3) != 0 && (a % 5) != 0 && (a % 7) != 0 &&
43 (a % 11) != 0 && (a % 13) != 0 && (a % 17) != 0 && (a % 19) != 0 && (a % 23) != 0 &&
44 (a % 29) != 0 && (a % 31) != 0 ;
47 static bool SelectionCriteriumOnElement(
const StoredElement* a)
49 return SelectionCriterium(a->GetUniqueID());
55 using FromTargetElementsToWeight = map< KeyElementType, double >;
68 using FromStringToArrows = unordered_map< string, FromTargetElementsToWeight >;
71 KeyElementType m_fromElement;
72 FromStringToArrows m_allRelations;
77 explicit Relations(
const KeyElementType& from):
82 const FromStringToArrows&
83 getConstSetOfAllRelations()
const
85 return m_allRelations;
88 FromStringToArrows::const_iterator
89 getConstSetOfToRelations(
const string& toSetName)
const
91 return m_allRelations.find(toSetName) ;
95 FromStringToArrows::iterator
96 getSetOfToRelations(
const string& toSetName)
98 return m_allRelations.find(toSetName) ;
101 FromStringToArrows::const_iterator
102 getSetOfToRelations(
const string& toSetName)
const
104 return m_allRelations.find(toSetName) ;
111 cout <<
"From KeyElement " << m_fromElement <<
"to:" << endl;
112 for (
const auto& toSet : m_allRelations) {
113 for (
auto pair : toSet.second)
115 << toSet.first <<
" "
117 <<
" ( " << pair.second <<
" ) " << endl;
119 cout <<
"-----------------------------------------------------------------" << endl;
124 isPresentRelationTo(
const string& toSetName, KeyElementType to)
const
126 auto toRelations = getConstSetOfToRelations(toSetName);
127 if (toRelations == m_allRelations.end())
129 return toRelations->second.find(to) != toRelations->second.end();
133 appendNewRelationTo(
const string& toName, KeyElementType to,
136 auto toRelations = getSetOfToRelations(toName);
137 if (toRelations == m_allRelations.end()) {
139 m_allRelations.insert(pair <string, FromTargetElementsToWeight>
141 FromTargetElementsToWeight({ {to, weight} })));
144 pair< KeyElementType, double > relation(to, weight);
145 toRelations->second.insert(relation);
149 const FromTargetElementsToWeight&
150 getAllRelations(
const string& toOtherSetName)
const
152 static FromTargetElementsToWeight nothing;
153 auto toRelations = getSetOfToRelations(toOtherSetName);
154 if (toRelations == m_allRelations.end()) {
157 return toRelations->second;
173 map< KeyElementType, Relations > m_set;
184 cout <<
"The NamedSet: " << m_name <<
" contains:" << endl ;
185 for (
auto set : m_set) {
186 cout << set.first << endl;
189 cout <<
"~~~~~~~~~~~~~~~~~~~~~~~" << endl;
193 explicit NamedSet(
const string& name =
"") :
194 m_name(name), m_storeArray(name) {}
197 bool operator()(
const NamedSet& a,
const NamedSet& b)
const
199 return a.getName() < b.getName();
203 [[nodiscard]]
const string getName()
const
214 void initializeDatastore()
221 array.registerInDataStore();
222 array.registerRelationTo(array);
227 void initializeDatastore(
const string& SetName)
237 array.registerInDataStore();
238 array.registerRelationTo(otherSet);
239 otherSet.registerRelationTo(array);
258 void appendNewElement(KeyElementType element)
260 m_set.insert(pair< KeyElementType, Relations > (element, Relations(element)));
263 void appendNewRelationTo(KeyElementType fromKey,
const string& toName, KeyElementType toKey,
266 auto fromElement = m_set.find(fromKey);
267 if (fromElement == m_set.end()) {
268 cout <<
"??" << endl;
271 fromElement->second.appendNewRelationTo(toName, toKey, weight);
274 [[nodiscard]]
bool isPresentRelationFromTo(
const KeyElementType& fromKey,
const string& otherSetName,
275 const KeyElementType& toKey)
const
277 auto fromElement = m_set.find(fromKey);
278 if (fromElement != m_set.end()) {
279 return fromElement->second.isPresentRelationTo(otherSetName, toKey);
281 cout <<
"Error: from: " << getName() <<
" id " << fromKey <<
282 " -> " << otherSetName <<
" id " << toKey << endl;
283 for (
const auto& element : m_set)
284 cout << element.first <<
"\t";
286 for (
const auto& element : m_storeArray)
287 cout << element.GetUniqueID() <<
"\t";
293 [[nodiscard]]
const FromTargetElementsToWeight& getAllRelations(
const KeyElementType& fromKey,
const string& toOtherSetName)
const
295 auto fromElement = m_set.find(fromKey);
296 return fromElement->second.getAllRelations(toOtherSetName);
299 using StlRelationArray = map< KeyElementType, FromTargetElementsToWeight >;
301 [[nodiscard]] StlRelationArray getRestrictedDomainRelationTo(
const string& toOtherSetName)
const
303 StlRelationArray theInducedRelation;
304 for (
const auto& element : m_set) {
305 if (SelectionCriterium(element.first) &&
306 element.second.getAllRelations(toOtherSetName).size() != 0)
307 theInducedRelation.insert(pair< KeyElementType, FromTargetElementsToWeight>
308 (element.first, element.second.getAllRelations(toOtherSetName)));
310 return theInducedRelation;
313 [[nodiscard]] StlRelationArray getRestrictedCodomainRelationTo(
const string& setName)
const
315 StlRelationArray theInducedRelation;
316 for (
const auto& element : m_set) {
317 if (element.second.getConstSetOfToRelations(setName) ==
318 element.second.getConstSetOfAllRelations().end())
320 for (
auto image : element.second.getConstSetOfToRelations(setName)->second) {
321 if (SelectionCriterium(image.first)) {
322 if (theInducedRelation.find(element.first) == theInducedRelation.end())
323 theInducedRelation.insert(pair< KeyElementType, FromTargetElementsToWeight>
324 (element.first, FromTargetElementsToWeight()));
325 theInducedRelation.find(element.first)->second.
326 insert(FromTargetElementsToWeight::value_type
327 (image.first, image.second));
331 return theInducedRelation;
334 [[nodiscard]] StlRelationArray getRestrictedSelfRelation()
const
336 StlRelationArray theInducedRelation;
337 for (
const auto& element : m_set) {
338 if (! SelectionCriterium(element.first) ||
339 element.second.getAllRelations(m_name).size() == 0)
341 for (
auto image : element.second.getConstSetOfToRelations(m_name)->second) {
342 if (SelectionCriterium(image.first)) {
343 if (theInducedRelation.find(element.first) == theInducedRelation.end())
344 theInducedRelation.insert(pair< KeyElementType, FromTargetElementsToWeight>
345 (element.first, FromTargetElementsToWeight()));
346 theInducedRelation.find(element.first)->second.
347 insert(FromTargetElementsToWeight::value_type
348 (image.first, image.second));
352 return theInducedRelation;
357 class CollectionOfSets {
367 vector< string > m_otherSetsNames;
368 unordered_map< string, NamedSet > m_otherSets;
372 CollectionOfSets(): m_set(
"theSet"),
373 m_subset(
"theSubset"),
374 m_otherSetsNames {string(
"G"), string(
"F"), string(
"E"),
375 string(
"D"), string(
"C"), string(
"B"), string(
"A")
378 m_setName = m_set.getName();
379 m_subsetName = m_subset.getName();
380 for (
const auto& aSetName : m_otherSetsNames)
381 m_otherSets.insert(pair<string, NamedSet> (aSetName, NamedSet(aSetName)));
394 return m_set.storedArray();
405 getSubsetName()
const
407 return m_subsetName ;
413 return m_subset.storedArray();
419 return m_otherSets.size() ;
422 const vector< string >&
423 getOtherSetsNames()
const
425 return m_otherSetsNames ;
429 getOtherSetsNames(
int i)
const
431 return m_otherSetsNames[i] ;
437 auto otherSet = m_otherSets.find(m_otherSetsNames[ i ]);
438 if (otherSet != m_otherSets.end())
439 return otherSet->second.storedArray();
441 cout <<
" ???????????? " << i << endl;
442 throw std::runtime_error(
"invalid set access");
445 pair< const string, NamedSet>&
446 getOtherNamedSet(
int i)
448 return * m_otherSets.find(m_otherSetsNames[ i ]);
451 unordered_map< string, NamedSet >&
458 initializeDatastore()
462 m_set.initializeDatastore();
464 for (
auto namedSet : m_otherSets)
465 namedSet.second.initializeDatastore(getSetName());
472 unsigned int nElements = 1368;
473 for (
unsigned int i = 0; i < nElements ; i++)
474 appendNewElement(m_set);
478 for (
auto& set : m_otherSets) {
479 unsigned int nOtherElements = nElements - n * 100;
481 for (
unsigned int i = 0; i < nOtherElements ; i++)
482 appendNewElement(set.second);
487 for (
auto& set : m_otherSets) {
490 unsigned int nArrows = nElements * j;
493 for (
unsigned int arrow = 0; arrow < nArrows ; arrow ++) {
494 appendNewRelationToOther(set);
495 appendNewRelationFromOther(set);
501 for (
unsigned int arrow = 0; arrow < 5 * nElements; arrow ++)
502 appendNewSelfRelation();
514 static double counter(0.0);
515 return counter += 1.;
519 flat_random(
unsigned int max)
525 static unsigned int next = 11036;
530 result = (
unsigned int)(next / 65536) % 2048;
535 result ^= (
unsigned int)(next / 65536) % 1024;
540 result ^= (
unsigned int)(next / 65536) % 1024;
547 appendNewElement(NamedSet& namedSet)
551 static int uniqueId(0);
553 namedSet.appendNewElement(uniqueId);
555 set[ i ]->SetUniqueID(uniqueId);
561 appendNewRelationToOther(pair< const string, NamedSet>& set)
564 int from_index = flat_random(getSet().getEntries());
565 KeyElementType from_key = getSet()[from_index]->GetUniqueID();
566 int to_index = flat_random(set.second.storedArray().getEntries());
567 KeyElementType to_key = set.second.storedArray()[to_index]->GetUniqueID();
570 if (getNamedSet().isPresentRelationFromTo(from_key, set.first, to_key))
574 double weight = getWeight();
576 getNamedSet().appendNewRelationTo(from_key, set.first, to_key, weight);
578 RelationArray setToOtherSet(getSet(), set.second.storedArray());
579 setToOtherSet.add(from_index, to_index, weight);
585 appendNewRelationFromOther(pair< const string, NamedSet>& otherSet)
589 unsigned int from_index = flat_random(otherSet.second.storedArray().getEntries());
591 KeyElementType from_key = otherSet.second.storedArray()[from_index]->GetUniqueID();
593 unsigned int to_index = flat_random(getSet().getEntries());
594 KeyElementType to_key = getSet()[to_index]->GetUniqueID();
596 if (otherSet.second.isPresentRelationFromTo(from_key, getSetName(), to_key))
600 double weight = getWeight();
602 otherSet.second.appendNewRelationTo(from_key, getSetName(), to_key, weight);
606 RelationArray otherSetToSet(otherSet.second.storedArray(), getSet());
607 otherSetToSet.add(from_index, to_index, weight);
612 appendNewSelfRelation()
614 unsigned int from_index = flat_random(getSet().getEntries());
615 KeyElementType from_key = getSet()[from_index]->GetUniqueID();
616 unsigned int to_index = flat_random(getSet().getEntries());
617 KeyElementType to_key = getSet()[to_index]->GetUniqueID();
620 if (getNamedSet().isPresentRelationFromTo(from_key, getSetName(), to_key))
623 double weight = getWeight();
625 getNamedSet().appendNewRelationTo(from_key, getSetName(), to_key, weight);
629 setToSet.add(from_index, to_index, weight);
640 CollectionOfSets m_TestBench;
642 void SetUp()
override
647 void TearDown()
override
654 testRelationToOther(pair< const string, NamedSet>& otherSet)
660 otherSet.second.storedArray());
663 NamedSet::StlRelationArray theInducedRelation;
665 for (
int relation = 0 ; relation < subsetToOtherSet.getEntries() ; relation++) {
666 size_t relationSize = subsetToOtherSet[ relation ].getSize();
669 KeyElementType fromElementKey = subset[from]->GetUniqueID();
670 if (theInducedRelation.find(fromElementKey) == theInducedRelation.end())
671 theInducedRelation.insert(pair< KeyElementType, FromTargetElementsToWeight>
672 (fromElementKey, FromTargetElementsToWeight()));
674 for (
unsigned int to_index = 0 ; to_index < relationSize ; to_index++) {
676 double weight = subsetToOtherSet[ relation ].getWeight(to_index);
677 KeyElementType toElementKey = otherSet.second.storedArray()[to]->GetUniqueID();
679 theInducedRelation.find(fromElementKey)->second.insert(pair< KeyElementType, double> (toElementKey, weight));
685 NamedSet::StlRelationArray theExpectedRelation = m_TestBench.getNamedSet().
686 getRestrictedDomainRelationTo(otherSet.first) ;
688 bool OKorKO = equal(theExpectedRelation.begin(), theExpectedRelation.end(), theInducedRelation.begin(),
689 [](
const NamedSet::StlRelationArray::value_type & a,
690 const NamedSet::StlRelationArray::value_type & b) {
692 cout << a.first <<
" vs " << b.first << endl;
694 return a.first == b.first &&
695 equal(a.second.begin(), a.second.end(), b.second.begin(),
696 [](const FromTargetElementsToWeight::value_type & x,
697 const FromTargetElementsToWeight::value_type & y) {
700 << x.first <<
"," << x.second
702 << y.first <<
"," << y.second <<
"\t";
703 cout << (x.first == y.first) <<
" , " << (x.second == y.second) << endl;
705 return x.first == y.first && x.second == y.second;
711 for (
auto relation : theExpectedRelation)
712 for (
auto to : relation.second)
713 cout << relation.first <<
" -> " << to.first <<
" ( " << to.second <<
" )" << endl;
715 for (
auto relation : theInducedRelation)
716 for (
auto to : relation.second)
717 cout << relation.first <<
" --> " << to.first <<
" ( " << to.second <<
" )" << endl;
725 testRelationFromOther(pair< const string, NamedSet>& otherNamedSet)
732 RelationArray subsetFromOtherSet(otherNamedSet.second.storedArray(), subset);
735 NamedSet::StlRelationArray theInducedRelation;
737 for (
int relation = 0 ; relation < subsetFromOtherSet.getEntries() ; relation++) {
738 size_t relationSize = subsetFromOtherSet[ relation ].getSize();
740 KeyElementType fromElementKey = other[from]->GetUniqueID();
741 if (theInducedRelation.find(fromElementKey) == theInducedRelation.end()) {
742 theInducedRelation.insert(pair< KeyElementType, FromTargetElementsToWeight>
743 (fromElementKey, FromTargetElementsToWeight()));
746 for (
unsigned int to_index = 0 ; to_index < relationSize ; to_index++) {
748 subsetFromOtherSet[ relation ].getToIndex(to_index);
749 double weight = subsetFromOtherSet[ relation ].getWeight(to_index);
750 KeyElementType toElementKey = subset[to]->GetUniqueID();
752 theInducedRelation.find(fromElementKey)->second.insert(pair< KeyElementType, double> (toElementKey, weight));
758 NamedSet::StlRelationArray theExpectedRelation
759 = otherNamedSet.second.getRestrictedCodomainRelationTo(m_TestBench.getSetName());
760 bool OKorKO = equal(theExpectedRelation.begin(), theExpectedRelation.end(), theInducedRelation.begin(),
761 [](
const NamedSet::StlRelationArray::value_type & a,
762 const NamedSet::StlRelationArray::value_type & b) {
764 cout << a.first <<
" vs " << b.first << endl;
766 return a.first == b.first &&
767 equal(a.second.begin(), a.second.end(), b.second.begin(),
768 [](const FromTargetElementsToWeight::value_type & x,
769 const FromTargetElementsToWeight::value_type & y) {
772 << x.first <<
"," << x.second
774 << y.first <<
"," << y.second <<
"\t";
775 cout << (x.first == y.first) <<
" , " << (x.second == y.second) << endl;
777 return x.first == y.first && x.second == y.second;
783 for (
auto relation : theExpectedRelation)
784 for (
auto to : relation.second)
785 cout << relation.first <<
" -> " << to.first <<
" ( " << to.second <<
" )" << endl;
787 for (
auto relation : theInducedRelation)
788 for (
auto to : relation.second)
789 cout << relation.first <<
" --> " << to.first <<
" ( " << to.second <<
" )" << endl;
805 NamedSet::StlRelationArray theInducedRelation;
807 for (
int relation = 0 ; relation < selfRelation.getEntries() ; relation++) {
808 size_t relationSize = selfRelation[ relation ].getSize();
810 KeyElementType fromElementKey = subset[from]->GetUniqueID();
811 if (theInducedRelation.find(fromElementKey) == theInducedRelation.end()) {
812 theInducedRelation.insert(pair< KeyElementType, FromTargetElementsToWeight>
813 (fromElementKey, FromTargetElementsToWeight()));
816 for (
unsigned int to_index = 0 ; to_index < relationSize ; to_index++) {
818 selfRelation[ relation ].getToIndex(to_index);
819 double weight = selfRelation[ relation ].getWeight(to_index);
820 KeyElementType toElementKey = subset[to]->GetUniqueID();
822 theInducedRelation.find(fromElementKey)->second.insert(pair< KeyElementType, double> (toElementKey, weight));
828 NamedSet::StlRelationArray theExpectedRelation = m_TestBench.getNamedSet().
829 getRestrictedSelfRelation();
831 bool OKorKO = equal(theExpectedRelation.begin(), theExpectedRelation.end(), theInducedRelation.begin(),
832 [](
const NamedSet::StlRelationArray::value_type & a,
833 const NamedSet::StlRelationArray::value_type & b) {
836 cout << a.first <<
" vs " << b.first << endl;
838 return (true || a.first == b.first) &&
839 equal(a.second.begin(), a.second.end(), b.second.begin(),
840 [](const FromTargetElementsToWeight::value_type & x,
841 const FromTargetElementsToWeight::value_type & y) {
844 << x.first <<
"," << x.second
846 << y.first <<
"," << y.second <<
"\t";
847 cout << (x.first == y.first) <<
" , " << (x.second == y.second) << endl;
849 return x.first == y.first && x.second == y.second;
856 cout <<
"We do expect the following set of relations" << endl;
857 for (
auto relation : theExpectedRelation)
858 for (
auto to : relation.second)
859 cout << relation.first <<
" -> " << to.first <<
" ( " << to.second <<
" )" << endl;
861 cout <<
"We found the following ones" << endl;
862 for (
auto relation : theInducedRelation)
863 for (
auto to : relation.second)
864 cout << relation.first <<
" --> " << to.first <<
" ( " << to.second <<
" )" << endl;
877 TEST_F(SelectSubsetTest, ExtensiveTest)
879 m_TestBench.initializeDatastore();
880 m_TestBench.populateDatastore();
889 for (
auto other : m_TestBench.getOtherSets()) {
899 selector.
select(SelectionCriteriumOnElement);
903 bool allSubsetElementsAreGood(
true);
908 for (
const auto& element : subset) {
909 if (! SelectionCriteriumOnElement(& element))
910 allSubsetElementsAreGood =
false;
915 EXPECT_TRUE(allSubsetElementsAreGood);
921 for (
const auto& element : set)
922 NSelected += SelectionCriteriumOnElement(&element) ? 1 : 0;
924 EXPECT_TRUE(NSelected == subset.getEntries());
928 EXPECT_TRUE(testSelfRelation());
930 for (
int i = 0 ; i < m_TestBench.getNSets(); i++) {
932 auto otherSet = m_TestBench.getOtherNamedSet(i);
933 EXPECT_TRUE(testRelationToOther(otherSet));
934 EXPECT_TRUE(testRelationFromOther(otherSet));
941 return (a->getArrayIndex() % 2) == 1;
944 TEST_F(SelectSubsetTest, TestWithManyRelations)
953 arrayMain.registerInDataStore();
954 arrayA.registerInDataStore();
955 arrayB.registerInDataStore();
956 arrayA.registerRelationTo(arrayMain);
957 arrayMain.registerRelationTo(arrayB);
969 for (
int i = 0; i < 10; i++) {
970 auto* mainObj = arrayMain.appendNew();
971 for (
int j = 0; j < 2; j++) {
972 auto* aObj = arrayA.appendNew();
973 aObj->addRelationTo(mainObj);
975 for (
int j = 0; j < 10; j++) {
976 auto* bObj = arrayB.appendNew();
977 mainObj->addRelationTo(bObj);
982 selectorMain.
select(hasOddIndex);
986 EXPECT_EQ(10, arrayMain.getEntries());
987 EXPECT_EQ(20, arrayA.getEntries());
988 EXPECT_EQ(100, arrayB.getEntries());
994 EXPECT_EQ(5, arraySubset.getEntries());
1005 EXPECT_TRUE(hasOddIndex(originalObject));
1009 TEST_F(SelectSubsetTest, InheritAll)
1018 arrayMain.registerInDataStore();
1019 arrayA.registerInDataStore();
1020 arrayB.registerInDataStore();
1021 arrayA.registerRelationTo(arrayMain);
1022 arrayMain.registerRelationTo(arrayB);
1038 TEST_F(SelectSubsetTest, TestExistingSetWithManyRelations)
1047 arrayMain.registerInDataStore();
1048 arrayA.registerInDataStore();
1049 arrayB.registerInDataStore();
1050 arrayA.registerRelationTo(arrayMain);
1051 arrayMain.registerRelationTo(arrayB);
1060 for (
int i = 0; i < 10; i++) {
1061 auto* mainObj = arrayMain.appendNew();
1062 for (
int j = 0; j < 2; j++) {
1063 auto* aObj = arrayA.appendNew();
1064 aObj->addRelationTo(mainObj);
1066 for (
int j = 0; j < 10; j++) {
1067 auto* bObj = arrayB.appendNew();
1068 mainObj->addRelationTo(bObj);
1073 EXPECT_EQ(10, arrayMain.getEntries());
1074 EXPECT_EQ(20, arrayA.getEntries());
1075 EXPECT_EQ(100, arrayB.getEntries());
1078 selectorMain.
select(hasOddIndex);
1082 EXPECT_EQ(5, arrayMain.getEntries());
1092 EXPECT_EQ((i / 2 % 2 == 1) ? 1u : 0u, r.getRelationsTo<
RelationsObject>(
"main").size());
1097 TEST_F(SelectSubsetTest, TestEmptyArray)
1106 arrayMain.registerInDataStore();
1107 arrayA.registerInDataStore();
1108 arrayB.registerInDataStore();
1109 arrayA.registerRelationTo(arrayMain);
1110 arrayMain.registerRelationTo(arrayB);
1119 EXPECT_EQ(0, arrayMain.getEntries());
1120 selectorMain.
select(hasOddIndex);
1121 EXPECT_EQ(0, arrayMain.getEntries());
1124 for (
int i = 0; i < 10; i++) {
1125 auto* mainObj = arrayMain.appendNew();
1126 for (
int j = 0; j < 2; j++) {
1127 auto* aObj = arrayA.appendNew();
1128 aObj->addRelationTo(mainObj);
1130 for (
int j = 0; j < 10; j++) {
1131 auto* bObj = arrayB.appendNew();
1132 mainObj->addRelationTo(bObj);
1137 EXPECT_EQ(10, arrayMain.getEntries());
1138 EXPECT_EQ(20, arrayA.getEntries());
1139 EXPECT_EQ(100, arrayB.getEntries());
1143 selectorMain.
select(never);
1147 EXPECT_EQ(0, arrayMain.getEntries());
static DataStore & Instance()
Instance of singleton Store.
void setInitializeActive(bool active)
Setter for m_initializeActive.
void reset(EDurability durability)
Frees memory occupied by data store items and removes all objects from the map.
Low-level class to create/modify relations between StoreArrays.
unsigned int index_type
type used for indices.
Defines interface for accessing relations of objects in StoreArray.
std::vector< std::string > getInheritToArrays() const
Get list of arrays we inherit relations to.
bool getInheritToSelf() const
Do we inherit relations from original set to itself?
std::vector< std::string > getInheritFromArrays() const
Get list of arrays we inherit relations from.
Class to create a subset of a given StoreArray together with the relations with other StoreArrays.
void inheritRelationsTo(const StoreArray< T > &array, MoreArguments... moreArgs)
Inherit relations pointing from objects selected into this subset to Other.
void inheritRelationsFrom(const StoreArray< T > &array, MoreArguments... moreArgs)
Inherit relations pointing from Other to objects selected into this subset.
void inheritAllRelations()
Automatically inherit all relations to or from the original set (if registered when calling this func...
void registerSubset(const StoreArray< StoredClass > &set, DataStore::EStoreFlags storeFlags=DataStore::c_ErrorIfAlreadyRegistered)
Remove all non-selected objects from set.
Accessor to arrays stored in the data store.
T * appendNew()
Construct a new T object at the end of the array.
int getEntries() const
Get the number of objects in the array.
void select(const std::function< bool(const StoredClass *)> &f)
This method is the actual worker.
RelationsInterface< TObject > RelationsObject
Provides interface for getting/adding relations to objects in StoreArrays.
Abstract base class for different kinds of events.