diff --git a/libsrc/core/archive.hpp b/libsrc/core/archive.hpp index af7efc5e..dc381a4a 100644 --- a/libsrc/core/archive.hpp +++ b/libsrc/core/archive.hpp @@ -910,6 +910,54 @@ namespace ngcore } }; + // HashArchive ================================================================= + // This class enables to easily create hashes for archivable objects by xoring + // threw its data + + class NGCORE_API HashArchive : public Archive + { + size_t hash_value; + char* h; + int offset; + public: + HashArchive() : Archive(true) + { h = (char*)&hash_value; } + + using Archive::operator&; + Archive & operator & (double & d) override { return ApplyHash(d); } + Archive & operator & (int & i) override { return ApplyHash(i); } + Archive & operator & (short & i) override { return ApplyHash(i); } + Archive & operator & (long & i) override { return ApplyHash(i); } + Archive & operator & (size_t & i) override { return ApplyHash(i); } + Archive & operator & (unsigned char & i) override { return ApplyHash(i); } + Archive & operator & (bool & b) override { return ApplyHash(b); } + Archive & operator & (std::string & str) override + { for(auto c : str) ApplyHash(c); return *this; } + Archive & operator & (char *& str) override + { char* s = str; while(*s != '\0') ApplyHash(*(s++)); return *this; } + + // HashArchive can be used in const context + template + Archive & operator& (const T& val) const + { return (*this) & const_cast(val); } + + size_t GetHash() const { return hash_value; } + + private: + template + Archive& ApplyHash(T val) + { + auto n = sizeof(T); + char* pval = (char*)&val; + for(int i = 0; i < n; i++) + { + h[offset++] ^= pval[i]; + offset %= 8; + } + return *this; + } + }; + } // namespace ngcore #endif // NETGEN_CORE_ARCHIVE_HPP diff --git a/libsrc/core/bitarray.cpp b/libsrc/core/bitarray.cpp index db9fc114..2523ce5f 100644 --- a/libsrc/core/bitarray.cpp +++ b/libsrc/core/bitarray.cpp @@ -83,6 +83,18 @@ namespace ngcore return *this; } + bool BitArray :: operator==(const BitArray& other) const + { + if(size != other.Size()) + return false; + for(auto i : Range(size/CHAR_BIT)) + if(data[i] != other.data[i]) + return false; + for(auto i : Range(size%CHAR_BIT)) + if(Test(i + size * (size/CHAR_BIT)) != other.Test(i + size * (size/CHAR_BIT))) + return false; + return true; + } BitArray & BitArray :: operator= (const BitArray & ba2) { @@ -115,29 +127,39 @@ namespace ngcore return cnt; } - Archive & operator & (Archive & archive, BitArray & ba) + void BitArray :: DoArchive(Archive& archive) { - if (archive.Output()) + if(archive.GetVersion("netgen") >= "v6.2.2007-62") { - archive << ba.Size(); - for (size_t i = 0; i < ba.Size(); i++) - archive << ba[i]; + archive.NeedsVersion("netgen", "v6.2.2007-62"); + auto size = Size(); + archive & size; + if(archive.Input()) + SetSize(size); + archive.Do(data, size/CHAR_BIT+1); } else { - size_t size; - archive & size; - ba.SetSize (size); - ba.Clear(); - for (size_t i = 0; i < size; i++) + if (archive.Output()) { - bool b; - archive & b; - if (b) ba.SetBit(i); + throw Exception("should not get here"); + archive << Size(); + for (size_t i = 0; i < Size(); i++) + archive << (*this)[i]; + } + else + { + size_t size; + archive & size; + SetSize (size); + Clear(); + for (size_t i = 0; i < size; i++) + { + bool b; + archive & b; + if (b) SetBit(i); + } } } - return archive; } - - -} +} // namespace ngcore diff --git a/libsrc/core/bitarray.hpp b/libsrc/core/bitarray.hpp index 9c0823cf..4005fc81 100644 --- a/libsrc/core/bitarray.hpp +++ b/libsrc/core/bitarray.hpp @@ -131,6 +131,7 @@ public: return Test(i); } + NGCORE_API bool operator==(const BitArray& other) const; /// invert all bits NGCORE_API BitArray & Invert (); @@ -145,6 +146,9 @@ public: NGCORE_API BitArray & operator= (const BitArray & ba2); NGCORE_API size_t NumSet () const; + + NGCORE_API void DoArchive(Archive& archive); + private: /// unsigned char Mask (size_t i) const @@ -190,11 +194,8 @@ private: return res; } - NGCORE_API std::ostream & operator<<(std::ostream & s, const BitArray & ba); - NGCORE_API Archive & operator & (Archive & archive, BitArray & ba); - } // namespace ngcore #endif // NETGEN_CORE_BITARRAY