diff --git a/uppsrc/Core/Index.h b/uppsrc/Core/Index.h index b68632418..22e1b62ba 100644 --- a/uppsrc/Core/Index.h +++ b/uppsrc/Core/Index.h @@ -96,16 +96,26 @@ public: unsigned hashfn(const T& x) const { return GetHashValue(x); } T& Add(const T& x, unsigned _hash); + T& Add(T&& x, unsigned _hash); T& Add(const T& x); + T& Add(T&& x); Index& operator<<(const T& x) { Add(x); return *this; } + Index& operator<<(T&& x) { Add(pick(x)); return *this; } int FindAdd(const T& key, unsigned _hash); int FindAdd(const T& key); + int FindAdd(T&& key, unsigned _hash); + int FindAdd(T&& key); int Put(const T& x, unsigned _hash); int Put(const T& x); + int Put(T&& x, unsigned _hash); + int Put(T&& x); + int FindPut(const T& key, unsigned _hash); int FindPut(const T& key); + int FindPut(T&& key, unsigned _hash); + int FindPut(T&& key); int Find(const T& x, unsigned _hash) const; int Find(const T& x) const; @@ -116,6 +126,8 @@ public: T& Set(int i, const T& x, unsigned _hash); T& Set(int i, const T& x); + T& Set(int i, T&& x, unsigned _hash); + T& Set(int i, T&& x); const T& operator[](int i) const { return key[i]; } int GetCount() const { return key.GetCount(); } diff --git a/uppsrc/Core/Map.hpp b/uppsrc/Core/Map.hpp index a451c06eb..90df68575 100644 --- a/uppsrc/Core/Map.hpp +++ b/uppsrc/Core/Map.hpp @@ -111,6 +111,20 @@ T& Index::Add(const T& x) { return Add(x, hashfn(x)); } +template +T& Index::Add(T&& x, unsigned _hash) +{ + T& t = key.Add(pick(x)); + hash.Add(_hash); + return t; +} + +template +T& Index::Add(T&& x) +{ + return Add(pick(x), hashfn(x)); +} + template int Index::FindAdd(const T& _key, unsigned _hash) { int i = Find(_key, _hash); @@ -120,6 +134,22 @@ int Index::FindAdd(const T& _key, unsigned _hash) { return i; } +template +int Index::FindAdd(T&& _key, unsigned _hash) +{ + int i = Find(_key, _hash); + if(i >= 0) return i; + i = key.GetCount(); + Add(pick(_key), _hash); + return i; +} + +template +int Index::FindAdd(T&& key) +{ + return FindAdd(pick(key), hashfn(key)); +} + template int Index::Put(const T& x, unsigned _hash) { @@ -139,6 +169,25 @@ int Index::Put(const T& x) return Put(x, hashfn(x)); } +template +int Index::Put(T&& x, unsigned _hash) +{ + int q = hash.Put(_hash); + if(q < 0) { + q = key.GetCount(); + Add(pick(x), _hash); + } + else + key[q] = pick(x); + return q; +} + +template +int Index::Put(T&& x) +{ + return Put(pick(x), hashfn(x)); +} + template int Index::FindPut(const T& _key, unsigned _hash) { @@ -153,6 +202,20 @@ int Index::FindPut(const T& key) return FindPut(key, hashfn(key)); } +template +int Index::FindPut(T&& key, unsigned hash) +{ + int i = Find(key, hash); + if(i >= 0) return i; + return Put(pick(key), hash); +} + +template +int Index::FindPut(T&& key) +{ + return FindPut(pick(key), hashfn(key)); +} + template inline int Index::Find(const T& x, unsigned hash_) const { @@ -211,6 +274,21 @@ T& Index::Set(int i, const T& x) { return Set(i, x, hashfn(x)); } +template +T& Index::Set(int i, T&& x, unsigned _hash) +{ + T& t = key[i]; + t = pick(x); + hash.Set(i, _hash); + return t; +} + +template +T& Index::Set(int i, T&& x) +{ + return Set(i, pick(x), hashfn(x)); +} + #ifdef UPP template void Index::Serialize(Stream& s) { diff --git a/uppsrc/Core/src.tpp/Indext_en-us.tpp b/uppsrc/Core/src.tpp/Indext_en-us.tpp index b16bfe377..7e1d04c1b 100644 --- a/uppsrc/Core/src.tpp/Indext_en-us.tpp +++ b/uppsrc/Core/src.tpp/Indext_en-us.tpp @@ -110,30 +110,34 @@ td`::initializer`_list]<[*@4 T]>_[*@3 init])&] [s4;%- &] [s5;:Index`:`:Add`(const T`&`,unsigned`):%- [*@4 T][@(0.0.255) `&]_[* Add]([@(0.0.255) const]_ [*@4 T][@(0.0.255) `&]_[*@3 x], [@(0.0.255) unsigned]_[*@3 `_hash])&] -[s2; Adds a new element [%-*@3 x] with a precomputed hash value [%-*@3 `_hash]. +[s5;:Upp`:`:Index`:`:Add`(T`&`&`,unsigned`):%- [*@4 T][@(0.0.255) `&]_[* Add]([*@4 T][@(0.0.255) `& +`&]_[*@3 x], [@(0.0.255) unsigned]_[*@3 `_hash])&] +[s2; Adds a new element [%-@3 x] with a precomputed hash value [%-@3 `_hash]. The performance benefit of this variant is that sometimes you can compute hash`-value as the part of other process, like fetching strings from an input stream. Returns a reference to the element.&] -[s6; Requires T to have deep copy constructor.&] [s6; Invalidates iterators to Index.&] [s6; Invalidates references to Index.&] [s6; The precomputed [%-@3 `_hash] must be the same as the hash specified by HashFn.&] -[s3;%- &] +[s3; &] [s4;%- &] [s5;:Index`:`:Add`(const T`&`):%- [*@4 T][@(0.0.255) `&]_[* Add]([@(0.0.255) const]_[*@4 T][@(0.0.255) `& ]_[*@3 x])&] -[s2; Adds a new element [%-*@3 x ]to Index. Returns a reference to -the element.&] -[s6; Requires T to have deep copy constructor.&] +[s5;:Upp`:`:Index`:`:Add`(T`&`&`):%- [*@4 T][@(0.0.255) `&]_[* Add]([*@4 T][@(0.0.255) `&`&]_[*@3 x +])&] +[s2; Adds a new element [%-@3 x ]to Index. Returns a reference to the +element.&] [s6; Invalidates iterators to Index.&] [s6; Invalidates references to Index.&] -[s3;%- &] +[s3; &] [s4;%- &] [s5;:Upp`:`:Index`:`:operator`<`<`(const T`&`):%- [_^Upp`:`:Index^ Index][@(0.0.255) `&]_ [* operator<<]([@(0.0.255) const]_[*@4 T][@(0.0.255) `&]_[*@3 x])&] +[s5;:Upp`:`:Index`:`:operator`<`<`(T`&`&`):%- [_^Upp`:`:Index^ Index][@(0.0.255) `&]_[* ope +rator<<]([*@4 T][@(0.0.255) `&`&]_[*@3 x])&] [s2; Same as Add([%-*@3 x]).&] -[s3;%- &] +[s3; &] [s4;%- &] [s5;:Index`:`:Find`(const T`&`,unsigned`)const:%- [@(0.0.255) int]_[* Find]([@(0.0.255) con st]_[*@4 T][@(0.0.255) `&]_[*@3 x], [@(0.0.255) unsigned]_[*@3 `_hash])_[@(0.0.255) const]&] @@ -201,13 +205,14 @@ negative number is returned. Unlinked elements are ignored.&] [s4;%- &] [s5;:Index`:`:FindAdd`(const T`&`,unsigned`):%- [@(0.0.255) int]_[* FindAdd]([@(0.0.255) co nst]_[*@4 T][@(0.0.255) `&]_[*@3 key], [@(0.0.255) unsigned]_[*@3 `_hash])&] +[s5;:Upp`:`:Index`:`:FindAdd`(T`&`&`,unsigned`):%- [@(0.0.255) int]_[* FindAdd]([*@4 T][@(0.0.255) `& +`&]_[*@3 `_key], [@(0.0.255) unsigned]_[*@3 `_hash])&] [s2; Retrieves position of first element with value [%-*@3 key] in AIndex, using a precomputed [%-*@3 `_hash]. If multi`-key ordering is not broken and more than one element with the same value exists in AIndex, the greatest position is retrieved. If element does not exist in AIndex, it is added to AIndex and position of this newly added element is returned. Unlinked elements are ignored.&] -[s0;l288;a4;%- [*@5;1 Requires T to have deep copy constructor.]&] [s0;l288;a4;%- [*@5;1 Invalidates iterators to AIndex.]&] [s6;%- Invalidates references to Index.&] [s6; The precomputed [%-@3 `_hash] must be the same as the hash specified @@ -216,13 +221,13 @@ by HashFn.&] [s4;%- &] [s5;:Index`:`:FindAdd`(const T`&`):%- [@(0.0.255) int]_[* FindAdd]([@(0.0.255) const]_[*@4 T][@(0.0.255) `& ]_[*@3 key])&] +[s5;:Upp`:`:Index`:`:FindAdd`(T`&`&`):%- [@(0.0.255) int]_[* FindAdd]([*@4 T]`&`&_[*@3 key])&] [s2; Retrieves position of first element with value [%-*@3 key] in AIndex. If multi`-key ordering is not broken and more than one element with the same value exists in AIndex, lowest position is retrieved. If element does not exist in AIndex, it is added to AIndex and position of this newly added element is returned. Unlinked elements are ignored.&] -[s0;l288;a4;%- [*@5;1 Requires T to have deep copy constructor.]&] [s0;l288;a4;%- [*@5;1 Invalidates iterators to AIndex.]&] [s2;%- [*@5;1 Invalidates references to Index.]&] [s3; &] @@ -234,32 +239,38 @@ but is ignored by any Find operation.&] [s4;%- &] [s5;:Index`:`:Put`(const T`&`,unsigned`):%- [@(0.0.255) int]_[* Put]([@(0.0.255) const]_[*@4 T ][@(0.0.255) `&]_[*@3 x], [@(0.0.255) unsigned]_[*@3 `_hash])&] +[s5;:Upp`:`:Index`:`:Put`(T`&`&`,unsigned`):%- [@(0.0.255) template]_<[@(0.0.255) class]_ +[*@4 T]>_[@(0.0.255) int]_[* Put]([*@4 T][@(0.0.255) `&`&]_[*@3 x], [@(0.0.255) unsigned]_[*@3 `_ +hash])&] [s2; If there are any unlinked elements in Index, one of them is replaced by [%-*@3 x]. If there are no unlinked elements, the element with the specified value is appended to the end of AIndex using [* Add]. The position of newly placed element is returned.&] [s6; Invalidates multi`-key ordering.&] -[s6; Requires T to have deep copy constructor.&] [s6; Invalidates iterators to AIndex.&] [s6; Invalidates references to Index.&] [s6; The precomputed [%-@3 `_hash] must be the same as the hash specified by HashFn.&] -[s3;%- &] +[s2; [%-*@3 x] .&] +[s3; &] [s4;%- &] [s5;:Index`:`:Put`(const T`&`):%- [@(0.0.255) int]_[* Put]([@(0.0.255) const]_[*@4 T][@(0.0.255) `& ]_[*@3 x])&] +[s5;:Upp`:`:Index`:`:Put`(T`&`&`):%- [@(0.0.255) int]_[* Put]([*@4 T][@(0.0.255) `&`&]_[*@3 x]) +&] [s2; If there are any unlinked elements in AIndex, one of them is replaced by [%-*@3 x]. If there are no unlinked elements, the element with the specified value is appended to the end of AIndex using [* Add]. The position of the newly placed element is returned.&] [s6; Invalidates multi`-key ordering.&] -[s6; Requires T to have deep copy constructor.&] [s6; Invalidates iterators to AIndex.&] [s6; Invalidates references to Index.&] -[s3;%- &] +[s3; &] [s4;%- &] [s5;:Index`:`:FindPut`(const T`&`,unsigned`):%- [@(0.0.255) int]_[* FindPut]([@(0.0.255) co nst]_[*@4 T][@(0.0.255) `&]_[*@3 key], [@(0.0.255) unsigned]_[*@3 `_hash])&] +[s5;:Upp`:`:Index`:`:FindPut`(T`&`&`,unsigned`):%- [@(0.0.255) int]_[* FindPut]([*@4 T][@(0.0.255) `& +`&]_[*@3 key], [@(0.0.255) unsigned]_[*@3 hash])&] [s2; Retrieves the position of the first element with the value [%-*@3 key] in AIndex, using a precomputed [%-*@3 `_hash]. The precomputed hash value must be the same as the hash value that would be the @@ -267,33 +278,35 @@ result of HashFn. If the specified value does not exist in the AIndex, it is placed to it using [* Put(const T`& x, unsigned `_hash).] The position of the found or placed element is returned.&] [s6;~~~.992; Invalidates multi`-key ordering.&] -[s6; Requires T to have deep copy constructor.&] [s6; Invalidates iterators to AIndex.&] [s6; Invalidates references to Index.&] [s6;%- The precomputed [@3 `_hash] must be the same as the hash specified by HashFn.&] -[s3;%- &] +[s2; [%-*@3 key] .&] +[s3; &] [s4;%- &] [s5;:Index`:`:FindPut`(const T`&`):%- [@(0.0.255) int]_[* FindPut]([@(0.0.255) const]_[*@4 T][@(0.0.255) `& ]_[*@3 key])&] +[s5;:Upp`:`:Index`:`:FindPut`(T`&`&`):%- [@(0.0.255) int]_[* FindPut]([*@4 T][@(0.0.255) `&`& +]_[*@3 key])&] [s2; Retrieves the position of the first element with value [%-*@3 key] in AIndex. If the element does not exist in the AIndex, it is placed to it using [* Put(const T`& x).] The position of the found or placed element is returned.&] [s6; Invalidates multi`-key ordering.&] -[s6; Requires T to have deep copy constructor.&] [s6; Invalidates iterators to AIndex.&] [s6; Invalidates references to Index.&] -[s3;%- &] +[s3; &] [s4;%- &] [s5;:Index`:`:Set`(int`,const T`&`,unsigned`):%- [*@4 T][@(0.0.255) `&]_[* Set]([@(0.0.255) i nt]_[*@3 i], [@(0.0.255) const]_[*@4 T][@(0.0.255) `&]_[*@3 x], [@(0.0.255) unsigned]_[*@3 `_ha sh])&] +[s5;:Upp`:`:Index`:`:Set`(int`,T`&`&`,unsigned`):%- [*@4 T][@(0.0.255) `&]_[* Set]([@(0.0.255) i +nt]_[*@3 i], [*@4 T][@(0.0.255) `&`&]_[*@3 x], [@(0.0.255) unsigned]_[*@3 `_hash])&] [s2; Replaces the element at the specified position with a new element with value [%-*@3 x], using a precomputed [%-*@3 `_hash]. Speed of this operation depends on the total number of elements with the same value as the specified one. Returns a reference to the element.&] -[s6; Requires T to have deep copy constructor.&] [s6; Invalidates iterators to AIndex.&] [s6; Invalidates references to Index.&] [s6;%- The precomputed [@3 `_hash] must be the same as the hash specified @@ -302,14 +315,15 @@ by HashFn.&] [s4;%- &] [s5;:Index`:`:Set`(int`,const T`&`):%- [*@4 T][@(0.0.255) `&]_[* Set]([@(0.0.255) int]_[*@3 i], [@(0.0.255) const]_[*@4 T][@(0.0.255) `&]_[*@3 x])&] +[s5;:Upp`:`:Index`:`:Set`(int`,T`&`&`):%- [*@4 T][@(0.0.255) `&]_[* Set]([@(0.0.255) int]_[*@3 i +], [*@4 T][@(0.0.255) `&`&]_[*@3 x])&] [s2; Replaces the element at the specified position with a new element with value [%-*@3 x]. Speed of this operation depends on the total number of elements with the same value as the specified one. Returns a reference to the element.&] -[s6; Requires T to have deep copy constructor.&] [s6; Invalidates iterators to AIndex.&] [s6; Invalidates references to Index.&] -[s3;%- &] +[s3; &] [s4;%- &] [s5;:Index`:`:operator`[`]`(int`)const:%- [@(0.0.255) const]_[*@4 T][@(0.0.255) `&]_[* operat or`[`]]([@(0.0.255) int]_[*@3 i])_[@(0.0.255) const]&]