Reformatted map classes.

BUG=
TEST=Trybots.

Review URL: https://webrtc-codereview.appspot.com/1006004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@3308 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
phoglund@webrtc.org 2012-12-18 17:18:35 +00:00
parent 61f39a3174
commit 6e0ce73741
5 changed files with 464 additions and 526 deletions

View File

@ -13,63 +13,62 @@
#include <map> #include <map>
#include "constructor_magic.h" #include "webrtc/system_wrappers/interface/constructor_magic.h"
namespace webrtc { namespace webrtc {
class MapItem class MapItem {
{ friend class MapWrapper;
friend class MapWrapper;
public: public:
MapItem(int id, void* ptr); MapItem(int id, void* ptr);
virtual ~MapItem(); virtual ~MapItem();
void* GetItem(); void* GetItem();
int GetId(); int GetId();
unsigned int GetUnsignedId(); unsigned int GetUnsignedId();
void SetItem(void* ptr); void SetItem(void* ptr);
private: private:
int item_id_; int item_id_;
void* item_pointer_; void* item_pointer_;
}; };
class MapWrapper class MapWrapper {
{ public:
public: MapWrapper();
MapWrapper(); ~MapWrapper();
~MapWrapper();
// Puts a pointer to anything in the map and associates it with id. Note, id // Puts a pointer to anything in the map and associates it with id. Note, id
// needs to be unique for all items in the map. // needs to be unique for all items in the map.
int Insert(int id, void* ptr); int Insert(int id, void* ptr);
// Removes item from map. // Removes item from map.
int Erase(MapItem* item); int Erase(MapItem* item);
// Finds item with associated with id and removes it from the map. // Finds item with associated with id and removes it from the map.
int Erase(int id); int Erase(int id);
// Returns the number of elements stored in the map. // Returns the number of elements stored in the map.
int Size() const; int Size() const;
// Returns a pointer to the first MapItem in the map. // Returns a pointer to the first MapItem in the map.
MapItem* First() const; MapItem* First() const;
// Returns a pointer to the last MapItem in the map. // Returns a pointer to the last MapItem in the map.
MapItem* Last() const; MapItem* Last() const;
// Returns a pointer to the MapItem stored after item in the map. // Returns a pointer to the MapItem stored after item in the map.
MapItem* Next(MapItem* item) const; MapItem* Next(MapItem* item) const;
// Returns a pointer to the MapItem stored before item in the map. // Returns a pointer to the MapItem stored before item in the map.
MapItem* Previous(MapItem* item) const; MapItem* Previous(MapItem* item) const;
// Returns a pointer to the MapItem associated with id from the map. // Returns a pointer to the MapItem associated with id from the map.
MapItem* Find(int id) const; MapItem* Find(int id) const;
private: private:
std::map<int, MapItem*> map_; std::map<int, MapItem*> map_;
}; };
} // namespace webrtc } // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_MAP_WRAPPER_H_ #endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_MAP_WRAPPER_H_

View File

@ -8,159 +8,134 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "map_wrapper.h" #include "webrtc/system_wrappers/interface/map_wrapper.h"
#include "trace.h" #include "webrtc/system_wrappers/interface/trace.h"
namespace webrtc { namespace webrtc {
MapItem::MapItem(int id, void* item) : item_id_(id), item_pointer_(item)
{ MapItem::MapItem(int id, void* item)
: item_id_(id),
item_pointer_(item) {
} }
MapItem::~MapItem() MapItem::~MapItem() {
{
} }
void* MapItem::GetItem() void* MapItem::GetItem() {
{ return item_pointer_;
return item_pointer_;
} }
int MapItem::GetId() int MapItem::GetId() {
{ return item_id_;
return item_id_;
} }
unsigned int MapItem::GetUnsignedId() unsigned int MapItem::GetUnsignedId() {
{ return static_cast<unsigned int>(item_id_);
return static_cast<unsigned int>(item_id_);
} }
void MapItem::SetItem(void* ptr) void MapItem::SetItem(void* ptr) {
{ item_pointer_ = ptr;
item_pointer_ = ptr;
} }
MapWrapper::MapWrapper() : map_() MapWrapper::MapWrapper() : map_() {
{
} }
MapWrapper::~MapWrapper() MapWrapper::~MapWrapper() {
{ if (!map_.empty()) {
if (!map_.empty()) WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1,
{ "Potential memory leak in MapWrapper");
WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1, // Remove all map items. Please note that std::map::clear() can't be
"Potential memory leak in MapWrapper"); // used because each item has some dynamically allocated memory
// Remove all map items. Please note that std::map::clear() can't be // associated with it (i.e. using std::map::clear would introduce a
// used because each item has some dynamically allocated memory // memory leak).
// associated with it (i.e. using std::map::clear would introduce a while (Erase(First()) == 0)
// memory leak). {}
while (Erase(First()) == 0) }
{}
}
} }
int MapWrapper::Size() const int MapWrapper::Size() const {
{ return (int)map_.size();
return (int)map_.size();
} }
int MapWrapper::Insert(int id, void* ptr) int MapWrapper::Insert(int id, void* ptr) {
{ map_[id] = new MapItem(id, ptr);
map_[id] = new MapItem(id,ptr); return 0;
}
MapItem* MapWrapper::First() const {
std::map<int, MapItem*>::const_iterator it = map_.begin();
if (it != map_.end()) {
return it->second;
}
return 0;
}
MapItem* MapWrapper::Last() const {
std::map<int, MapItem*>::const_reverse_iterator it = map_.rbegin();
if (it != map_.rend()) {
return it->second;
}
return 0;
}
MapItem* MapWrapper::Next(MapItem* item) const {
if (item == 0) {
return 0; return 0;
}
std::map<int, MapItem*>::const_iterator it = map_.find(item->item_id_);
if (it != map_.end()) {
it++;
if (it != map_.end()) {
return it->second;
}
}
return 0;
} }
MapItem* MapWrapper::First() const MapItem* MapWrapper::Previous(MapItem* item) const {
{ if (item == 0) {
std::map<int, MapItem*>::const_iterator it = map_.begin();
if (it != map_.end())
{
return it->second;
}
return 0; return 0;
}
std::map<int, MapItem*>::const_iterator it = map_.find(item->item_id_);
if ((it != map_.end()) &&
(it != map_.begin())) {
--it;
return it->second;
}
return 0;
} }
MapItem* MapWrapper::Last() const MapItem* MapWrapper::Find(int id) const {
{ std::map<int, MapItem*>::const_iterator it = map_.find(id);
std::map<int, MapItem*>::const_reverse_iterator it = map_.rbegin(); if (it != map_.end()) {
if (it != map_.rend()) return it->second;
{ }
return it->second; return 0;
}
return 0;
} }
MapItem* MapWrapper::Next(MapItem* item) const int MapWrapper::Erase(MapItem* item) {
{ if (item == 0) {
if (item == 0)
{
return 0;
}
std::map<int, MapItem*>::const_iterator it = map_.find(item->item_id_);
if (it != map_.end())
{
it++;
if (it != map_.end())
{
return it->second;
}
}
return 0;
}
MapItem* MapWrapper::Previous(MapItem* item) const
{
if (item == 0)
{
return 0;
}
std::map<int, MapItem*>::const_iterator it = map_.find(item->item_id_);
if ((it != map_.end()) &&
(it != map_.begin()))
{
--it;
return it->second;
}
return 0;
}
MapItem* MapWrapper::Find(int id) const
{
std::map<int, MapItem*>::const_iterator it = map_.find(id);
if (it != map_.end())
{
return it->second;
}
return 0;
}
int MapWrapper::Erase(MapItem* item)
{
if (item == 0)
{
return -1;
}
std::map<int, MapItem*>::iterator it = map_.find(item->item_id_);
if (it != map_.end())
{
delete it->second;
map_.erase(it);
return 0;
}
return -1; return -1;
}
std::map<int, MapItem*>::iterator it = map_.find(item->item_id_);
if (it != map_.end()) {
delete it->second;
map_.erase(it);
return 0;
}
return -1;
} }
int MapWrapper::Erase(const int id) int MapWrapper::Erase(const int id) {
{ std::map<int, MapItem*>::iterator it = map_.find(id);
std::map<int, MapItem*>::iterator it = map_.find(id); if (it != map_.end()) {
if (it != map_.end()) delete it->second;
{ map_.erase(it);
delete it->second; return 0;
map_.erase(it); }
return 0; return -1;
}
return -1;
} }
} // namespace webrtc } // namespace webrtc

View File

@ -8,210 +8,173 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "map_no_stl.h" #include "webrtc/system_wrappers/source/map_no_stl.h"
#include "critical_section_wrapper.h" #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "trace.h" #include "webrtc/system_wrappers/interface/trace.h"
namespace webrtc { namespace webrtc {
MapNoStlItem::MapNoStlItem(int id, void* item) MapNoStlItem::MapNoStlItem(int id, void* item)
: next_(0), : next_(0),
prev_(0), prev_(0),
item_id_(id), item_id_(id),
item_ptr_(item) item_ptr_(item) {
{
} }
MapNoStlItem::~MapNoStlItem() MapNoStlItem::~MapNoStlItem() {
{
} }
void* MapNoStlItem::GetItem() void* MapNoStlItem::GetItem() {
{ return item_ptr_;
return item_ptr_;
} }
int MapNoStlItem::GetId() int MapNoStlItem::GetId() {
{ return item_id_;
return item_id_;
} }
unsigned int MapNoStlItem::GetUnsignedId() unsigned int MapNoStlItem::GetUnsignedId() {
{ return static_cast<unsigned int>(item_id_);
return static_cast<unsigned int>(item_id_);
} }
void MapNoStlItem::SetItem(void* ptr) void MapNoStlItem::SetItem(void* ptr) {
{ item_ptr_ = ptr;
item_ptr_ = ptr;
} }
MapNoStl::MapNoStl() MapNoStl::MapNoStl()
: critical_section_(CriticalSectionWrapper::CreateCriticalSection()), : critical_section_(CriticalSectionWrapper::CreateCriticalSection()),
first_(0), first_(0),
last_(0), last_(0),
size_(0) size_(0) {
{
} }
MapNoStl::~MapNoStl() MapNoStl::~MapNoStl() {
{ if (First()) {
if (First()) WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1,
{ "Potential memory leak in MapNoStl");
WEBRTC_TRACE(kTraceMemory, kTraceUtility, -1, while (Erase(First()) == 0)
"Potential memory leak in MapNoStl"); {}
while (Erase(First()) == 0) }
{} delete critical_section_;
}
delete critical_section_;
} }
int MapNoStl::Size() const int MapNoStl::Size() const {
{ return size_;
return size_;
} }
int MapNoStl::Insert(int id, void* ptr) int MapNoStl::Insert(int id, void* ptr) {
{ MapNoStlItem* new_item = new MapNoStlItem(id, ptr);
MapNoStlItem* new_item = new MapNoStlItem(id, ptr);
CriticalSectionScoped lock(critical_section_); CriticalSectionScoped lock(critical_section_);
MapNoStlItem* item = first_; MapNoStlItem* item = first_;
size_++; size_++;
if (!item) if (!item) {
{ first_ = new_item;
first_ = new_item;
last_ = new_item;
return 0;
}
while(item->next_)
{
// Three scenarios
// 1. Item should be inserted first.
// 2. Item should be inserted between two items
// 3. Item should be inserted last
if (item->GetId() > id)
{
new_item->next_ = item;
item->prev_ = new_item;
if (item == first_)
{
first_ = new_item;
}
else
{
new_item->prev_ = item->prev_;
new_item->prev_->next_ = new_item;
}
return 0;
}
item = item->next_;
}
// 3
item->next_ = new_item;
new_item->prev_ = item;
last_ = new_item; last_ = new_item;
return 0; return 0;
} }
while (item->next_) {
MapNoStlItem* MapNoStl::First() const // Three scenarios
{ // 1. Item should be inserted first.
return first_; // 2. Item should be inserted between two items
} // 3. Item should be inserted last
if (item->GetId() > id) {
MapNoStlItem* MapNoStl::Last() const new_item->next_ = item;
{ item->prev_ = new_item;
return last_; if (item == first_) {
} first_ = new_item;
} else {
MapNoStlItem* MapNoStl::Next(MapNoStlItem* item) const new_item->prev_ = item->prev_;
{ new_item->prev_->next_ = new_item;
if (!item) }
{ return 0;
return 0;
} }
return item->next_; item = item->next_;
}
// 3
item->next_ = new_item;
new_item->prev_ = item;
last_ = new_item;
return 0;
} }
MapNoStlItem* MapNoStl::Previous(MapNoStlItem* item) const MapNoStlItem* MapNoStl::First() const {
{ return first_;
if (!item)
{
return 0;
}
return item->prev_;
} }
MapNoStlItem* MapNoStl::Find(int id) const MapNoStlItem* MapNoStl::Last() const {
{ return last_;
CriticalSectionScoped lock(critical_section_);
MapNoStlItem* item = Locate(id);
return item;
} }
int MapNoStl::Erase(MapNoStlItem* item) MapNoStlItem* MapNoStl::Next(MapNoStlItem* item) const {
{ if (!item) {
if(!item)
{
return -1;
}
CriticalSectionScoped lock(critical_section_);
return Remove(item);
}
int MapNoStl::Erase(const int id)
{
CriticalSectionScoped lock(critical_section_);
MapNoStlItem* item = Locate(id);
if(!item)
{
return -1;
}
return Remove(item);
}
MapNoStlItem* MapNoStl::Locate(int id) const
{
MapNoStlItem* item = first_;
while(item)
{
if (item->GetId() == id)
{
return item;
}
item = item->next_;
}
return 0; return 0;
}
return item->next_;
} }
int MapNoStl::Remove(MapNoStlItem* item) MapNoStlItem* MapNoStl::Previous(MapNoStlItem* item) const {
{ if (!item) {
if (!item)
{
return -1;
}
size_--;
MapNoStlItem* previous_item = item->prev_;
MapNoStlItem* next_item = item->next_;
if (!previous_item)
{
next_item->prev_ = 0;
first_ = next_item;
}
else
{
previous_item->next_ = next_item;
}
if (!next_item)
{
previous_item->next_ = 0;
last_ = previous_item;
}
else
{
next_item->prev_ = previous_item;
}
delete item;
return 0; return 0;
}
return item->prev_;
} }
MapNoStlItem* MapNoStl::Find(int id) const {
CriticalSectionScoped lock(critical_section_);
MapNoStlItem* item = Locate(id);
return item;
}
int MapNoStl::Erase(MapNoStlItem* item) {
if (!item) {
return -1;
}
CriticalSectionScoped lock(critical_section_);
return Remove(item);
}
int MapNoStl::Erase(const int id) {
CriticalSectionScoped lock(critical_section_);
MapNoStlItem* item = Locate(id);
if (!item) {
return -1;
}
return Remove(item);
}
MapNoStlItem* MapNoStl::Locate(int id) const {
MapNoStlItem* item = first_;
while (item) {
if (item->GetId() == id) {
return item;
}
item = item->next_;
}
return 0;
}
int MapNoStl::Remove(MapNoStlItem* item) {
if (!item) {
return -1;
}
size_--;
MapNoStlItem* previous_item = item->prev_;
MapNoStlItem* next_item = item->next_;
if (!previous_item) {
next_item->prev_ = 0;
first_ = next_item;
} else {
previous_item->next_ = next_item;
}
if (!next_item) {
previous_item->next_ = 0;
last_ = previous_item;
} else {
next_item->prev_ = previous_item;
}
delete item;
return 0;
}
} // namespace webrtc } // namespace webrtc

View File

@ -11,60 +11,60 @@
#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_MAP_NO_STL_H_ #ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_MAP_NO_STL_H_
#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_MAP_NO_STL_H_ #define WEBRTC_SYSTEM_WRAPPERS_SOURCE_MAP_NO_STL_H_
#include "constructor_magic.h" #include "webrtc/system_wrappers/interface/constructor_magic.h"
namespace webrtc { namespace webrtc {
class CriticalSectionWrapper; class CriticalSectionWrapper;
class MapNoStlItem class MapNoStlItem {
{ friend class Map;
friend class Map;
public: public:
MapNoStlItem(int id, void* ptr); MapNoStlItem(int id, void* ptr);
virtual ~MapNoStlItem(); virtual ~MapNoStlItem();
void* GetItem(); void* GetItem();
int GetId(); int GetId();
unsigned int GetUnsignedId(); unsigned int GetUnsignedId();
void SetItem(void* ptr); void SetItem(void* ptr);
protected: protected:
MapNoStlItem* next_; MapNoStlItem* next_;
MapNoStlItem* prev_; MapNoStlItem* prev_;
private: private:
int item_id_; int item_id_;
void* item_ptr_; void* item_ptr_;
DISALLOW_COPY_AND_ASSIGN(MapNoStlItem); DISALLOW_COPY_AND_ASSIGN(MapNoStlItem);
}; };
class MapNoStl class MapNoStl {
{ public:
public: MapNoStl();
MapNoStl(); virtual ~MapNoStl();
virtual ~MapNoStl();
// MapWrapper functions. // MapWrapper functions.
int Insert(int id, void* ptr); int Insert(int id, void* ptr);
int Erase(MapNoStlItem* item); int Erase(MapNoStlItem* item);
int Erase(int id); int Erase(int id);
int Size() const; int Size() const;
MapNoStlItem* First() const; MapNoStlItem* First() const;
MapNoStlItem* Last() const; MapNoStlItem* Last() const;
MapNoStlItem* Next(MapNoStlItem* item) const; MapNoStlItem* Next(MapNoStlItem* item) const;
MapNoStlItem* Previous(MapNoStlItem* item) const; MapNoStlItem* Previous(MapNoStlItem* item) const;
MapNoStlItem* Find(int id) const; MapNoStlItem* Find(int id) const;
private: private:
MapNoStlItem* Locate(int id) const; MapNoStlItem* Locate(int id) const;
int Remove(MapNoStlItem* item); int Remove(MapNoStlItem* item);
CriticalSection* critical_section_; CriticalSection* critical_section_;
MapNoStlItem* first_; MapNoStlItem* first_;
MapNoStlItem* last_; MapNoStlItem* last_;
int size_; int size_;
DISALLOW_COPY_AND_ASSIGN(MapNoStl); DISALLOW_COPY_AND_ASSIGN(MapNoStl);
}; };
} // namespace webrtc } // namespace webrtc
#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_MAP_NO_STL_H_ #endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_MAP_NO_STL_H_

View File

@ -8,9 +8,9 @@
* be found in the AUTHORS file in the root of the source tree. * be found in the AUTHORS file in the root of the source tree.
*/ */
#include "gtest/gtest.h" #include "webrtc/system_wrappers/interface/map_wrapper.h"
#include "map_wrapper.h" #include "gtest/gtest.h"
using ::webrtc::MapWrapper; using ::webrtc::MapWrapper;
using ::webrtc::MapItem; using ::webrtc::MapItem;
@ -18,214 +18,215 @@ using ::webrtc::MapItem;
const int kNumberOfElements = 10; const int kNumberOfElements = 10;
int* ItemPointer(MapItem* item) { int* ItemPointer(MapItem* item) {
if (item == NULL) { if (item == NULL) {
return NULL; return NULL;
} }
return reinterpret_cast<int*>(item->GetItem()); return reinterpret_cast<int*>(item->GetItem());
} }
bool DeleteItemContent(MapItem* item) { bool DeleteItemContent(MapItem* item) {
if(item == NULL) { if (item == NULL) {
return false; return false;
} }
int* value_ptr = ItemPointer(item); int* value_ptr = ItemPointer(item);
delete value_ptr; delete value_ptr;
return true; return true;
} }
int ItemValue(MapItem* item) { int ItemValue(MapItem* item) {
if (item == NULL) { if (item == NULL) {
return -1; return -1;
} }
const int* value_ptr = ItemPointer(item); const int* value_ptr = ItemPointer(item);
if (value_ptr == 0) { if (value_ptr == 0) {
return -1; return -1;
} }
return *value_ptr; return *value_ptr;
} }
void PrintToConsole(const char* message, bool supress) { void PrintToConsole(const char* message, bool supress) {
if (supress) { if (supress) {
return; return;
} }
printf("%s", message); printf("%s", message);
} }
bool CreateAscendingMap(MapWrapper* ascending_map) { bool CreateAscendingMap(MapWrapper* ascending_map) {
int* insert_value = NULL; int* insert_value = NULL;
for (int i = 0; i < kNumberOfElements; ++i) { for (int i = 0; i < kNumberOfElements; ++i) {
insert_value = new int; insert_value = new int;
if (insert_value == NULL) { if (insert_value == NULL) {
return false; return false;
}
*insert_value = i;
if (0 != ascending_map->Insert(
i,
reinterpret_cast<void*>(insert_value))) {
return false;
}
} }
return true; *insert_value = i;
if (0 != ascending_map->Insert(
i,
reinterpret_cast<void*>(insert_value))) {
return false;
}
}
return true;
} }
bool ClearMap(MapWrapper* clear_map) { bool ClearMap(MapWrapper* clear_map) {
bool success = true; bool success = true;
while (clear_map->Size() != 0) { while (clear_map->Size() != 0) {
MapItem* remove_item = clear_map->First(); MapItem* remove_item = clear_map->First();
if (remove_item == NULL) { if (remove_item == NULL) {
return false; return false;
}
if (!DeleteItemContent(remove_item)) {
success = false;
}
if (clear_map->Erase(remove_item) != 0) {
return false;
}
} }
return success; if (!DeleteItemContent(remove_item)) {
success = false;
}
if (clear_map->Erase(remove_item) != 0) {
return false;
}
}
return success;
} }
void PrintMapItem(MapItem* item, bool supress) { void PrintMapItem(MapItem* item, bool supress) {
const int id = item->GetId(); const int id = item->GetId();
const int value = ItemValue(item); const int value = ItemValue(item);
char print_buffer[16]; char print_buffer[16];
sprintf(print_buffer, "(%3i,%3i) ", id, value); sprintf(print_buffer, "(%3i,%3i) ", id, value);
PrintToConsole(print_buffer, supress); PrintToConsole(print_buffer, supress);
} }
// Succeeds only if all the items were printed. // Succeeds only if all the items were printed.
bool PrintMap(const MapWrapper& print_map, bool supress) { bool PrintMap(const MapWrapper& print_map, bool supress) {
const int elements_to_print = print_map.Size(); const int elements_to_print = print_map.Size();
int elements_printed = 0; int elements_printed = 0;
MapItem* item = print_map.First(); MapItem* item = print_map.First();
PrintToConsole("[", supress); PrintToConsole("[", supress);
while (item != NULL) { while (item != NULL) {
PrintMapItem(item, supress); PrintMapItem(item, supress);
++elements_printed; ++elements_printed;
item = print_map.Next(item); item = print_map.Next(item);
} }
PrintToConsole("]\n", supress); PrintToConsole("]\n", supress);
return elements_printed == elements_to_print; return elements_printed == elements_to_print;
} }
// Succeeds only if all the items were printed. // Succeeds only if all the items were printed.
bool ReversePrintMap(const MapWrapper& print_map, bool supress) { bool ReversePrintMap(const MapWrapper& print_map, bool supress) {
const int elements_to_print = print_map.Size(); const int elements_to_print = print_map.Size();
int elements_printed = 0; int elements_printed = 0;
MapItem* item = print_map.Last(); MapItem* item = print_map.Last();
PrintToConsole("[", supress); PrintToConsole("[", supress);
while (item != NULL) { while (item != NULL) {
PrintMapItem(item, supress); PrintMapItem(item, supress);
++elements_printed; ++elements_printed;
item = print_map.Previous(item); item = print_map.Previous(item);
} }
PrintToConsole("]\n", supress); PrintToConsole("]\n", supress);
return elements_printed == elements_to_print; return elements_printed == elements_to_print;
} }
// Returns true if the map items contain the same item. // Returns true if the map items contain the same item.
bool CompareItems(MapItem* lhs_item, MapItem* rhs_item) { bool CompareItems(MapItem* lhs_item, MapItem* rhs_item) {
if ((lhs_item == NULL) || (rhs_item == NULL)) { if ((lhs_item == NULL) || (rhs_item == NULL)) {
return false; return false;
} }
if (lhs_item->GetId() != rhs_item->GetId()) { if (lhs_item->GetId() != rhs_item->GetId()) {
return false; return false;
} }
return lhs_item->GetItem() == rhs_item->GetItem(); return lhs_item->GetItem() == rhs_item->GetItem();
} }
// Returns true if the map contains the same items. // Returns true if the map contains the same items.
bool CompareMaps(const MapWrapper& lhs, const MapWrapper& rhs) { bool CompareMaps(const MapWrapper& lhs, const MapWrapper& rhs) {
const int map_size = lhs.Size(); const int map_size = lhs.Size();
if (map_size != rhs.Size()) { if (map_size != rhs.Size()) {
return false; return false;
}
int item_count = 0;
MapItem* lhs_item = lhs.First();
while (lhs_item != NULL) {
MapItem* rhs_item = rhs.Find(lhs_item->GetId());
if (rhs_item == NULL) {
return false;
} }
int item_count = 0; if (!CompareItems(lhs_item, rhs_item)) {
MapItem* lhs_item = lhs.First(); return false;
while (lhs_item != NULL) {
MapItem* rhs_item = rhs.Find(lhs_item->GetId());
if (rhs_item == NULL) {
return false;
}
if (!CompareItems(lhs_item, rhs_item)) {
return false;
}
++item_count;
lhs_item = lhs.Next(lhs_item);
} }
return item_count == map_size; ++item_count;
} lhs_item = lhs.Next(lhs_item);
}
return item_count == map_size;
}
class MapWrapperTest : public ::testing::Test { class MapWrapperTest : public ::testing::Test {
protected: protected:
virtual void SetUp() { virtual void SetUp() {
ASSERT_TRUE(CreateAscendingMap(&ascending_map_)); ASSERT_TRUE(CreateAscendingMap(&ascending_map_));
} }
virtual void TearDown() { virtual void TearDown() {
EXPECT_TRUE(ClearMap(&ascending_map_)); EXPECT_TRUE(ClearMap(&ascending_map_));
} }
MapWrapper ascending_map_; MapWrapper ascending_map_;
}; };
TEST_F(MapWrapperTest,RemoveTest) { TEST_F(MapWrapperTest, RemoveTest) {
// Erase using int id // Erase using int id
{ // Create local scope to avoid accidental re-use {
MapItem* item_first = ascending_map_.First(); // Create local scope to avoid accidental re-use
ASSERT_FALSE(item_first == NULL); MapItem* item_first = ascending_map_.First();
const int first_value_id = item_first->GetId(); ASSERT_FALSE(item_first == NULL);
const int first_value = ItemValue(item_first); const int first_value_id = item_first->GetId();
EXPECT_TRUE(first_value == 0); const int first_value = ItemValue(item_first);
EXPECT_EQ(first_value_id,first_value); EXPECT_TRUE(first_value == 0);
EXPECT_FALSE(NULL == ascending_map_.Find(first_value_id)); EXPECT_EQ(first_value_id, first_value);
EXPECT_TRUE(DeleteItemContent(item_first)); EXPECT_FALSE(NULL == ascending_map_.Find(first_value_id));
ascending_map_.Erase(first_value_id); EXPECT_TRUE(DeleteItemContent(item_first));
EXPECT_TRUE(NULL == ascending_map_.Find(first_value_id)); ascending_map_.Erase(first_value_id);
EXPECT_EQ(kNumberOfElements-1,ascending_map_.Size()); EXPECT_TRUE(NULL == ascending_map_.Find(first_value_id));
} EXPECT_EQ(kNumberOfElements - 1, ascending_map_.Size());
}
// Erase using MapItem* item
MapItem* item_last = ascending_map_.Last(); // Erase using MapItem* item
ASSERT_FALSE(item_last == NULL); MapItem* item_last = ascending_map_.Last();
const int last_value_id = item_last->GetId(); ASSERT_FALSE(item_last == NULL);
const int last_value = ItemValue(item_last); const int last_value_id = item_last->GetId();
EXPECT_TRUE(last_value == kNumberOfElements - 1); const int last_value = ItemValue(item_last);
EXPECT_EQ(last_value_id, last_value); EXPECT_TRUE(last_value == kNumberOfElements - 1);
EXPECT_FALSE(NULL == ascending_map_.Find(last_value_id)); EXPECT_EQ(last_value_id, last_value);
EXPECT_TRUE(DeleteItemContent(item_last)); EXPECT_FALSE(NULL == ascending_map_.Find(last_value_id));
ascending_map_.Erase(last_value_id); EXPECT_TRUE(DeleteItemContent(item_last));
EXPECT_TRUE(NULL == ascending_map_.Find(last_value_id)); ascending_map_.Erase(last_value_id);
EXPECT_EQ(kNumberOfElements-2,ascending_map_.Size()); EXPECT_TRUE(NULL == ascending_map_.Find(last_value_id));
EXPECT_EQ(kNumberOfElements - 2, ascending_map_.Size());
} }
TEST_F(MapWrapperTest, PrintTest) { TEST_F(MapWrapperTest, PrintTest) {
const bool supress = true; // Don't spam the console const bool supress = true; // Don't spam the console
EXPECT_TRUE(PrintMap(ascending_map_, supress)); EXPECT_TRUE(PrintMap(ascending_map_, supress));
EXPECT_TRUE(ReversePrintMap(ascending_map_, supress)); EXPECT_TRUE(ReversePrintMap(ascending_map_, supress));
} }
TEST_F(MapWrapperTest, CopyTest) { TEST_F(MapWrapperTest, CopyTest) {
MapWrapper compare_map; MapWrapper compare_map;
ASSERT_TRUE(CreateAscendingMap(&compare_map)); ASSERT_TRUE(CreateAscendingMap(&compare_map));
const int map_size = compare_map.Size(); const int map_size = compare_map.Size();
ASSERT_EQ(ascending_map_.Size(), map_size); ASSERT_EQ(ascending_map_.Size(), map_size);
// CompareMaps compare the pointers not value of the pointers. // CompareMaps compare the pointers not value of the pointers.
// (the values are the same since both are ascending maps). // (the values are the same since both are ascending maps).
EXPECT_FALSE(CompareMaps(compare_map,ascending_map_)); EXPECT_FALSE(CompareMaps(compare_map, ascending_map_));
int copy_count = 0; int copy_count = 0;
MapItem* ascend_item = ascending_map_.First(); MapItem* ascend_item = ascending_map_.First();
while (ascend_item != NULL) { while (ascend_item != NULL) {
MapItem* compare_item = compare_map.Find(ascend_item->GetId()); MapItem* compare_item = compare_map.Find(ascend_item->GetId());
ASSERT_FALSE(compare_item == NULL); ASSERT_FALSE(compare_item == NULL);
DeleteItemContent(compare_item); DeleteItemContent(compare_item);
compare_item->SetItem(ascend_item->GetItem()); compare_item->SetItem(ascend_item->GetItem());
ascend_item = ascending_map_.Next(ascend_item); ascend_item = ascending_map_.Next(ascend_item);
++copy_count; ++copy_count;
} }
EXPECT_TRUE(CompareMaps(compare_map,ascending_map_)); EXPECT_TRUE(CompareMaps(compare_map, ascending_map_));
while (compare_map.Erase(compare_map.First()) == 0) { while (compare_map.Erase(compare_map.First()) == 0) {
} }
EXPECT_EQ(map_size, copy_count); EXPECT_EQ(map_size, copy_count);
} }