/** ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** * Copyright 2014 Ben Vanik. All rights reserved. * * Released under the BSD license - see LICENSE in the root for more details. * ****************************************************************************** */ #ifndef POLY_MEMORY_H_ #define POLY_MEMORY_H_ #include #include #include #include namespace poly { inline size_t hash_combine(size_t seed) { return seed; } template size_t hash_combine(size_t seed, const T& v, const Ts&... vs) { std::hash hasher; seed ^= hasher(v) + 0x9E3779B9 + (seed << 6) + (seed >> 2); return hash_combine(seed, vs...); } size_t page_size(); template T load(const void* mem); template <> inline int8_t load(const void* mem) { return *reinterpret_cast(mem); } template <> inline uint8_t load(const void* mem) { return *reinterpret_cast(mem); } template <> inline int16_t load(const void* mem) { return *reinterpret_cast(mem); } template <> inline uint16_t load(const void* mem) { return *reinterpret_cast(mem); } template <> inline int32_t load(const void* mem) { return *reinterpret_cast(mem); } template <> inline uint32_t load(const void* mem) { return *reinterpret_cast(mem); } template <> inline int64_t load(const void* mem) { return *reinterpret_cast(mem); } template <> inline uint64_t load(const void* mem) { return *reinterpret_cast(mem); } template <> inline float load(const void* mem) { return *reinterpret_cast(mem); } template <> inline double load(const void* mem) { return *reinterpret_cast(mem); } template inline T load(const void* mem) { if (sizeof(T) == 1) { return static_cast(load(mem)); } else if (sizeof(T) == 2) { return static_cast(load(mem)); } else if (sizeof(T) == 4) { return static_cast(load(mem)); } else if (sizeof(T) == 8) { return static_cast(load(mem)); } else { assert_always("Invalid poly::load size"); } } template T load_and_swap(const void* mem); template <> inline int8_t load_and_swap(const void* mem) { return *reinterpret_cast(mem); } template <> inline uint8_t load_and_swap(const void* mem) { return *reinterpret_cast(mem); } template <> inline int16_t load_and_swap(const void* mem) { return byte_swap(*reinterpret_cast(mem)); } template <> inline uint16_t load_and_swap(const void* mem) { return byte_swap(*reinterpret_cast(mem)); } template <> inline int32_t load_and_swap(const void* mem) { return byte_swap(*reinterpret_cast(mem)); } template <> inline uint32_t load_and_swap(const void* mem) { return byte_swap(*reinterpret_cast(mem)); } template <> inline int64_t load_and_swap(const void* mem) { return byte_swap(*reinterpret_cast(mem)); } template <> inline uint64_t load_and_swap(const void* mem) { return byte_swap(*reinterpret_cast(mem)); } template <> inline float load_and_swap(const void* mem) { return byte_swap(*reinterpret_cast(mem)); } template <> inline double load_and_swap(const void* mem) { return byte_swap(*reinterpret_cast(mem)); } template <> inline std::string load_and_swap(const void* mem) { std::string value; for (int i = 0;; ++i) { auto c = poly::load_and_swap(reinterpret_cast(mem) + i); if (!c) { break; } value.push_back(static_cast(c)); } return value; } template <> inline std::wstring load_and_swap(const void* mem) { std::wstring value; for (int i = 0;; ++i) { auto c = poly::load_and_swap( reinterpret_cast(mem) + i); if (!c) { break; } value.push_back(static_cast(c)); } return value; } template void store(void* mem, T value); template <> inline void store(void* mem, int8_t value) { *reinterpret_cast(mem) = value; } template <> inline void store(void* mem, uint8_t value) { *reinterpret_cast(mem) = value; } template <> inline void store(void* mem, int16_t value) { *reinterpret_cast(mem) = value; } template <> inline void store(void* mem, uint16_t value) { *reinterpret_cast(mem) = value; } template <> inline void store(void* mem, int32_t value) { *reinterpret_cast(mem) = value; } template <> inline void store(void* mem, uint32_t value) { *reinterpret_cast(mem) = value; } template <> inline void store(void* mem, int64_t value) { *reinterpret_cast(mem) = value; } template <> inline void store(void* mem, uint64_t value) { *reinterpret_cast(mem) = value; } template <> inline void store(void* mem, float value) { *reinterpret_cast(mem) = value; } template <> inline void store(void* mem, double value) { *reinterpret_cast(mem) = value; } template inline void store(const void* mem, T value) { if (sizeof(T) == 1) { store(mem, static_cast(value)); } else if (sizeof(T) == 2) { store(mem, static_cast(value)); } else if (sizeof(T) == 4) { store(mem, static_cast(value)); } else if (sizeof(T) == 8) { store(mem, static_cast(value)); } else { assert_always("Invalid poly::store size"); } } template void store_and_swap(void* mem, T value); template <> inline void store_and_swap(void* mem, int8_t value) { *reinterpret_cast(mem) = value; } template <> inline void store_and_swap(void* mem, uint8_t value) { *reinterpret_cast(mem) = value; } template <> inline void store_and_swap(void* mem, int16_t value) { *reinterpret_cast(mem) = byte_swap(value); } template <> inline void store_and_swap(void* mem, uint16_t value) { *reinterpret_cast(mem) = byte_swap(value); } template <> inline void store_and_swap(void* mem, int32_t value) { *reinterpret_cast(mem) = byte_swap(value); } template <> inline void store_and_swap(void* mem, uint32_t value) { *reinterpret_cast(mem) = byte_swap(value); } template <> inline void store_and_swap(void* mem, int64_t value) { *reinterpret_cast(mem) = byte_swap(value); } template <> inline void store_and_swap(void* mem, uint64_t value) { *reinterpret_cast(mem) = byte_swap(value); } template <> inline void store_and_swap(void* mem, float value) { *reinterpret_cast(mem) = byte_swap(value); } template <> inline void store_and_swap(void* mem, double value) { *reinterpret_cast(mem) = byte_swap(value); } template struct be { be() = default; be(const T& src) : value(poly::byte_swap(src)) {} be(const be& other) { value = other.value; } operator T() const { return poly::byte_swap(value); } T value; }; } // namespace poly #endif // POLY_MEMORY_H_