Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MMIO: Get rid of a TODO regarding tuples #4767

Merged
merged 1 commit into from Jan 28, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
40 changes: 13 additions & 27 deletions Source/Core/Core/HW/MMIO.h
Expand Up @@ -6,6 +6,7 @@

#include <array>
#include <string>
#include <tuple>
#include <type_traits>

#include "Common/Assert.h"
Expand Down Expand Up @@ -177,45 +178,30 @@ class Mapping
HandlerArray<u32>::Write m_write_handlers32;

// Getter functions for the handler arrays.
//
// TODO:
// It would be desirable to clean these methods up using tuples, i.e. doing something like
//
// auto handlers = std::tie(m_read_handlers8, m_read_handlers16, m_read_handlers32);
// return std::get<Unit>(handlers)[index];
//
// However, we cannot use this currently because of a compiler bug in clang, presumably related
// to http://llvm.org/bugs/show_bug.cgi?id=18345, due to which the above code makes the compiler
// exceed the template recursion depth.
// As a workaround, we cast all handlers to the requested one's type. This cast will
// compile to a NOP for the returned member variable, but it's necessary to get this
// code to compile at all.
template <typename Unit>
ReadHandler<Unit>& GetReadHandler(size_t index)
{
static_assert(std::is_same<Unit, u8>::value || std::is_same<Unit, u16>::value ||
std::is_same<Unit, u32>::value,
static_assert(std::is_same<Unit, u8>() || std::is_same<Unit, u16>() ||

This comment was marked as off-topic.

This comment was marked as off-topic.

This comment was marked as off-topic.

This comment was marked as off-topic.

std::is_same<Unit, u32>(),
"Invalid unit used");

auto handlers = std::tie(m_read_handlers8, m_read_handlers16, m_read_handlers32);

using ArrayType = typename HandlerArray<Unit>::Read;
ArrayType& handler = *(std::is_same<Unit, u8>::value ?
(ArrayType*)&m_read_handlers8 :
std::is_same<Unit, u16>::value ? (ArrayType*)&m_read_handlers16 :
(ArrayType*)&m_read_handlers32);
return handler[index];
return std::get<ArrayType&>(handlers)[index];
}

template <typename Unit>
WriteHandler<Unit>& GetWriteHandler(size_t index)
{
static_assert(std::is_same<Unit, u8>::value || std::is_same<Unit, u16>::value ||
std::is_same<Unit, u32>::value,
static_assert(std::is_same<Unit, u8>() || std::is_same<Unit, u16>() ||
std::is_same<Unit, u32>(),
"Invalid unit used");

auto handlers = std::tie(m_write_handlers8, m_write_handlers16, m_write_handlers32);

using ArrayType = typename HandlerArray<Unit>::Write;
ArrayType& handler = *(std::is_same<Unit, u8>::value ?
(ArrayType*)&m_write_handlers8 :
std::is_same<Unit, u16>::value ? (ArrayType*)&m_write_handlers16 :
(ArrayType*)&m_write_handlers32);
return handler[index];
return std::get<ArrayType&>(handlers)[index];
}
};

Expand Down