21 inline Bijection_Base::InjectivityViolation::InjectivityViolation ()
22 : inherited{
"Injectivity violation"sv}
31 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
33 requires (IEqualsComparer<equal_to<DOMAIN_TYPE>, DOMAIN_TYPE> and IEqualsComparer<equal_to<RANGE_TYPE>, RANGE_TYPE>)
34 :
Bijection{equal_to<DOMAIN_TYPE>{}, equal_to<RANGE_TYPE>{}}
36 _AssertRepValidType ();
38 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
39 template <IEqualsComparer<DOMAIN_TYPE> DOMAIN_EQUALS_COMPARER, IEqualsComparer<RANGE_TYPE> RANGE_EQUALS_COMPARER>
40 inline Bijection<DOMAIN_TYPE, RANGE_TYPE>::Bijection (DOMAIN_EQUALS_COMPARER&& domainEqualsComparer, RANGE_EQUALS_COMPARER&& rangeEqualsComparer)
41 : Bijection{DataExchange::ValidationStrategy::eAssertion, forward<DOMAIN_EQUALS_COMPARER> (domainEqualsComparer),
42 forward<RANGE_EQUALS_COMPARER> (rangeEqualsComparer)}
44 _AssertRepValidType ();
46 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
47 template <IEqualsComparer<DOMAIN_TYPE> DOMAIN_EQUALS_COMPARER, IEqualsComparer<RANGE_TYPE> RANGE_EQUALS_COMPARER>
49 DOMAIN_EQUALS_COMPARER&& domainEqualsComparer, RANGE_EQUALS_COMPARER&& rangeEqualsComparer)
50 : inherited{Factory::Bijection_Factory<DOMAIN_TYPE, RANGE_TYPE, remove_cvref_t<DOMAIN_EQUALS_COMPARER>, remove_cvref_t<RANGE_EQUALS_COMPARER>>::
Default () (
51 injectivityCheckPolicy, forward<DOMAIN_EQUALS_COMPARER> (domainEqualsComparer), forward<RANGE_EQUALS_COMPARER> (rangeEqualsComparer))}
53 _AssertRepValidType ();
55 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
57 requires (IEqualsComparer<equal_to<DOMAIN_TYPE>, DOMAIN_TYPE> and IEqualsComparer<equal_to<RANGE_TYPE>, RANGE_TYPE>)
61 _AssertRepValidType ();
63 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
64 template <IEqualsComparer<DOMAIN_TYPE> DOMAIN_EQUALS_COMPARER, IEqualsComparer<RANGE_TYPE> RANGE_EQUALS_COMPARER>
66 RANGE_EQUALS_COMPARER&& rangeEqualsComparer,
const initializer_list<value_type>& src)
67 : Bijection{forward<DOMAIN_EQUALS_COMPARER> (domainEqualsComparer), forward<RANGE_EQUALS_COMPARER> (rangeEqualsComparer)}
70 _AssertRepValidType ();
72#if !qCompilerAndStdLib_RequiresNotMatchInlineOutOfLineForTemplateClassBeingDefined_Buggy
73 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
74 template <IIterableOfTo<KeyValuePair<DOMAIN_TYPE, RANGE_TYPE>> ITERABLE_OF_ADDABLE>
76 requires (not derived_from<remove_cvref_t<ITERABLE_OF_ADDABLE>, Bijection<DOMAIN_TYPE, RANGE_TYPE>>)
79 AddAll (forward<ITERABLE_OF_ADDABLE> (src));
80 _AssertRepValidType ();
83 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
84 template <IEqualsComparer<DOMAIN_TYPE> DOMAIN_EQUALS_COMPARER, IEqualsComparer<RANGE_TYPE> RANGE_EQUALS_COMPARER, IIterableOfTo<KeyValuePair<DOMAIN_TYPE, RANGE_TYPE>> ITERABLE_OF_ADDABLE>
86 RANGE_EQUALS_COMPARER&& rangeEqualsComparer, ITERABLE_OF_ADDABLE&& src)
87 : Bijection{forward<DOMAIN_EQUALS_COMPARER> (domainEqualsComparer), forward<RANGE_EQUALS_COMPARER> (rangeEqualsComparer)}
89 AddAll (forward<ITERABLE_OF_ADDABLE> (src));
90 _AssertRepValidType ();
92 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
93 template <IInputIterator<KeyValuePair<DOMAIN_TYPE, RANGE_TYPE>> ITERATOR_OF_ADDABLE, sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE>> ITERATOR_OF_ADDABLE2>
95 requires (IEqualsComparer<equal_to<DOMAIN_TYPE>, DOMAIN_TYPE> and IEqualsComparer<equal_to<RANGE_TYPE>, RANGE_TYPE>)
98 AddAll (forward<ITERATOR_OF_ADDABLE> (start), forward<ITERATOR_OF_ADDABLE2> (end));
99 _AssertRepValidType ();
101 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
102 template <IEqualsComparer<DOMAIN_TYPE> DOMAIN_EQUALS_COMPARER, IEqualsComparer<RANGE_TYPE> RANGE_EQUALS_COMPARER,
103 IInputIterator<KeyValuePair<DOMAIN_TYPE, RANGE_TYPE>> ITERATOR_OF_ADDABLE, sentinel_for<remove_cvref_t<ITERATOR_OF_ADDABLE>> ITERATOR_OF_ADDABLE2>
105 ITERATOR_OF_ADDABLE&& start, ITERATOR_OF_ADDABLE2&& end)
106 : Bijection{forward<DOMAIN_EQUALS_COMPARER> (domainEqualsComparer), forward<RANGE_EQUALS_COMPARER> (rangeEqualsComparer)}
108 AddAll (forward<ITERATOR_OF_ADDABLE> (start), forward<ITERATOR_OF_ADDABLE2> (
end));
109 _AssertRepValidType ();
111 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
116 _AssertRepValidType ();
118 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
122 _AssertRepValidType ();
124 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
125 inline auto Bijection<DOMAIN_TYPE, RANGE_TYPE>::GetDomainEqualsComparer () const -> DomainEqualsCompareFunctionType
127 return _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().GetDomainEqualsComparer ();
129 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
130 inline auto Bijection<DOMAIN_TYPE, RANGE_TYPE>::GetRangeEqualsComparer () const -> RangeEqualsCompareFunctionType
132 return _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().GetRangeEqualsComparer ();
134 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
139 return this->inherited::template Map<Iterable<DOMAIN_TYPE>> ([] (
const pair<DOMAIN_TYPE, RANGE_TYPE>& elt) {
return elt.first; });
141 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
146 return this->inherited::template Map<Iterable<RANGE_TYPE>> ([] (
const pair<DOMAIN_TYPE, RANGE_TYPE>& elt) {
return elt.second; });
148 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
151 if (item ==
nullptr) {
152 return _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().Lookup (key,
nullptr);
155 optional<RangeType> tmp;
156 if (_SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().Lookup (key, &tmp)) {
163 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
166 return _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().Lookup (key, item);
168 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
171 optional<RANGE_TYPE> r;
172 [[maybe_unused]]
bool result = _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().Lookup (key, &r);
173 Ensure (result == r.has_value ());
176 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
179 return _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().Lookup (key,
nullptr);
181 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
184 optional<RANGE_TYPE> r = Lookup (key);
185 return r.has_value () ? *r : defaultValue;
187 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
190 if (item ==
nullptr) {
191 return _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().InverseLookup (key,
nullptr);
194 optional<DomainType> tmp;
195 if (_SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().InverseLookup (key, &tmp)) {
202 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
205 return _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().InverseLookup (key, item);
207 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
210 optional<DOMAIN_TYPE> r;
211 [[maybe_unused]]
bool result = _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().InverseLookup (key, &r);
212 Ensure (result == r.has_value ());
215 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
218 return _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().InverseLookup (key,
nullptr);
220 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
223 optional<DOMAIN_TYPE> r = InverseLookup (key);
224 return r.has_value () ? *r : defaultValue;
226 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
229 vector<RANGE_TYPE> tmp;
230 tmp.reserve (values.size ());
231 for (
const auto& i : values) {
232 tmp.push_back (*Lookup (i));
236 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
239 vector<DOMAIN_TYPE> tmp;
240 tmp.reserve (values.size ());
241 for (
const auto& i : values) {
242 tmp.push_back (*InverseLookup (i));
246 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
247 template <
typename RESULT_CONTAINER, invocable<pair<DOMAIN_TYPE, RANGE_TYPE>> ELEMENT_MAPPER>
249 requires (convertible_to<invoke_result_t<ELEMENT_MAPPER, pair<DOMAIN_TYPE, RANGE_TYPE>>,
typename RESULT_CONTAINER::value_type> or
250 convertible_to<invoke_result_t<ELEMENT_MAPPER, pair<DOMAIN_TYPE, RANGE_TYPE>>, optional<typename RESULT_CONTAINER::value_type>>)
252 if constexpr (same_as<RESULT_CONTAINER, Bijection>) {
254 return inherited::template Where<RESULT_CONTAINER> (
255 forward<ELEMENT_MAPPER> (elementMapper), RESULT_CONTAINER{_SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().CloneEmpty ()});
258 return inherited::template Where<RESULT_CONTAINER> (forward<ELEMENT_MAPPER> (elementMapper));
261 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
262 template <derived_from<Iterable<pair<DOMAIN_TYPE, RANGE_TYPE>>> RESULT_CONTAINER, predicate<pair<DOMAIN_TYPE, RANGE_TYPE>> INCLUDE_PREDICATE>
265 if constexpr (same_as<RESULT_CONTAINER, Bijection>) {
267 return inherited::template Where<RESULT_CONTAINER> (
268 forward<INCLUDE_PREDICATE> (includeIfTrue), RESULT_CONTAINER{_SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().CloneEmpty ()});
271 return inherited::template Where<RESULT_CONTAINER> (forward<INCLUDE_PREDICATE> (includeIfTrue));
274 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
278 _SafeReadRepAccessor<_IRep> lhs{
this};
279 Bijection result = lhs._ConstGetRep ().CloneEmpty ();
280 for (
const auto& i : *
this) {
281 if (domainValues.Contains (i.first, this->GetDomainEqualsComparer ())) {
287 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
291 _SafeReadRepAccessor<_IRep> lhs{
this};
292 Bijection result = lhs._ConstGetRep ().CloneEmpty ();
293 for (
const auto& i : *
this) {
294 if (rangeValues.Contains (i.second, this->GetRangeEqualsComparer ())) {
300 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
303 return _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().
Lookup (key,
nullptr);
305 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
310 if (GetRangeEqualsComparer () (t.second, v)) {
316 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
319 _SafeReadWriteRepAccessor<_IRep>{
this}._GetWriteableRep ().Add (key, newElt);
321 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
322 template <
typename ADDABLE_T>
324 requires (convertible_to<ADDABLE_T, pair<DOMAIN_TYPE, RANGE_TYPE>> or convertible_to<ADDABLE_T, KeyValuePair<DOMAIN_TYPE, RANGE_TYPE>>)
326 if constexpr (is_convertible_v<remove_cvref_t<ADDABLE_T>, value_type>) {
327 _SafeReadWriteRepAccessor<_IRep>{
this}._GetWriteableRep ().Add (p.first, p.second);
330 static_assert (is_convertible_v<ADDABLE_T, Common::KeyValuePair<DomainType, RangeType>>);
331 _SafeReadWriteRepAccessor<_IRep>{
this}._GetWriteableRep ().Add (p.fKey, p.fValue);
334 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
335 template <IInputIterator<KeyValuePair<DOMAIN_TYPE, RANGE_TYPE>> COPY_FROM_ITERATOR_KEYVALUE, sentinel_for<remove_cvref_t<COPY_FROM_ITERATOR_KEYVALUE>> COPY_FROM_ITERATOR_KEYVALUE2>
338 for (
auto i = forward<COPY_FROM_ITERATOR_KEYVALUE> (start); i != forward<COPY_FROM_ITERATOR_KEYVALUE2> (end); ++i) {
342 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
343 template <IIterableOfTo<KeyValuePair<DOMAIN_TYPE, RANGE_TYPE>> CONTAINER_OF_KEYVALUE>
352 AddAll (std::begin (items), std::end (items));
354 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
357 _SafeReadWriteRepAccessor<_IRep>{
this}._GetWriteableRep ().RemoveDomainElement (d);
359 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
362 _SafeReadWriteRepAccessor<_IRep>{
this}._GetWriteableRep ().RemoveRangeElement (r);
364 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
367 Require (not i.
Done ());
368 auto [writerRep, patchedIterator] = _GetWritableRepAndPatchAssociatedIterator (i);
369 writerRep->Remove (patchedIterator, nextI);
371 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
374 _SafeReadRepAccessor<_IRep> tmp{
this};
375 if (not tmp._ConstGetRep ().empty ()) {
376 this->_fRep = tmp._ConstGetRep ().CloneEmpty ();
379 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
380 template <predicate<pair<DOMAIN_TYPE, RANGE_TYPE>> PREDICATE>
384 for (Iterator<pair<DOMAIN_TYPE, RANGE_TYPE>> i = this->begin (); i != this->end ();) {
395 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
396 template <
typename TARGET_CONTAINER>
397 TARGET_CONTAINER Bijection<DOMAIN_TYPE, RANGE_TYPE>::Inverse ()
const
400 for (value_type i : *this) {
401 r.Add (i.second, i.first);
405 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
406 template <
typename CONTAINER_PAIR_RANGE_DOMAIN>
410 if constexpr (derived_from<CONTAINER_PAIR_RANGE_DOMAIN, Iterable<pair<DOMAIN_TYPE, RANGE_TYPE>>>) {
411 return CONTAINER_PAIR_RANGE_DOMAIN{this->begin (), this->end ()};
415 using BIT =
decltype (this->begin ());
416 return CONTAINER_PAIR_RANGE_DOMAIN{this->begin (), BIT{this->end ()}};
419 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
424 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
428 this->Remove (i, &nextI);
431 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
432 template <IIterableOfTo<KeyValuePair<DOMAIN_TYPE, RANGE_TYPE>> ITERABLE_OF_ADDABLE>
438 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
439 template <IIterableOfTo<KeyValuePair<DOMAIN_TYPE, RANGE_TYPE>> ITERABLE_OF_ADDABLE>
445 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
447 -> tuple<_IRep*, Iterator<value_type>>
449 Require (not i.Done ());
450 using element_type =
typename inherited::_SharedByValueRepType::element_type;
452 element_type* writableRep = this->_fRep.rwget ([&] (
const element_type& prevRepPtr) ->
typename inherited::_SharedByValueRepType::shared_ptr_type {
453 return Debug::UncheckedDynamicCast<const _IRep&> (prevRepPtr).CloneAndPatchIterator (&patchedIterator);
456 return make_tuple (Debug::UncheckedDynamicCast<_IRep*> (writableRep), move (patchedIterator));
458 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
462 _SafeReadRepAccessor<_IRep>{
this};
465 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
468 return _SafeReadRepAccessor<_IRep>{
this}._ConstGetRep ().Equals (_SafeReadRepAccessor<_IRep>{&rhs}._ConstGetRep ());
476 template <
typename DOMAIN_TYPE,
typename RANGE_TYPE>
483 if (this->
size () != rhs.size ()) {
488 for (
auto i = this->
MakeIterator (); not i.Done (); ++i) {
489 optional<RangeType> tmp;
490 if (not rhs.Lookup (i->first, &tmp) or not GetRangeEqualsComparer () (*tmp, i->second)) {
#define qStroika_Foundation_Debug_AssertionsChecked
The qStroika_Foundation_Debug_AssertionsChecked flag determines if assertions are checked and validat...
#define RequireNotNull(p)
#define RequireExpression(c)
Bijection allows for the bijective (1-1) association of two elements.
nonvirtual void RemoveDomainElement(ArgByValueType< DomainType > d)
nonvirtual void RemoveAll()
RemoveAll removes all, or all matching (predicate, iterator range, equals comparer or whatever) items...
nonvirtual Iterable< DomainType > MapToDomain(const Iterable< RangeType > &values) const
nonvirtual Iterator< value_type > erase(const Iterator< value_type > &i)
STL-ish alias for Remove ().
nonvirtual void RemoveRangeElement(ArgByValueType< RangeType > r)
nonvirtual Bijection WhereDomainIntersects(const Iterable< DomainType > &domainValues) const
nonvirtual void Remove(const Iterator< value_type > &i, Iterator< value_type > *nextI=nullptr)
nonvirtual Bijection WhereRangeIntersects(const Iterable< RangeType > &rangeValues) const
nonvirtual CONTAINER_PAIR_RANGE_DOMAIN As() const
nonvirtual Iterable< DomainType > Preimage() const
nonvirtual void Add(ArgByValueType< DomainType > key, ArgByValueType< RangeType > newElt)
nonvirtual Bijection & operator+=(const ITERABLE_OF_ADDABLE &items)
nonvirtual RESULT_CONTAINER Where(INCLUDE_PREDICATE &&includeIfTrue) const
Like Iterable<T>::Where, but returning a bijection - subset of this bijection where includeIfTrue is ...
nonvirtual optional< DomainType > InverseLookup(ArgByValueType< RangeType > key) const
nonvirtual Bijection & operator-=(const ITERABLE_OF_ADDABLE &items)
nonvirtual RESULT_CONTAINER Map(ELEMENT_MAPPER &&elementMapper) const
'override' Iterable<>::Map () function so RESULT_CONTAINER defaults to Bijection, and improve that ca...
typename inherited::value_type value_type
nonvirtual Iterable< RangeType > MapToRange(const Iterable< DomainType > &values) const
nonvirtual DomainType InverseLookupValue(ArgByValueType< RangeType > key, ArgByValueType< DomainType > defaultValue=DomainType()) const
nonvirtual optional< RangeType > Lookup(ArgByValueType< DomainType > key) const
nonvirtual bool ContainsRangeElement(ArgByValueType< RangeType > v) const
nonvirtual Iterable< RangeType > Image() const
nonvirtual RangeType LookupValue(ArgByValueType< DomainType > key, ArgByValueType< RangeType > defaultValue=RangeType()) const
nonvirtual bool ContainsDomainElement(ArgByValueType< DomainType > key) const
nonvirtual bool operator==(const Bijection &rhs) const
nonvirtual tuple< _IRep *, Iterator< value_type > > _GetWritableRepAndPatchAssociatedIterator(const Iterator< value_type > &i)
Utility to get WRITABLE underlying shared_ptr (replacement for what we normally do - _SafeReadWriteRe...
nonvirtual void AddAll(const CONTAINER_OF_KEYVALUE &items)
virtual Iterator< value_type > MakeIterator() const =0
virtual size_t size() const
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
static constexpr default_sentinel_t end() noexcept
Support for ranged for, and STL syntax in general.
An Iterator<T> is a copyable object which allows traversing the contents of some container....
nonvirtual bool Done() const
Done () means there is nothing left in this iterator (a synonym for (it == container....