summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/device.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/device.cpp')
-rw-r--r--src/emu/device.cpp90
1 files changed, 66 insertions, 24 deletions
diff --git a/src/emu/device.cpp b/src/emu/device.cpp
index 99f3fcc7ce5..51088b02d4a 100644
--- a/src/emu/device.cpp
+++ b/src/emu/device.cpp
@@ -146,10 +146,10 @@ std::vector<std::string> device_t::searchpath() const
// info for a given region
//-------------------------------------------------
-memory_region *device_t::memregion(std::string _tag) const
+memory_region *device_t::memregion(std::string_view tag) const
{
// build a fully-qualified name and look it up
- auto search = machine().memory().regions().find(subtag(std::move(_tag)));
+ auto search = machine().memory().regions().find(subtag(tag));
if (search != machine().memory().regions().end())
return search->second.get();
else
@@ -162,10 +162,10 @@ memory_region *device_t::memregion(std::string _tag) const
// info for a given share
//-------------------------------------------------
-memory_share *device_t::memshare(std::string _tag) const
+memory_share *device_t::memshare(std::string_view tag) const
{
// build a fully-qualified name and look it up
- auto search = machine().memory().shares().find(subtag(std::move(_tag)));
+ auto search = machine().memory().shares().find(subtag(tag));
if (search != machine().memory().shares().end())
return search->second.get();
else
@@ -178,9 +178,9 @@ memory_share *device_t::memshare(std::string _tag) const
// bank info for a given bank
//-------------------------------------------------
-memory_bank *device_t::membank(std::string _tag) const
+memory_bank *device_t::membank(std::string_view tag) const
{
- auto search = machine().memory().banks().find(subtag(std::move(_tag)));
+ auto search = machine().memory().banks().find(subtag(tag));
if (search != machine().memory().banks().end())
return search->second.get();
else
@@ -193,10 +193,10 @@ memory_bank *device_t::membank(std::string _tag) const
// object for a given port name
//-------------------------------------------------
-ioport_port *device_t::ioport(std::string tag) const
+ioport_port *device_t::ioport(std::string_view tag) const
{
// build a fully-qualified name and look it up
- return machine().ioport().port(subtag(std::move(tag)).c_str());
+ return machine().ioport().port(subtag(tag));
}
@@ -205,7 +205,7 @@ ioport_port *device_t::ioport(std::string tag) const
// parameter
//-------------------------------------------------
-std::string device_t::parameter(const char *tag) const
+std::string device_t::parameter(std::string_view tag) const
{
// build a fully-qualified name and look it up
return machine().parameters().lookup(subtag(tag));
@@ -881,7 +881,7 @@ void device_t::device_timer(emu_timer &timer, device_timer_id id, int param, voi
// caching the results
//-------------------------------------------------
-device_t *device_t::subdevice_slow(const char *tag) const
+device_t *device_t::subdevice_slow(std::string_view tag) const
{
// resolve the full path
std::string fulltag = subtag(tag);
@@ -893,16 +893,22 @@ device_t *device_t::subdevice_slow(const char *tag) const
// walk the device list to the final path
device_t *curdevice = &mconfig().root_device();
- if (fulltag.length() > 1)
- for (int start = 1, end = fulltag.find_first_of(':', start); start != 0 && curdevice != nullptr; start = end + 1, end = fulltag.find_first_of(':', start))
+ std::string_view part(std::string_view(fulltag).substr(1));
+ while (!part.empty() && curdevice != nullptr)
+ {
+ std::string_view::size_type end = part.find_first_of(':');
+ if (end == std::string::npos)
{
- std::string part(fulltag, start, (end == -1) ? -1 : end - start);
curdevice = curdevice->subdevices().find(part);
+ part = std::string_view();
+ }
+ else
+ {
+ curdevice = curdevice->subdevices().find(part.substr(0, end));
+ part.remove_prefix(end + 1);
}
+ }
- // if we got a match, add to the fast map
- if (curdevice != nullptr)
- m_subdevices.m_tagmap.insert(std::make_pair(tag, curdevice));
return curdevice;
}
@@ -912,14 +918,13 @@ device_t *device_t::subdevice_slow(const char *tag) const
// to our device based on the provided tag
//-------------------------------------------------
-std::string device_t::subtag(std::string _tag) const
+std::string device_t::subtag(std::string_view tag) const
{
- const char *tag = _tag.c_str();
std::string result;
- if (*tag == ':')
+ if (!tag.empty() && tag[0] == ':')
{
// if the tag begins with a colon, ignore our path and start from the root
- tag++;
+ tag.remove_prefix(1);
result.assign(":");
}
else
@@ -931,12 +936,12 @@ std::string device_t::subtag(std::string _tag) const
}
// iterate over the tag, look for special path characters to resolve
- const char *caret;
- while ((caret = strchr(tag, '^')) != nullptr)
+ std::string_view::size_type caret;
+ while ((caret = tag.find('^')) != std::string_view::npos)
{
// copy everything up to there
- result.append(tag, caret - tag);
- tag = caret + 1;
+ result.append(tag, 0, caret);
+ tag.remove_prefix(caret + 1);
// strip trailing colons
int len = result.length();
@@ -964,6 +969,43 @@ std::string device_t::subtag(std::string _tag) const
//-------------------------------------------------
+// append - add a new subdevice to the list
+//-------------------------------------------------
+
+device_t &device_t::subdevice_list::append(std::unique_ptr<device_t> &&device)
+{
+ device_t &result(m_list.append(*device.release()));
+ m_tagmap.emplace(result.m_basetag, std::ref(result));
+ return result;
+}
+
+
+//-------------------------------------------------
+// replace_and_remove - add a new device to
+// replace an existing subdevice
+//-------------------------------------------------
+
+device_t &device_t::subdevice_list::replace_and_remove(std::unique_ptr<device_t> &&device, device_t &existing)
+{
+ m_tagmap.erase(existing.m_basetag);
+ device_t &result(m_list.replace_and_remove(*device.release(), existing));
+ m_tagmap.emplace(result.m_basetag, std::ref(result));
+ return result;
+}
+
+
+//-------------------------------------------------
+// remove - remove a subdevice from the list
+//-------------------------------------------------
+
+void device_t::subdevice_list::remove(device_t &device)
+{
+ m_tagmap.erase(device.m_basetag);
+ m_list.remove(device);
+}
+
+
+//-------------------------------------------------
// register_auto_finder - add a new item to the
// list of stuff to find after we go live
//-------------------------------------------------