Commit 32cd2715 authored by Jakub Klinkovský's avatar Jakub Klinkovský
Browse files

Rewritten Containers::IndexedSet

The original structure was not a set in the mathematical sense, but a
map - renamed to reflect this.
parent e5f29862
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -4,6 +4,8 @@ set( headers Array.h
             Array_impl.h
             ArrayIO.h
             DynamicTypeTag.h
             IndexedMap.h
             IndexedMap_impl.h
             IndexedSet.h
             IndexedSet_impl.h
             List.h
+82 −0
Original line number Diff line number Diff line
/***************************************************************************
                          IndexedMap.h  -  description
                             -------------------
    begin                : Feb 15, 2014
    copyright            : (C) 2014 by Tomas Oberhuber
    email                : tomas.oberhuber@fjfi.cvut.cz
 ***************************************************************************/

/* See Copyright Notice in tnl/Copyright */

#pragma once

#include <map>
#include <stdexcept>

namespace TNL {
namespace Containers {

template< typename Element,
          typename Index,
          typename Key >
class IndexedMap
{
   public:

   typedef Element   ElementType;
   typedef Index     IndexType;
   typedef Key       KeyType;

   void reset();

   IndexType getSize() const;

   IndexType insert( const ElementType &data );

   bool find( const ElementType &data, IndexType& index ) const;

   template< typename ArrayType >
   void toArray( ArrayType& array ) const;

   const Element& getElement( KeyType key ) const;

   Element& getElement( KeyType key );
 
   void print( std::ostream& str ) const;

   protected:

   struct DataWithIndex
   {
      // This constructor is here only because of bug in g++, we might fix it later.
      // http://stackoverflow.com/questions/22357887/comparing-two-mapiterators-why-does-it-need-the-copy-constructor-of-stdpair
      DataWithIndex(){};
 
      DataWithIndex( const DataWithIndex& d ) : data( d.data ), index( d.index) {}
 
      explicit DataWithIndex( const Element data) : data( data ) {}

      DataWithIndex( const Element data,
                     const Index index) : data(data), index(index) {}

      Element data;
      Index index;
   };

   typedef std::map< Key, DataWithIndex >      STDMapType;
   typedef typename STDMapType::value_type     STDMapValueType;
   typedef typename STDMapType::const_iterator STDMapIteratorType;

   STDMapType map;

};

template< typename Element,
          typename Index,
          typename Key >
std::ostream& operator <<( std::ostream& str, IndexedMap< Element, Index, Key >& set );

} // namespace Containers
} // namespace TNL

#include <TNL/Containers/IndexedMap_impl.h>
+111 −0
Original line number Diff line number Diff line
/***************************************************************************
                          IndexedMap_impl.h  -  description
                             -------------------
    begin                : Feb 15, 2014
    copyright            : (C) 2014 by Tomas Oberhuber
    email                : tomas.oberhuber@fjfi.cvut.cz
 ***************************************************************************/

/* See Copyright Notice in tnl/Copyright */

#pragma once

namespace TNL {
namespace Containers {

template< typename Element,
          typename Index,
          typename Key >
void IndexedMap< Element, Index, Key >::reset()
{
   map.clear();
}

template< typename Element,
          typename Index,
          typename Key >
Index IndexedMap< Element, Index, Key >::getSize() const
{
   return map.size();
}

template< typename Element,
          typename Index,
          typename Key >
Index IndexedMap< Element, Index, Key >::insert( const Element &data )
{
   STDMapIteratorType iter = map.insert( STDMapValueType( Key( data ),
                                         DataWithIndex( data, getSize() ) ) ).first;
   return iter->second.index;
}

template< typename Element,
          typename Index,
          typename Key >
bool IndexedMap< Element, Index, Key >::find( const Element &data, Index& index ) const
{
   STDMapIteratorType iter = map.find( Key( data ) );
   if (iter == map.end())
      return false;
   index = iter->second.index;
   return true;
}

template< typename Element,
          typename Index,
          typename Key >
   template<typename ArrayType>
void IndexedMap< Element, Index, Key >::toArray( ArrayType& array ) const
{
   Assert( array.getSize() == getSize(),
              std::cerr << "array.getSize() = " << array.getSize()
                   << " getSize() = " << getSize() );

   for( STDMapIteratorType iter = map.begin();
        iter != map.end();
        ++iter)
      array[ iter->second.index ] = iter->second.data;
}

template< typename Element,
          typename Index,
          typename Key >
const Element& IndexedMap< Element, Index, Key >::getElement( KeyType key ) const
{
   return map[ key ];
}

template< typename Element,
          typename Index,
          typename Key >
Element& IndexedMap< Element, Index, Key >::getElement( KeyType key )
{
   return map[ key ];
}

template< typename Element,
          typename Index,
          typename Key >
void IndexedMap< Element, Index, Key >::print( std::ostream& str ) const
{
   STDMapIteratorType iter = map.begin();
   str << iter->second.data;
   iter++;
   while( iter != map.end() )
   {
      str << ", " << iter->second.data;
      iter++;
   }
}

template< typename Element,
          typename Index,
          typename Key >
std::ostream& operator<<( std::ostream& str, IndexedMap< Element, Index, Key >& set )
{
   set.print( str );
   return str;
}

} // namespace Containers
} // namespace TNL
+21 −46
Original line number Diff line number Diff line
@@ -11,70 +11,45 @@
#pragma once

#include <map>
#include <stdexcept>
#include <ostream>

namespace TNL {
namespace Containers {

template< typename Element,
          typename Index,
          typename Key >
template< class Key,
          class Index,
          class Compare = std::less< Key >,
          class Allocator = std::allocator< std::pair< const Key, Index > > >
class IndexedSet
{
   public:

   typedef Element   ElementType;
   typedef Index     IndexType;
   typedef Key       KeyType;

   void reset();

   IndexType getSize() const;

   IndexType insert( const ElementType &data );

   bool find( const ElementType &data, IndexType& index ) const;

   template< typename ArrayType >
   void toArray( ArrayType& array ) const;

   const Element& getElement( KeyType key ) const;

   Element& getElement( KeyType key );
 
   void print( std::ostream& str ) const;

protected:
   using map_type = std::map< Key, Index, Compare, Allocator >;
   map_type map;

   struct DataWithIndex
   {
      // This constructor is here only because of bug in g++, we might fix it later.
      // http://stackoverflow.com/questions/22357887/comparing-two-mapiterators-why-does-it-need-the-copy-constructor-of-stdpair
      DataWithIndex(){};
public:
   using key_type = Key;
   using index_type = Index;
   using value_type = typename map_type::value_type;
   using size_type = typename map_type::size_type;

      DataWithIndex( const DataWithIndex& d ) : data( d.data ), index( d.index) {}
   void clear();

      explicit DataWithIndex( const Element data) : data( data ) {}
   size_type size() const;

      DataWithIndex( const Element data,
                     const Index index) : data(data), index(index) {}
   Index insert( const Key& key );

      Element data;
      Index index;
   };
   bool find( const Key& key, Index& index ) const;

   typedef std::map< Key, DataWithIndex >      STDMapType;
   typedef typename STDMapType::value_type     STDMapValueType;
   typedef typename STDMapType::const_iterator STDMapIteratorType;
   size_type count( const Key& key ) const;

   STDMapType map;
   size_type erase( const Key& key );

   void print( std::ostream& str ) const;
};

template< typename Element,
          typename Index,
          typename Key >
std::ostream& operator <<( std::ostream& str, IndexedSet< Element, Index, Key >& set );
          typename Index >
std::ostream& operator <<( std::ostream& str, IndexedSet< Element, Index >& set );

} // namespace Containers
} // namespace TNL
+55 −56
Original line number Diff line number Diff line
@@ -10,85 +10,83 @@

#pragma once

#include <TNL/Containers/IndexedSet.h>

namespace TNL {
namespace Containers {

template< typename Element,
          typename Index,
          typename Key >
void IndexedSet< Element, Index, Key >::reset()
template< class Key,
          class Index,
          class Compare,
          class Allocator >
void
IndexedSet< Key, Index, Compare, Allocator >::clear()
{
   map.clear();
}

template< typename Element,
          typename Index,
          typename Key >
Index IndexedSet< Element, Index, Key >::getSize() const
template< class Key,
          class Index,
          class Compare,
          class Allocator >
typename IndexedSet< Key, Index, Compare, Allocator >::size_type
IndexedSet< Key, Index, Compare, Allocator >::size() const
{
   return map.size();
}

template< typename Element,
          typename Index,
          typename Key >
Index IndexedSet< Element, Index, Key >::insert( const Element &data )
template< class Key,
          class Index,
          class Compare,
          class Allocator >
Index
IndexedSet< Key, Index, Compare, Allocator >::insert( const Key& key )
{
   STDMapIteratorType iter = map.insert( STDMapValueType( Key( data ),
                                         DataWithIndex( data, getSize() ) ) ).first;
   return iter->second.index;
   auto iter = map.insert( value_type( key, size() ) ).first;
   return iter->second;
}

template< typename Element,
          typename Index,
          typename Key >
bool IndexedSet< Element, Index, Key >::find( const Element &data, Index& index ) const
template< class Key,
          class Index,
          class Compare,
          class Allocator >
bool
IndexedSet< Key, Index, Compare, Allocator >::find( const Key& key, Index& index ) const
{
   STDMapIteratorType iter = map.find( Key( data ) );
   auto iter = map.find( Key( key ) );
   if( iter == map.end() )
      return false;
   index = iter->second.index;
   return true;
}

template< typename Element,
          typename Index,
          typename Key >
   template<typename ArrayType>
void IndexedSet< Element, Index, Key >::toArray( ArrayType& array ) const
{
   TNL_ASSERT( array.getSize() == getSize(),
              std::cerr << "array.getSize() = " << array.getSize()
                   << " getSize() = " << getSize() );

   for( STDMapIteratorType iter = map.begin();
        iter != map.end();
        ++iter)
      array[ iter->second.index ] = iter->second.data;
}

template< typename Element,
          typename Index,
          typename Key >
const Element& IndexedSet< Element, Index, Key >::getElement( KeyType key ) const
template< class Key,
          class Index,
          class Compare,
          class Allocator >
typename IndexedSet< Key, Index, Compare, Allocator >::size_type
IndexedSet< Key, Index, Compare, Allocator >::count( const Key& key ) const
{
   return map[ key ];
   return map.count( key );
}

template< typename Element,
          typename Index,
          typename Key >
Element& IndexedSet< Element, Index, Key >::getElement( KeyType key )
template< class Key,
          class Index,
          class Compare,
          class Allocator >
typename IndexedSet< Key, Index, Compare, Allocator >::size_type
IndexedSet< Key, Index, Compare, Allocator >::erase( const Key& key )
{
   return map[ key ];
   return map.erase( key );
}

template< typename Element,
          typename Index,
          typename Key >
void IndexedSet< Element, Index, Key >::print( std::ostream& str ) const
template< class Key,
          class Index,
          class Compare,
          class Allocator >
void IndexedSet< Key, Index, Compare, Allocator >::print( std::ostream& str ) const
{
   STDMapIteratorType iter = map.begin();
   auto iter = map.begin();
   str << iter->second.data;
   iter++;
   while( iter != map.end() )
@@ -98,10 +96,11 @@ void IndexedSet< Element, Index, Key >::print( std::ostream& str ) const
   }
}

template< typename Element,
          typename Index,
          typename Key >
std::ostream& operator<<( std::ostream& str, IndexedSet< Element, Index, Key >& set )
template< class Key,
          class Index,
          class Compare,
          class Allocator >
std::ostream& operator<<( std::ostream& str, IndexedSet< Key, Index, Compare, Allocator >& set )
{
   set.print( str );
   return str;