/* Copyright 2017 - 2021 R. Thomas * Copyright 2017 - 2021 Quarkslab * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef LIEF_HASH_H_ #define LIEF_HASH_H_ #include #include "LIEF/visibility.h" #include "LIEF/Object.hpp" #include "LIEF/Visitor.hpp" namespace LIEF { LIEF_API size_t hash(const Object& v); LIEF_API size_t hash(const std::vector& raw); class LIEF_API Hash : public Visitor { public: template static size_t hash(const Object& obj); static size_t hash(const std::vector& raw); static size_t hash(const void* raw, size_t size); // combine two elements to produce a size_t. template static inline size_t combine(size_t lhs, U rhs); public: using Visitor::visit; Hash(void); Hash(size_t init_value); virtual Hash& process(const Object& obj); virtual Hash& process(size_t integer); virtual Hash& process(const std::string& str); virtual Hash& process(const std::u16string& str); virtual Hash& process(const std::vector& raw); template::value>::type> Hash& process(T v) { return this->process(static_cast(v)); } template Hash& process(typename It::iterator v) { return this->process(std::begin(v), std::end(v)); } template Hash& process(const std::array& array) { this->process(std::begin(array), std::end(array)); return *this; } template Hash& process(const std::vector& vector) { this->process(std::begin(vector), std::end(vector)); return *this; } template Hash& process(const std::set& set) { this->process(std::begin(set), std::end(set)); return *this; } template Hash& process(const std::pair& p) { this->process(p.first); this->process(p.second); return *this; } template Hash& process(InputIt begin, InputIt end) { for (auto&& it = begin; it != end; ++it) { this->process(*it); } return *this; } size_t value(void) const; virtual ~Hash(void); protected: size_t value_; }; template size_t Hash::combine(size_t lhs, U rhs) { return (lhs ^ rhs) + 0x9e3779b9 + (lhs << 6) + (rhs >> 2); } template size_t Hash::hash(const Object& obj) { H h; obj.accept(h); return h.value(); } } #endif