[Positioning] Building: guarantee unique areas & waypoints

Building:
- Display areas & waypoints statistics in operator<<().
- Use an unordered_map for areas.
- Use an unordered_set for waypoints.
(instead of two vectors)

Area: display building name in operator<<().
This commit is contained in:
Matteo Cypriani 2010-04-02 10:56:52 +02:00
parent 2d4c90e4cd
commit f4e8d7a1b7
4 changed files with 79 additions and 43 deletions

View File

@ -1,4 +1,5 @@
#include "area.hh"
#include "building.hh"
using namespace std ;
@ -152,12 +153,14 @@ bool Area::operator==(const Area &source) const
*/
ostream &operator<<(ostream &os, const Area &a)
{
os << a.name << ';'
<< a.p_min.get_x() << ';'
<< a.p_max.get_x() << ';'
<< a.p_min.get_y() << ';'
<< a.p_max.get_y() << ';'
<< a.p_min.get_z() << ';'
<< a.p_max.get_z() ;
os
<< (a.building ? a.building->get_name() : "No building") << ';'
<< a.name << ';'
<< a.p_min.get_x() << ';'
<< a.p_max.get_x() << ';'
<< a.p_min.get_y() << ';'
<< a.p_max.get_y() << ';'
<< a.p_min.get_z() << ';'
<< a.p_max.get_z() ;
return os ;
}

View File

@ -4,6 +4,8 @@
using namespace std ;
using std::tr1::unordered_set ;
using std::tr1::unordered_map ;
@ -18,13 +20,13 @@ using namespace std ;
Building::~Building()
{
// Empty Area list
for (vector<Area*>::const_iterator i = areas.begin() ;
for (unordered_map<string, Area*>::const_iterator i = areas.begin() ;
i != areas.end() ; ++i)
delete *i ;
delete i->second ;
areas.clear() ;
// Empty Waypoint list
for (vector<Waypoint*>::const_iterator i = waypoints.begin() ;
for (unordered_set<Waypoint*>::const_iterator i = waypoints.begin() ;
i != waypoints.end() ; ++i)
{
// Delete current waypoint only if it is not linked to another building
@ -36,6 +38,41 @@ Building::~Building()
/* *** Write accessors *** */
/**
* @param a A pointer to the Area to add. If \em a is NULL, nothing will
* be added. If the Area it points to already exist in #areas, it is
* deleted and nullified, unless it is the same pointer (see the code to
* understand!); hmm, maybe we should handle that with exceptions
*/
void Building::add_area(Area *&area)
{
if (area == NULL)
return ;
string area_name = area->get_name() ;
// Check if the area already exist in areas
unordered_map<string, Area*>::const_iterator i =
areas.find(area_name) ;
if (i != areas.end())
{
// Do not delete if area points to the already stored Area
if (i->second != area)
{
delete area ;
area = NULL ;
}
return ;
}
areas[area_name] = const_cast<Area*>(area) ;
}
/* *** Operators *** */
@ -67,7 +104,10 @@ bool Building::operator==(const Building &source) const
ostream& operator<<(ostream &os, const Building &b)
{
os << b.name ;
os
<< b.name << " ("
<< b.areas.size() << " areas, "
<< b.waypoints.size() << " waypoints)" ;
return os ;
}

View File

@ -5,8 +5,9 @@ class Area ;
class Waypoint ;
#include <string>
#include <vector>
#include <ostream>
#include <boost/tr1/unordered_set.hpp>
#include <boost/tr1/unordered_map.hpp>
/// Represents a building, containing one or more Area
class Building
@ -14,9 +15,9 @@ class Building
protected:
std::string name ;
/// List of Area contained in the Building
std::vector<Area*> areas ;
std::tr1::unordered_map<std::string, Area*> areas ;
/// List of Waypoint in the Building
std::vector<Waypoint*> waypoints ;
std::tr1::unordered_set<Waypoint*> waypoints ;
public :
Building(const std::string &_name = "Unnamed building"):
@ -31,15 +32,16 @@ public :
/** @name Read accessors */
//@{
const std::string& get_name(void) const ;
const std::vector<Area*>& get_areas(void) const ;
const std::vector<Waypoint*>& get_waypoints(void) const ;
const std::tr1::unordered_map<std::string, Area*>&
get_areas(void) const ;
const std::tr1::unordered_set<Waypoint*>& get_waypoints(void) const ;
//@}
/** @name Write accessors */
//@{
void set_name(const std::string &_name) ;
/// Adds an Area to the \link #areas list of areas\endlink
void add_area(const Area *a) ;
void add_area(Area *&a) ;
/// Adds a Waypoint to the \link #waypoints list of waypoints\endlink
void add_waypoint(const Waypoint *wp) ;
//@}
@ -66,13 +68,15 @@ inline const std::string& Building::get_name() const
}
inline const std::vector<Area*>& Building::get_areas() const
inline const std::tr1::unordered_map<std::string, Area*>&
Building::get_areas() const
{
return areas ;
}
inline const std::vector<Waypoint*>& Building::get_waypoints() const
inline const std::tr1::unordered_set<Waypoint*>&
Building::get_waypoints() const
{
return waypoints ;
}
@ -88,17 +92,6 @@ inline void Building::set_name(const std::string &_name)
}
/**
* @param a A pointer to the Area to add. If \em a is NULL, nothing
* will be added.
*/
inline void Building::add_area(const Area *a)
{
if (a != NULL)
areas.push_back(const_cast<Area*>(a)) ;
}
/**
* @param wp A pointer to the Waypoint to add. If \em wp is NULL,
* nothing will be added.
@ -106,7 +99,7 @@ inline void Building::add_area(const Area *a)
inline void Building::add_waypoint(const Waypoint *wp)
{
if (wp != NULL)
waypoints.push_back(const_cast<Waypoint*>(wp)) ;
waypoints.insert(const_cast<Waypoint*>(wp)) ;
}

View File

@ -27,10 +27,10 @@ public:
// Simple read accessors
Building b1 ;
TS_ASSERT_EQUALS(b1.get_name(), "Unnamed building") ;
std::vector<Area*> va1 ;
TS_ASSERT_EQUALS(b1.get_areas(), va1) ;
std::vector<Waypoint*> vwp1 ;
TS_ASSERT_EQUALS(b1.get_waypoints(), vwp1) ;
std::tr1::unordered_map<std::string, Area*> areas1 ;
TS_ASSERT_EQUALS(b1.get_areas(), areas1) ;
std::tr1::unordered_set<Waypoint*> waypoints1 ;
TS_ASSERT_EQUALS(b1.get_waypoints(), waypoints1) ;
// Write & read accessors
Building b2("My Building") ;
@ -42,17 +42,17 @@ public:
Waypoint *wp2 = new Waypoint(&b2, 12, 78, 2) ;
b2.add_waypoint(wp1) ;
b2.add_waypoint(wp2) ;
vwp1.push_back(wp1) ;
vwp1.push_back(wp2) ;
TS_ASSERT_EQUALS(b2.get_waypoints(), vwp1) ;
waypoints1.insert(wp1) ;
waypoints1.insert(wp2) ;
TS_ASSERT_EQUALS(b2.get_waypoints(), waypoints1) ;
Area *a1 = new Area() ;
Area *a2 = new Area() ;
Area *a1 = new Area(&b2, "area1") ;
Area *a2 = new Area(&b2, "area2") ;
b2.add_area(a1) ;
b2.add_area(a2) ;
va1.push_back(a1) ;
va1.push_back(a2) ;
TS_ASSERT_EQUALS(b2.get_areas(), va1) ;
areas1["area1"] = a1 ;
areas1["area2"] = a2 ;
TS_ASSERT_EQUALS(b2.get_areas(), areas1) ;
}