hash: add hash_all variadic tpl func, use in rose

This commit is contained in:
Justin Viiret 2016-08-23 16:12:34 +10:00 committed by Matthew Barr
parent 13af3bfb74
commit 13b6023a18
3 changed files with 127 additions and 161 deletions

View File

@ -928,6 +928,7 @@ SET (hs_SRCS
src/util/dump_mask.cpp
src/util/dump_mask.h
src/util/graph.h
src/util/hash.h
src/util/multibit_build.cpp
src/util/multibit_build.h
src/util/order_check.h

View File

@ -34,13 +34,16 @@
#include "som/som_operation.h"
#include "util/alloc.h"
#include "util/container.h"
#include "util/hash.h"
#include "util/make_unique.h"
#include "util/ue2_containers.h"
#include <algorithm>
#include <array>
#include <vector>
#include <boost/functional/hash/hash_fwd.hpp>
#include <boost/range/adaptor/map.hpp>
namespace ue2 {
@ -193,7 +196,7 @@ public:
virtual bool operator==(const RoseInstrType &) const { return true; }
size_t hash() const override {
return Opcode;
return boost::hash_value(static_cast<int>(Opcode));
}
bool equiv_to(const RoseInstrType &, const RoseInstruction::OffsetMap &,
@ -223,9 +226,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, groups);
return v;
return hash_all(static_cast<int>(opcode), groups);
}
void write(void *dest, RoseEngineBlob &blob,
@ -252,9 +253,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, min_offset);
return v;
return hash_all(static_cast<int>(opcode), min_offset);
}
void write(void *dest, RoseEngineBlob &blob,
@ -280,9 +279,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, groups);
return v;
return hash_all(static_cast<int>(opcode), groups);
}
void write(void *dest, RoseEngineBlob &blob,
@ -309,8 +306,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
return v;
return boost::hash_value(static_cast<int>(opcode));
}
void write(void *dest, RoseEngineBlob &blob,
@ -340,10 +336,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, min_bound);
boost::hash_combine(v, max_bound);
return v;
return hash_all(static_cast<int>(opcode), min_bound, max_bound);
}
void write(void *dest, RoseEngineBlob &blob,
@ -372,9 +365,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, key);
return v;
return hash_all(static_cast<int>(opcode), key);
}
void write(void *dest, RoseEngineBlob &blob,
@ -405,10 +396,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, index);
boost::hash_combine(v, count);
return v;
return hash_all(static_cast<int>(opcode), index, count);
}
void write(void *dest, RoseEngineBlob &blob,
@ -444,12 +432,8 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, and_mask);
boost::hash_combine(v, cmp_mask);
boost::hash_combine(v, neg_mask);
boost::hash_combine(v, offset);
return v;
return hash_all(static_cast<int>(opcode), and_mask, cmp_mask, neg_mask,
offset);
}
void write(void *dest, RoseEngineBlob &blob,
@ -487,12 +471,8 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, and_mask);
boost::hash_combine(v, cmp_mask);
boost::hash_combine(v, neg_mask);
boost::hash_combine(v, offset);
return v;
return hash_all(static_cast<int>(opcode), and_mask, cmp_mask, neg_mask,
offset);
}
void write(void *dest, RoseEngineBlob &blob,
@ -529,12 +509,8 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, and_mask);
boost::hash_combine(v, cmp_mask);
boost::hash_combine(v, negation);
boost::hash_combine(v, offset);
return v;
return hash_all(static_cast<int>(opcode), and_mask, cmp_mask, negation,
offset);
}
void write(void *dest, RoseEngineBlob &blob,
@ -568,11 +544,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, queue);
boost::hash_combine(v, lag);
boost::hash_combine(v, report);
return v;
return hash_all(static_cast<int>(opcode), queue, lag, report);
}
void write(void *dest, RoseEngineBlob &blob,
@ -605,11 +577,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, queue);
boost::hash_combine(v, lag);
boost::hash_combine(v, report);
return v;
return hash_all(static_cast<int>(opcode), queue, lag, report);
}
void write(void *dest, RoseEngineBlob &blob,
@ -638,10 +606,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, delay);
boost::hash_combine(v, index);
return v;
return hash_all(static_cast<int>(opcode), delay, index);
}
void write(void *dest, RoseEngineBlob &blob,
@ -667,9 +632,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, id);
return v;
return hash_all(static_cast<int>(opcode), id);
}
void write(void *dest, RoseEngineBlob &blob,
@ -710,9 +673,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, distance);
return v;
return hash_all(static_cast<int>(opcode), distance);
}
void write(void *dest, RoseEngineBlob &blob,
@ -740,10 +701,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, queue);
boost::hash_combine(v, lag);
return v;
return hash_all(static_cast<int>(opcode), queue, lag);
}
void write(void *dest, RoseEngineBlob &blob,
@ -771,10 +729,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, som.type);
boost::hash_combine(v, som.onmatch);
return v;
return hash_all(static_cast<int>(opcode), som.type, som.onmatch);
}
void write(void *dest, RoseEngineBlob &blob,
@ -810,11 +765,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, cancel);
boost::hash_combine(v, queue);
boost::hash_combine(v, event);
return v;
return hash_all(static_cast<int>(opcode), cancel, queue, event);
}
void write(void *dest, RoseEngineBlob &blob,
@ -842,10 +793,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, queue);
boost::hash_combine(v, event);
return v;
return hash_all(static_cast<int>(opcode), queue, event);
}
void write(void *dest, RoseEngineBlob &blob,
@ -877,11 +825,8 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, quash_som);
boost::hash_combine(v, dkey);
boost::hash_combine(v, offset_adjust);
return v;
return hash_all(static_cast<int>(opcode), quash_som, dkey,
offset_adjust);
}
void write(void *dest, RoseEngineBlob &blob,
@ -916,11 +861,8 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, quash_som);
boost::hash_combine(v, dkey);
boost::hash_combine(v, offset_adjust);
return v;
return hash_all(static_cast<int>(opcode), quash_som, dkey,
offset_adjust);
}
void write(void *dest, RoseEngineBlob &blob,
@ -951,10 +893,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, event);
boost::hash_combine(v, top_squash_distance);
return v;
return hash_all(static_cast<int>(opcode), event, top_squash_distance);
}
void write(void *dest, RoseEngineBlob &blob,
@ -983,10 +922,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, som.type);
boost::hash_combine(v, som.onmatch);
return v;
return hash_all(static_cast<int>(opcode), som.type, som.onmatch);
}
void write(void *dest, RoseEngineBlob &blob,
@ -1014,10 +950,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, som.type);
boost::hash_combine(v, som.onmatch);
return v;
return hash_all(static_cast<int>(opcode), som.type, som.onmatch);
}
void write(void *dest, RoseEngineBlob &blob,
@ -1044,10 +977,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, onmatch);
boost::hash_combine(v, offset_adjust);
return v;
return hash_all(static_cast<int>(opcode), onmatch, offset_adjust);
}
void write(void *dest, RoseEngineBlob &blob,
@ -1078,11 +1008,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, onmatch);
boost::hash_combine(v, offset_adjust);
boost::hash_combine(v, ekey);
return v;
return hash_all(static_cast<int>(opcode), onmatch, offset_adjust, ekey);
}
void write(void *dest, RoseEngineBlob &blob,
@ -1111,10 +1037,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, onmatch);
boost::hash_combine(v, offset_adjust);
return v;
return hash_all(static_cast<int>(opcode), onmatch, offset_adjust);
}
void write(void *dest, RoseEngineBlob &blob,
@ -1145,11 +1068,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, onmatch);
boost::hash_combine(v, offset_adjust);
boost::hash_combine(v, ekey);
return v;
return hash_all(static_cast<int>(opcode), onmatch, offset_adjust, ekey);
}
void write(void *dest, RoseEngineBlob &blob,
@ -1186,12 +1105,8 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, quash_som);
boost::hash_combine(v, dkey);
boost::hash_combine(v, onmatch);
boost::hash_combine(v, offset_adjust);
return v;
return hash_all(static_cast<int>(opcode), quash_som, dkey, onmatch,
offset_adjust);
}
void write(void *dest, RoseEngineBlob &blob,
@ -1221,10 +1136,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, onmatch);
boost::hash_combine(v, offset_adjust);
return v;
return hash_all(static_cast<int>(opcode), onmatch, offset_adjust);
}
void write(void *dest, RoseEngineBlob &blob,
@ -1252,9 +1164,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, ekey);
return v;
return hash_all(static_cast<int>(opcode), ekey);
}
void write(void *dest, RoseEngineBlob &blob,
@ -1286,10 +1196,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, end_adj);
boost::hash_combine(v, min_length);
return v;
return hash_all(static_cast<int>(opcode), end_adj, min_length);
}
void write(void *dest, RoseEngineBlob &blob,
@ -1315,9 +1222,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, index);
return v;
return hash_all(static_cast<int>(opcode), index);
}
void write(void *dest, RoseEngineBlob &blob,
@ -1343,9 +1248,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, groups);
return v;
return hash_all(static_cast<int>(opcode), groups);
}
void write(void *dest, RoseEngineBlob &blob,
@ -1371,9 +1274,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, groups);
return v;
return hash_all(static_cast<int>(opcode), groups);
}
void write(void *dest, RoseEngineBlob &blob,
@ -1401,9 +1302,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, index);
return v;
return hash_all(static_cast<int>(opcode), index);
}
void write(void *dest, RoseEngineBlob &blob,
@ -1435,10 +1334,9 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, num_keys);
for (const auto &jump : jump_table) {
boost::hash_combine(v, jump.first);
size_t v = hash_all(static_cast<int>(opcode), num_keys);
for (const u32 &key : jump_table | boost::adaptors::map_keys) {
boost::hash_combine(v, key);
}
return v;
}
@ -1508,9 +1406,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, state);
return v;
return hash_all(static_cast<int>(opcode), state);
}
void write(void *dest, RoseEngineBlob &blob,
@ -1554,10 +1450,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, num_keys);
boost::hash_combine(v, keys);
return v;
return hash_all(static_cast<int>(opcode), num_keys, keys);
}
void write(void *dest, RoseEngineBlob &blob,
@ -1584,9 +1477,7 @@ public:
}
size_t hash() const override {
size_t v = opcode;
boost::hash_combine(v, iter_offset);
return v;
return hash_all(static_cast<int>(opcode), iter_offset);
}
void write(void *dest, RoseEngineBlob &blob,

74
src/util/hash.h Normal file
View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* \file
* \brief Hashing utility functions.
*/
#ifndef UTIL_HASH_H
#define UTIL_HASH_H
#include <boost/functional/hash/hash_fwd.hpp>
namespace ue2 {
namespace hash_detail {
template<typename T>
void hash_build(size_t &v, const T &obj) {
boost::hash_combine(v, obj);
}
template<typename T, typename... Args>
void hash_build(size_t &v, const T &obj, Args&&... args) {
hash_build(v, obj);
hash_build(v, args...); // recursive
}
} // namespace hash_detail
/**
* \brief Computes the combined hash of all its arguments.
*
* Simply use:
*
* size_t hash = hash_all(a, b, c, d);
*
* Where a, b, c and d are hashable.
*/
template<typename... Args>
size_t hash_all(Args&&... args) {
size_t v = 0;
hash_detail::hash_build(v, args...);
return v;
}
} // namespace ue2
#endif // UTIL_HASH_H