diff options
author | redpony <redpony@ec762483-ff6d-05da-a07a-a48fb63a330f> | 2010-10-18 23:24:01 +0000 |
---|---|---|
committer | redpony <redpony@ec762483-ff6d-05da-a07a-a48fb63a330f> | 2010-10-18 23:24:01 +0000 |
commit | e0ef743090038ee02d656cee11debd2246624ba0 (patch) | |
tree | e5e1d32402c8dcb490c574e24c087c56d4cc172e /klm/util/key_value_packing.hh | |
parent | 0c2514868f58bbfe422aa275e2905182cf2f57eb (diff) |
kenneth's LM preliminary integration
git-svn-id: https://ws10smt.googlecode.com/svn/trunk@681 ec762483-ff6d-05da-a07a-a48fb63a330f
Diffstat (limited to 'klm/util/key_value_packing.hh')
-rw-r--r-- | klm/util/key_value_packing.hh | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/klm/util/key_value_packing.hh b/klm/util/key_value_packing.hh new file mode 100644 index 00000000..450512ac --- /dev/null +++ b/klm/util/key_value_packing.hh @@ -0,0 +1,122 @@ +#ifndef UTIL_KEY_VALUE_PACKING__ +#define UTIL_KEY_VALUE_PACKING__ + +/* Why such a general interface? I'm planning on doing bit-level packing. */ + +#include <algorithm> +#include <cstddef> +#include <cstring> + +#include <inttypes.h> + +namespace util { + +template <class Key, class Value> struct Entry { + Key key; + Value value; + + const Key &GetKey() const { return key; } + const Value &GetValue() const { return value; } + + void Set(const Key &key_in, const Value &value_in) { + SetKey(key_in); + SetValue(value_in); + } + void SetKey(const Key &key_in) { key = key_in; } + void SetValue(const Value &value_in) { value = value_in; } + + bool operator<(const Entry<Key, Value> &other) const { return GetKey() < other.GetKey(); } +}; + +// And now for a brief interlude to specialize std::swap. +} // namespace util +namespace std { +template <class Key, class Value> void swap(util::Entry<Key, Value> &first, util::Entry<Key, Value> &second) { + swap(first.key, second.key); + swap(first.value, second.value); +} +}// namespace std +namespace util { + +template <class KeyT, class ValueT> class AlignedPacking { + public: + typedef KeyT Key; + typedef ValueT Value; + + public: + static const std::size_t kBytes = sizeof(Entry<Key, Value>); + static const std::size_t kBits = kBytes * 8; + + typedef Entry<Key, Value> * MutableIterator; + typedef const Entry<Key, Value> * ConstIterator; + typedef const Entry<Key, Value> & ConstReference; + + static MutableIterator FromVoid(void *start) { + return reinterpret_cast<MutableIterator>(start); + } + + static Entry<Key, Value> Make(const Key &key, const Value &value) { + Entry<Key, Value> ret; + ret.Set(key, value); + return ret; + } +}; + +template <class KeyT, class ValueT> class ByteAlignedPacking { + public: + typedef KeyT Key; + typedef ValueT Value; + + private: +#pragma pack(push) +#pragma pack(1) + struct RawEntry { + Key key; + Value value; + + const Key &GetKey() const { return key; } + const Value &GetValue() const { return value; } + + void Set(const Key &key_in, const Value &value_in) { + SetKey(key_in); + SetValue(value_in); + } + void SetKey(const Key &key_in) { key = key_in; } + void SetValue(const Value &value_in) { value = value_in; } + + bool operator<(const RawEntry &other) const { return GetKey() < other.GetKey(); } + }; +#pragma pack(pop) + + friend void std::swap<>(RawEntry&, RawEntry&); + + public: + typedef RawEntry *MutableIterator; + typedef const RawEntry *ConstIterator; + typedef RawEntry &ConstReference; + + static const std::size_t kBytes = sizeof(RawEntry); + static const std::size_t kBits = kBytes * 8; + + static MutableIterator FromVoid(void *start) { + return MutableIterator(reinterpret_cast<RawEntry*>(start)); + } + + static RawEntry Make(const Key &key, const Value &value) { + RawEntry ret; + ret.Set(key, value); + return ret; + } +}; + +} // namespace util +namespace std { +template <class Key, class Value> void swap( + typename util::ByteAlignedPacking<Key, Value>::RawEntry &first, + typename util::ByteAlignedPacking<Key, Value>::RawEntry &second) { + swap(first.key, second.key); + swap(first.value, second.value); +} +}// namespace std + +#endif // UTIL_KEY_VALUE_PACKING__ |