19 #ifndef SNARK_GRAPHICS_APPLICATIONS_LABELPOINTS_POINTMAP_H_
20 #define SNARK_GRAPHICS_APPLICATIONS_LABELPOINTS_POINTMAP_H_
25 #include <boost/optional.hpp>
26 #include <boost/static_assert.hpp>
27 #include <comma/math/compare.h>
33 template<
typename K,
typename T, std::
size_t D,
typename Compare = std::less< T > >
34 struct MultidimensionalMapimpl :
public std::map< K, MultidimensionalMapimpl< K, T, D - 1, Compare >, Compare >
36 typedef MultidimensionalMapimpl< K, T, D - 1, Compare > Basevalue_type;
37 typedef std::map< K, Basevalue_type, Compare > Base;
39 template <
typename P >
40 std::vector< T* > find(
const P& p )
42 typename Base::iterator it = this->Base::find( p[ p.size() - D ] );
43 if( it == this->Base::end() ) {
return std::vector< T* >(); }
44 return it->second.find( p );
47 template <
typename P >
48 void erase(
const P& p )
50 typename Base::iterator it = this->Base::find( p[ p.size() - D ] );
51 if( it == this->Base::end() ) {
return; }
52 it->second.erase( p );
53 if( it->second.empty() ) { this->Base::erase( it ); }
56 template <
typename P >
57 void insert(
const P& p,
const T& t ) { this->Base::operator[]( p[ p.size() - D ] ).insert( p, t ); }
59 template <
typename P >
60 void find( MultidimensionalMapimpl& m,
const P& lower,
const P& upper )
const
62 typename Base::const_iterator i = this->Base::lower_bound( lower[ lower.size() - D ] );
63 typename Base::const_iterator j = this->Base::upper_bound( upper[ upper.size() - D ] );
66 i->second.find( m[ i->first ], lower, upper );
67 if( m[ i->first ].empty() ) { m.MultidimensionalMapimpl::Base::erase( i->first ); }
71 std::size_t size()
const
74 for(
typename Base::const_iterator i = this->Base::begin(); i != this->Base::end(); ++i ) { s += i->second.size(); }
82 if( it == map->end() ) {
return; }
83 if( en.it != en.map->end() ) { ++en;
if( en.it != en.map->end() ) {
return; } }
85 if( it == map->end() ) {
return; }
86 it->second.setBegin( en );
88 template <
typename P >
89 void get( P& key, T*& value )
91 if( it == map->end() ) { value = NULL;
return; }
92 key[ key.size() - D ] = it->first;
95 typename Base::iterator it;
96 typename Basevalue_type::Enumerator en;
97 MultidimensionalMapimpl* map;
100 void setBegin( Enumerator& e )
102 e.map =
const_cast< MultidimensionalMapimpl*
>( this );
103 e.it = e.map->Base::begin();
104 if( e.it != this->Base::end() ) { e.it->second.setBegin( e.en ); }
107 void toString( std::ostringstream& oss,
const std::string& indent =
"" )
const
109 oss << indent <<
"[" << D <<
"]: size = " << this->Base::size() <<
":" << std::endl;
110 for(
typename Base::const_iterator it = this->Base::begin(); it != this->Base::end(); ++it )
112 oss << indent <<
" " << it->first <<
":" << std::endl;
113 it->second.toString( oss, indent +
" " );
118 template<
typename K,
typename T,
typename Compare >
119 struct MultidimensionalMapimpl< K, T, 1, Compare > :
public std::multimap< K, T, Compare >
121 typedef std::multimap< K, T, Compare > Base;
123 template <
typename P >
124 std::vector< T* > find(
const P& p )
127 typename Base::iterator it = this->Base::lower_bound( p[ p.size() - 1 ] );
128 typename Base::iterator upper = this->Base::upper_bound( p[ p.size() - 1 ] );
129 for( ; it != this->Base::end() && it != upper; ++it ) { v.push_back( &it->second ); }
133 template <
typename P >
134 void erase(
const P& p ) { this->Base::erase( p[ p.size() - 1 ] ); }
136 template <
typename P >
137 void insert(
const P& p,
const T& t ) { this->Base::insert( std::make_pair( p[ p.size() - 1 ], t ) ); }
139 template <
typename P >
140 void find( MultidimensionalMapimpl& m,
const P& lower,
const P& upper )
const
142 if( comma::math::less( upper[ lower.size() - 1 ], lower[ lower.size() - 1 ] ) ) {
return; }
143 typename Base::const_iterator l = this->Base::lower_bound( lower[ lower.size() - 1 ] );
144 typename Base::const_iterator u = this->Base::upper_bound( upper[ upper.size() - 1 ] );
145 if( l == this->Base::end() && u == this->Base::end() ) {
return; }
146 m.Base::insert( l, u );
151 void operator++() {
if( it != map->end() ) { ++it; } }
152 template <
typename P >
153 void get( P& key, T*& value )
155 if( it == map->end() ) { value = NULL;
return; }
156 key[ key.size() - 1 ] = it->first;
159 typename Base::iterator it;
160 MultidimensionalMapimpl* map;
163 void setBegin( Enumerator& e ) { e.map =
const_cast< MultidimensionalMapimpl*
>( this ); e.it = e.map->Base::begin(); }
165 void toString( std::ostringstream& oss,
const std::string& indent )
const
167 for(
typename Base::const_iterator it = this->Base::begin(); it != this->Base::end(); ++it )
169 oss << indent << it->first <<
":" << it->second << std::endl;
174 template <
typename T >
struct Less {
bool operator()(
const T& s,
const T& t )
const {
return comma::math::less( s, t ); } };
178 template<
typename P,
typename T >
179 struct PointMap :
public impl::MultidimensionalMapimpl< typename P::Scalar, T, P::RowsAtCompileTime, impl::Less< typename P::Scalar > >
181 typedef typename impl::MultidimensionalMapimpl< typename P::Scalar, T, P::RowsAtCompileTime, impl::Less< typename P::Scalar > > Base;
187 std::vector< T* > find(
const P& p )
const {
return const_cast< PointMap*
>( this )->Base::find( p ); }
188 std::vector< T* > find(
const P& p ) {
return Base::find( p ); }
189 void insert(
const P& p,
const T& t ) { Base::insert( p, t ); }
190 void insert(
const PointMap& m ) {
for( PointMap::ConstEnumerator en = m.begin(); !en.end(); ++en ) { Base::insert( en.key(), en.value() ); } }
191 void erase(
const P& p ) {
return Base::erase( p ); }
192 void erase(
const PointMap& m ) {
for( PointMap::ConstEnumerator en = m.begin(); !en.end(); ++en ) { Base::erase( en.key() ); } }
193 PointMap find(
const P& lower,
const P& upper )
const { PointMap m; Base::find( m, lower, upper );
return m; }
194 std::size_t size()
const {
return Base::size(); }
196 class ConstEnumerator
199 ConstEnumerator& operator++() { ++m_enum; m_enum.get( m_key, m_value );
return *
this; }
200 bool end()
const {
return m_value == NULL; }
201 const P& key()
const {
return m_key; }
203 const T& value()
const {
return *m_value; }
206 friend struct PointMap;
209 typename PointMap::Base::Enumerator m_enum;
212 class Enumerator :
public ConstEnumerator
215 T& value() {
return *this->m_value; }
218 ConstEnumerator begin()
const { ConstEnumerator e;
const_cast< PointMap*
>( this )->Base::setBegin( e.m_enum ); e.m_enum.get( e.m_key, e.m_value );
return e; }
219 Enumerator begin() { Enumerator e; this->Base::setBegin( e.m_enum ); e.m_enum.get( e.m_key, e.m_value );
return e; }
221 std::string toString() const
223 std::ostringstream oss;
224 this->Base::toString( oss );
231 #endif // SNARK_GRAPHICS_APPLICATIONS_LABELPOINTS_POINTMAP_H_