summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/save.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/save.h')
-rw-r--r--src/emu/save.h61
1 files changed, 32 insertions, 29 deletions
diff --git a/src/emu/save.h b/src/emu/save.h
index 631fd590296..bd20d816d7c 100644
--- a/src/emu/save.h
+++ b/src/emu/save.h
@@ -75,6 +75,29 @@ class rewinder;
class save_manager
{
+ // stuff for working with arrays
+ template <typename T> struct array_unwrap
+ {
+ using underlying_type = T;
+ static constexpr std::size_t SAVE_COUNT = 1U;
+ static constexpr std::size_t SIZE = sizeof(underlying_type);
+ static underlying_type *ptr(T &value) { return &value; }
+ };
+ template <typename T, std::size_t N> struct array_unwrap<T [N]>
+ {
+ using underlying_type = typename array_unwrap<T>::underlying_type;
+ static constexpr std::size_t SAVE_COUNT = N * array_unwrap<T>::SAVE_COUNT;
+ static constexpr std::size_t SIZE = sizeof(underlying_type);
+ static underlying_type *ptr(T (&value)[N]) { return array_unwrap<T>::ptr(value[0]); }
+ };
+ template <typename T, std::size_t N> struct array_unwrap<std::array<T, N> >
+ {
+ using underlying_type = typename array_unwrap<T>::underlying_type;
+ static constexpr std::size_t SAVE_COUNT = N * array_unwrap<T>::SAVE_COUNT;
+ static constexpr std::size_t SIZE = sizeof(underlying_type);
+ static underlying_type *ptr(std::array<T, N> &value) { return array_unwrap<T>::ptr(value[0]); }
+ };
+
// type_checker is a set of templates to identify valid save types
template <typename ItemType> struct type_checker { static constexpr bool is_atom = false; static constexpr bool is_pointer = false; };
template <typename ItemType> struct type_checker<ItemType *> { static constexpr bool is_atom = false; static constexpr bool is_pointer = true; };
@@ -105,29 +128,6 @@ class save_manager
friend class rewinder;
public:
- // stuff for working with arrays
- template <typename T> struct array_unwrap
- {
- using underlying_type = T;
- static constexpr std::size_t SAVE_COUNT = 1U;
- static constexpr std::size_t SIZE = sizeof(underlying_type);
- static underlying_type *ptr(T &value) { return &value; }
- };
- template <typename T, std::size_t N> struct array_unwrap<T [N]>
- {
- using underlying_type = typename array_unwrap<T>::underlying_type;
- static constexpr std::size_t SAVE_COUNT = N * array_unwrap<T>::SAVE_COUNT;
- static constexpr std::size_t SIZE = sizeof(underlying_type);
- static underlying_type *ptr(T (&value)[N]) { return array_unwrap<T>::ptr(value[0]); }
- };
- template <typename T, std::size_t N> struct array_unwrap<std::array<T, N> >
- {
- using underlying_type = typename array_unwrap<T>::underlying_type;
- static constexpr std::size_t SAVE_COUNT = N * array_unwrap<T>::SAVE_COUNT;
- static constexpr std::size_t SIZE = sizeof(underlying_type);
- static underlying_type *ptr(std::array<T, N> &value) { return array_unwrap<T>::ptr(value[0]); }
- };
-
// stuff to allow STRUCT_MEMBER to work with pointers
template <typename T> struct pointer_unwrap { using underlying_type = typename array_unwrap<T>::underlying_type; };
template <typename T> struct pointer_unwrap<T &> { using underlying_type = typename pointer_unwrap<std::remove_cv_t<T> >::underlying_type; };
@@ -168,9 +168,10 @@ public:
}
// templatized wrapper for structure members
- template <typename ItemType, typename ElementType>
- void save_item(device_t *device, const char *module, const char *tag, int index, ItemType &value, ElementType array_unwrap<ItemType>::underlying_type::*element, const char *valname)
+ template <typename ItemType, typename StructType, typename ElementType>
+ void save_item(device_t *device, const char *module, const char *tag, int index, ItemType &value, ElementType StructType::*element, const char *valname)
{
+ static_assert(std::is_base_of<StructType, typename array_unwrap<ItemType>::underlying_type>::value, "Called save_item on a non-matching struct member pointer!");
static_assert(!(sizeof(typename array_unwrap<ItemType>::underlying_type) % sizeof(typename array_unwrap<ElementType>::underlying_type)), "Called save_item on an unaligned struct member!");
static_assert(!type_checker<ElementType>::is_pointer, "Called save_item on a struct member pointer!");
static_assert(type_checker<typename array_unwrap<ElementType>::underlying_type>::is_atom, "Called save_item on a non-fundamental type!");
@@ -185,9 +186,10 @@ public:
save_memory(device, module, tag, index, valname, array_unwrap<ItemType>::ptr(value[0]), array_unwrap<ItemType>::SIZE, array_unwrap<ItemType>::SAVE_COUNT * count);
}
- template <typename ItemType, typename ElementType>
- void save_pointer(device_t *device, const char *module, const char *tag, int index, ItemType *value, ElementType array_unwrap<ItemType>::underlying_type::*element, const char *valname, u32 count)
+ template <typename ItemType, typename StructType, typename ElementType>
+ void save_pointer(device_t *device, const char *module, const char *tag, int index, ItemType *value, ElementType StructType::*element, const char *valname, u32 count)
{
+ static_assert(std::is_base_of<StructType, typename array_unwrap<ItemType>::underlying_type>::value, "Called save_pointer on a non-matching struct member pointer!");
static_assert(!(sizeof(typename array_unwrap<ItemType>::underlying_type) % sizeof(typename array_unwrap<ElementType>::underlying_type)), "Called save_pointer on an unaligned struct member!");
static_assert(!type_checker<ElementType>::is_pointer, "Called save_pointer on a struct member pointer!");
static_assert(type_checker<typename array_unwrap<ElementType>::underlying_type>::is_atom, "Called save_pointer on a non-fundamental type!");
@@ -202,9 +204,10 @@ public:
save_memory(device, module, tag, index, valname, array_unwrap<ItemType>::ptr(value[0]), array_unwrap<ItemType>::SIZE, array_unwrap<ItemType>::SAVE_COUNT * count);
}
- template <typename ItemType, typename ElementType>
- void save_pointer(device_t *device, const char *module, const char *tag, int index, const std::unique_ptr<ItemType []> &value, ElementType array_unwrap<ItemType>::underlying_type::*element, const char *valname, u32 count)
+ template <typename ItemType, typename StructType, typename ElementType>
+ void save_pointer(device_t *device, const char *module, const char *tag, int index, const std::unique_ptr<ItemType []> &value, ElementType StructType::*element, const char *valname, u32 count)
{
+ static_assert(std::is_base_of<StructType, typename array_unwrap<ItemType>::underlying_type>::value, "Called save_pointer on a non-matching struct member pointer!");
static_assert(!(sizeof(typename array_unwrap<ItemType>::underlying_type) % sizeof(typename array_unwrap<ElementType>::underlying_type)), "Called save_pointer on an unaligned struct member!");
static_assert(!type_checker<ElementType>::is_pointer, "Called save_pointer on a struct member pointer!");
static_assert(type_checker<typename array_unwrap<ElementType>::underlying_type>::is_atom, "Called save_pointer on a non-fundamental type!");