Commit 4a9c9ff3 authored by btolsch's avatar btolsch Committed by Commit Bot

Add small_map::emplace

This also replaces some uses of small_map::insert with emplace.

Bug: None
Change-Id: I857ca36847eefe7dcc4a7f90d12c0d99ccf2afd8
Reviewed-on: https://chromium-review.googlesource.com/567599
Commit-Queue: Brandon Tolsch <btolsch@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarDerek Cheng <imcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#486254}
parent eff595d3
...@@ -452,6 +452,34 @@ class small_map { ...@@ -452,6 +452,34 @@ class small_map {
} }
} }
// Invalidates iterators.
template <typename... Args>
std::pair<iterator, bool> emplace(Args&&... args) {
key_equal compare;
if (size_ >= 0) {
value_type x(std::forward<Args>(args)...);
for (int i = 0; i < size_; i++) {
if (compare(array_[i]->first, x.first)) {
return std::make_pair(iterator(array_ + i), false);
}
}
if (size_ == kArraySize) {
ConvertToRealMap(); // Invalidates all iterators!
std::pair<typename NormalMap::iterator, bool> ret =
map_->emplace(std::move(x));
return std::make_pair(iterator(ret.first), ret.second);
} else {
array_[size_].Init(std::move(x));
return std::make_pair(iterator(array_ + size_++), true);
}
} else {
std::pair<typename NormalMap::iterator, bool> ret =
map_->emplace(std::forward<Args>(args)...);
return std::make_pair(iterator(ret.first), ret.second);
}
}
iterator begin() { iterator begin() {
if (size_ >= 0) { if (size_ >= 0) {
return iterator(array_); return iterator(array_);
......
...@@ -509,12 +509,15 @@ TEST(SmallMap, SubclassInitializationWithFunctionObject) { ...@@ -509,12 +509,15 @@ TEST(SmallMap, SubclassInitializationWithFunctionObject) {
EXPECT_EQ(1u, m.count(-1)); EXPECT_EQ(1u, m.count(-1));
} }
namespace {
// This class acts as a basic implementation of a move-only type. The canonical // This class acts as a basic implementation of a move-only type. The canonical
// example of such a type is scoped_ptr/unique_ptr. // example of such a type is scoped_ptr/unique_ptr.
template <typename V>
class MoveOnlyType { class MoveOnlyType {
public: public:
MoveOnlyType() : value_(0) {} MoveOnlyType() : value_(0) {}
explicit MoveOnlyType(int value) : value_(value) {} explicit MoveOnlyType(V value) : value_(value) {}
MoveOnlyType(MoveOnlyType&& other) { MoveOnlyType(MoveOnlyType&& other) {
*this = std::move(other); *this = std::move(other);
...@@ -529,26 +532,28 @@ class MoveOnlyType { ...@@ -529,26 +532,28 @@ class MoveOnlyType {
MoveOnlyType(const MoveOnlyType&) = delete; MoveOnlyType(const MoveOnlyType&) = delete;
MoveOnlyType& operator=(const MoveOnlyType&) = delete; MoveOnlyType& operator=(const MoveOnlyType&) = delete;
int value() const { return value_; } V value() const { return value_; }
private: private:
int value_; V value_;
}; };
} // namespace
TEST(SmallMap, MoveOnlyValueType) { TEST(SmallMap, MoveOnlyValueType) {
small_map<std::map<int, MoveOnlyType>, 2> m; small_map<std::map<int, MoveOnlyType<int>>, 2> m;
m[0] = MoveOnlyType(1); m[0] = MoveOnlyType<int>(1);
m[1] = MoveOnlyType(2); m[1] = MoveOnlyType<int>(2);
m.erase(m.begin()); m.erase(m.begin());
// small_map will move m[1] to an earlier index in the internal array. // small_map will move m[1] to an earlier index in the internal array.
EXPECT_EQ(m.size(), 1u); EXPECT_EQ(m.size(), 1u);
EXPECT_EQ(m[1].value(), 2); EXPECT_EQ(m[1].value(), 2);
m[0] = MoveOnlyType(1); m[0] = MoveOnlyType<int>(1);
// small_map must move the values from the array into the internal std::map. // small_map must move the values from the array into the internal std::map.
m[2] = MoveOnlyType(3); m[2] = MoveOnlyType<int>(3);
EXPECT_EQ(m.size(), 3u); EXPECT_EQ(m.size(), 3u);
EXPECT_EQ(m[0].value(), 1); EXPECT_EQ(m[0].value(), 1);
...@@ -563,4 +568,36 @@ TEST(SmallMap, MoveOnlyValueType) { ...@@ -563,4 +568,36 @@ TEST(SmallMap, MoveOnlyValueType) {
EXPECT_EQ(m[2].value(), 3); EXPECT_EQ(m[2].value(), 3);
} }
TEST(SmallMap, Emplace) {
small_map<std::map<size_t, MoveOnlyType<size_t>>> sm;
// loop through the transition from small map to map.
for (size_t i = 1; i <= 10; ++i) {
// insert an element
auto ret = sm.emplace(i, MoveOnlyType<size_t>(100 * i));
EXPECT_TRUE(ret.second);
EXPECT_TRUE(ret.first == sm.find(i));
EXPECT_EQ(ret.first->first, i);
EXPECT_EQ(ret.first->second.value(), 100 * i);
// try to insert it again with different value, fails, but we still get an
// iterator back with the original value.
ret = sm.emplace(i, MoveOnlyType<size_t>(i));
EXPECT_FALSE(ret.second);
EXPECT_TRUE(ret.first == sm.find(i));
EXPECT_EQ(ret.first->first, i);
EXPECT_EQ(ret.first->second.value(), 100 * i);
// check the state of the map.
for (size_t j = 1; j <= i; ++j) {
const auto it = sm.find(j);
EXPECT_TRUE(it != sm.end());
EXPECT_EQ(it->first, j);
EXPECT_EQ(it->second.value(), j * 100);
}
EXPECT_EQ(sm.size(), i);
EXPECT_FALSE(sm.empty());
}
}
} // namespace base } // namespace base
...@@ -73,11 +73,10 @@ GetInterfaceGuidMacMap() { ...@@ -73,11 +73,10 @@ GetInterfaceGuidMacMap() {
base::small_map<std::map<GUID, std::string, GuidOperatorLess>> guid_mac_map; base::small_map<std::map<GUID, std::string, GuidOperatorLess>> guid_mac_map;
for (ULONG i = 0; i < interface_table->NumEntries; ++i) { for (ULONG i = 0; i < interface_table->NumEntries; ++i) {
const auto* interface_row = &interface_table->Table[i]; const auto* interface_row = &interface_table->Table[i];
guid_mac_map.insert(std::make_pair( guid_mac_map.emplace(interface_row->InterfaceGuid,
interface_row->InterfaceGuid, std::string{reinterpret_cast<const char*>(
std::string{ interface_row->PhysicalAddress),
reinterpret_cast<const char*>(interface_row->PhysicalAddress), interface_row->PhysicalAddressLength});
interface_row->PhysicalAddressLength}));
} }
return guid_mac_map; return guid_mac_map;
...@@ -153,7 +152,7 @@ base::small_map<std::map<std::string, std::string>> GetMacSsidMap() { ...@@ -153,7 +152,7 @@ base::small_map<std::map<std::string, std::string>> GetMacSsidMap() {
if (ssid.empty()) { if (ssid.empty()) {
continue; continue;
} }
mac_ssid_map.insert(std::make_pair(mac_entry->second, std::move(ssid))); mac_ssid_map.emplace(mac_entry->second, std::move(ssid));
} }
return mac_ssid_map; return mac_ssid_map;
} }
......
...@@ -106,9 +106,8 @@ class PresentationFrame { ...@@ -106,9 +106,8 @@ class PresentationFrame {
base::small_map< base::small_map<
std::map<std::string, std::unique_ptr<PresentationMediaSinksObserver>>> std::map<std::string, std::unique_ptr<PresentationMediaSinksObserver>>>
url_to_sinks_observer_; url_to_sinks_observer_;
std::unordered_map< std::unordered_map<MediaRoute::Id,
MediaRoute::Id, std::unique_ptr<PresentationConnectionStateSubscription>>
std::unique_ptr<PresentationConnectionStateSubscription>>
connection_state_subscriptions_; connection_state_subscriptions_;
std::unordered_map<MediaRoute::Id, std::unordered_map<MediaRoute::Id,
std::unique_ptr<BrowserPresentationConnectionProxy>> std::unique_ptr<BrowserPresentationConnectionProxy>>
...@@ -207,8 +206,7 @@ void PresentationFrame::Reset() { ...@@ -207,8 +206,7 @@ void PresentationFrame::Reset() {
void PresentationFrame::AddPresentation( void PresentationFrame::AddPresentation(
const content::PresentationInfo& presentation_info, const content::PresentationInfo& presentation_info,
const MediaRoute& route) { const MediaRoute& route) {
presentation_id_to_route_.insert( presentation_id_to_route_.emplace(presentation_info.presentation_id, route);
std::make_pair(presentation_info.presentation_id, route));
} }
void PresentationFrame::ConnectToPresentation( void PresentationFrame::ConnectToPresentation(
...@@ -247,8 +245,7 @@ void PresentationFrame::ConnectToPresentation( ...@@ -247,8 +245,7 @@ void PresentationFrame::ConnectToPresentation(
auto* proxy = new BrowserPresentationConnectionProxy( auto* proxy = new BrowserPresentationConnectionProxy(
router_, route_id, std::move(receiver_connection_request), router_, route_id, std::move(receiver_connection_request),
std::move(controller_connection_ptr)); std::move(controller_connection_ptr));
browser_connection_proxies_.insert( browser_connection_proxies_.emplace(route_id, base::WrapUnique(proxy));
std::make_pair(route_id, base::WrapUnique(proxy)));
} }
} }
...@@ -285,9 +282,9 @@ void PresentationFrame::ListenForConnectionStateChange( ...@@ -285,9 +282,9 @@ void PresentationFrame::ListenForConnectionStateChange(
return; return;
} }
connection_state_subscriptions_.insert(std::make_pair( connection_state_subscriptions_.emplace(
route_id, router_->AddPresentationConnectionStateChangedCallback( route_id, router_->AddPresentationConnectionStateChangedCallback(
route_id, state_changed_cb))); route_id, state_changed_cb));
} }
PresentationServiceDelegateImpl* PresentationServiceDelegateImpl*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment