Elm  2
ELM is a library providing generic data structures, OS-independent interface, plugins and XML.
Data Structures

Classes

class  GenTree< T, K, C, A >
 
class  Set< T, C >
 
class  Map< K, T, C, E, A >
 
class  Queue< T, C, A >
 
class  StrictMapDelegate< C >
 
class  EquivManager< T, E, A >
 
class  CompareManager< T, C, E, A >
 
class  HashManager< K, H, A >
 
class  ArrayDelegate< C, I, T >
 
class  MapDelegate< C, I, T, D >
 
class  Bag< T >
 
class  Slice< C >
 
class  Array< T >
 
class  AllocArray< T >
 
class  BiDiList< T, E, A >
 
class  BinomialQueue< T, C, A >
 
class  FragTable< T, E, A >
 
class  HashTable< T, H, A >
 
class  HashMap< K, T, H, A, E >
 
class  HashSet< T, H, A >
 
class  List< T, E, A >
 
class  ListQueue< T, M >
 
class  class
 
class  SortedList< T, C, A >
 
class  ListSet< T, C, A >
 
class  ListMapManager
 
class  ListMap< K, T, C, E, A >
 
class  StaticStack< T, N >
 
class  Vector< T, E, A >
 
class  PreIterator< I, T >
 
class  InplacePreIterator< I, T >
 
class  PreIter< I, T >
 
class  ConstPreIter< I, T >
 
class  MutPreIter< I, T >
 

Functions

template<class A , class C = Comparator<typename A::t>>
void quicksort (A &array, const C &c=Comparator< typename A::t >())
 
template<class C , class P >
int count (const C &c, const P &p)
 
template<class C , class P >
bool forall (const C &c, const P &p)
 
template<class C , class P >
bool exists (const C &c, const P &p)
 
template<class C , class F , class D >
void map (const C &c, const F &f, D &d)
 
template<class C , class F >
void iter (const C &c, const F &f)
 
template<class C >
C::t sum (const C &c)
 
template<class C >
C::t product (const C &c)
 
template<class C >
void fill (C &c, int n, const typename C::t v=type_info< typename C::t >::null)
 
template<class C1 , class C2 >
bool equals (const C1 &c1, const C2 &c2)
 
template<class C1 , class C2 >
Pair< typename C1::Iter, typename C2::Iter > mismatch (const C1 &c1, const C2 &c2)
 
template<class C >
void deleteAll (const C &c)
 
template<class C1 , class C2 , class P >
Pair< typename C1::Iter, typename C2::Iter > mismatch (const C1 &c1, const C2 &c2, P p)
 
template<class T >
Array< T > _array (int n, T t[])
 
template<class I >
Range< I > range (const I &begin, const I &end)
 

Detailed Description

Principles
This module groups together classes implementing storage data structure. It is new in ELM 2.0 and try to extend and to make easier the use of classes from the old Old Data Structures module. The main differences includes:
  • shorter names for classes and for iterators,
  • included in the main elm name space,
  • more STL compliance,
  • more operators overloading,
  • versatile system for configuration (comparator, allocator, etc).
In addition, their documentation includes several topic allowing a better understanding of their work to help choosing the better data structure:
  • complexity (average and worst) of basic operations like add and remove,
  • basic memory and element relative memory foot print.
As for old data structures, the following topics applies:
  • concepts implemented by the data structure are provided,
  • a data structure must not be modified while an iterator is active on it unless specific methods are provided.
Selecting a data structure

This sections aims to help a developer to select a data structure fittings his needs. They are sorted according to different criteria: the right data structure to use is the one matching most of them. The criteria includes access type, collection size, etc.

Collection size:

Access type:

Modification type:

Memory footprint:

The array below sum up the complexity of operations for the data structures described above. When 2 complexity are give o1/o2, o1 is the average case and o2 the worst case.

For simple collections, we get:

Data Structure adding lookup insertion removal
Vector O(1) O(n) O(n) O(n)
List O(1) O(n) O(1) O(1)
BiDiList O(1) O(n) O(1) O(1)
ListBag O(log(n))/O(n) O(log(n))/O(n) O(1) O(1)
FragTable O(1) O(n) O(n) O(n)
HashTable O(b) O(b) O(1) O(1)
HashSet O(b) O(b) O(1) O(1)
avl::Tree O(log(n)) O(log(n)) O(1) O(log(n))
avl::Set O(log(n)) O(log(n)) O(1) O(log(n))

Map operations:

Data Structure lookup insertion removal
HashMap O(b) O(b) O(b)
avl::Map O(log(n)) O(log(n)) O(log(n))
TreeMap O(log(n))/O(n) O(log(n))/O(n) O(log(n))/O(n)
ListMap O(n) O(n) O(n)

Random access to array elements:

Data Structure Indexed Access
Array O(1)
FragTable O(1)
Vector O(1)
List O(n)
BiDiList O(n)

Stack (LIFO) operations:

Data Structure push pop
Vector O(1) O(1)
List O(1) O(1)
BiDiList O(1) O(1)
FragTable O(1) O(1)

Queue (FIFO) operations:

Data Structure put get
Vector O(n) O(1)
List O(1) O(n)
BiDiList O(1) O(1)
FragTable O(n) O(1)
VectorQueue O(1) O(1)
ListQueue O(1) O(1)
BinomialQueue O(1) O(log(n))

Set operations:

Data Structure join meet difference
HashSet O(bn) O(bn) O(bn)
avl::Set O(n) O(n) O(n)
BitVector O(n) O(n) O(n)

Priority queues:

Data Structure put get
BinomialQueue O(1) O(log(n))
SortedList O(n) O(1)
Iterator Helper Classes
#include <elm/PreIterator.h>

Basically, the PreIterator function avoids rewriting the large number of operator overloading. In fact, only the constructor and 3 functions need to be written:

Therefore, an iterator must be written as below (with T the type of iterated items):

class MyIter: public PreIterator<MyIter, T> {
public:
MyIter(...) { ... };
inline bool ended(void) const { return ...; }
inline const T& item(void) const { return ...; }
inline void next(void) { ... }
inline bool equals(const MyIter& i) { ... }
private:
...
};

And the use of such an iterator becomes:

for(MyIter i(...); i(); ++i)
use(*i);

Notices that if T is a pointer, the arrow iterator may be used without a star:

for(MyIter i(...); i(); ++i)
use(i->to_something);

Likely, PreIterator provides automatic conversion to T:

for(MyIter i(...); i(); ++i) {
T v = i;
...
}

Beside, PreIterator provides also a way to use iterators as in the STL. You have to provide a equals() function to test for equality:

class MyIter: public PreIterator<MyIter, T> {
public:
MyIter(...) { ... };
inline bool ended(void) const { return ...; }
inline const T& item(void) const { return ...; }
inline void next(void) { ... }
inline bool compare(const MyIter& i) { return ...; }
private:
...
};

And now the iteration can be written (with begin() the function returning the initial iterator and end() the end iterator):

for(auto i = begin(); i != end(); ++i)
use(*i);

A very fast and intuitive way to perform iteration on a collection of items proposed by C++ 11 requires a couple of begin() and end() functions declared in a collection object coll:

for(auto i: coll)
use(i);

Notice that i is of type T, the type of iterated elements. As this is very convenient, all ELM data classes provide begin() and end() functions.

The following classes may help to work or to extend the concrete data structures:

Helper functions

<elm/data/quicksort.h> provides a quicksort implementation for data collections:

Other functions provides very generic processing over the collection. They generically takes as parameter a collection, a class providing some specific computation and comes in two flavors, with or without an additional argument. To use them, one has to include <elm/data/util.h>:

Other functions provides specialized iterators:

Other functions and classes are provided for easier combination:

Delegate Classes

Delegate class in ELM allows to get references on value managed by specific class functions to ensure their access or their assignment.

They support the same operations as the C++ references:

The following delegates exists:

Customizing the work

Common customization of container classes includes the memory allocation, the element comparison or hashing.

Basically, the customization can be declared static and passed to the container using class templates:

class MyComparator { ... };
AContainer<int, MyComparator> container;

In this case, the memory cost for such a customization is zero.

If the customization requires an instance, the instance has to be passed also to the constructor of the container. In this case, the container inherits from the customization class and this one must support a copy constructor where is passed the instance:

class MyComparator {
public:
MyComparator(const MyComparator& i) { ... }
};
MyComparator my_comparator_instance;
AContainer<int, MyComparator> container(my_comprator);

In this case, the container size grows according to the size of the instance customization class.

To support this behavior, delegate classes may help:. For instance, DefaultAllocator class provides access to OS allocation but it is passed by default to container as DefaultAllocatorDelegate that just propagate allocation to the default allocator.

The following delegate classes exist:

Function Documentation

◆ _array()

Array< T > _array ( int  n,
t[] 
)
inline

#include <include/elm/data/Array.h>

Short way to build an Array of type T.

Parameters
nArray element count.
tArray element buffer.
See also
Array

◆ count()

int count ( const C &  c,
const P &  p 
)
inline

#include <include/elm/data/util.h>

Count the number of elements of c that matches the predicate p.

Parameters
cCollection to count in (must implement concept::Collection).
pPredicate to test element (must implement concept::Predicate).

References elm::io::p().

Referenced by Tree::count(), JobScheduler::setThreadCount(), and InstanceType::typeFor().

◆ deleteAll()

void deleteAll ( const C &  c)
inline

#include <include/elm/data/util.h>

Consider that c is a collection of pointers and call the deletion on each of these pointers.

Parameters
cCollection of pointers to delete.
CType of collection.

◆ equals()

bool equals ( const C1 &  c1,
const C2 &  c2 
)
inline

#include <include/elm/data/util.h>

Test if two collections are equals.

Parameters
c1First collection.
c2Second collection.
Returns
True if both collection are equal, false else.
Parameters
C1Type of first collection.
C2Type of second collection.

Referenced by VectorQueue< elm::Pair >::contains(), ArrayList< T, E >::contains(), AssocEquiv< K, T, E >::equals(), Vector< elm::dtd::AbstractAttribute * >::equals(), ArrayList< T, E >::find(), Vector< elm::dtd::AbstractAttribute * >::find(), ArrayList< T, E >::indexOf(), EqualsEquiv< T >::isEqual(), HashKey< T * >::isEqual(), HashKey< const T * >::isEqual(), ArrayList< T, E >::lastIndexOf(), and ArrayList< T, E >::remove().

◆ exists()

bool exists ( const C &  c,
const P &  p 
)
inline

#include <include/elm/data/util.h>

Test if the predicate p is true at least for one element of c.

Parameters
cCollection to test (must implement concept::Collection).
pPredicate to evaluate (must implement concept::Predicate).
Returns
True if at least one element is true for predicate p.

References elm::io::p().

◆ fill()

void fill ( C &  c,
int  n,
const typename C::t  v = type_info<typename C::t>::null 
)
inline

#include <include/elm/data/util.h>

Add n items of value v to to the collection c.

Parameters
cCollection add values to.
nNumber of values to add.
vValue to add (as a default, the null value).

Referenced by WAHVector::clear(), builder::fix(), builder::pushLite(), WAHVector::set(), and WAHVector::WAHVector().

◆ forall()

bool forall ( const C &  c,
const P &  p 
)
inline

#include <include/elm/data/util.h>

Test if the predicate p is true for each element of c.

Parameters
cCollection to test (must implement concept::Collection).
pPredicate to evaluate (must implement concept::Predicate).
Returns
True if the predicate p is true for all element of c.

References elm::io::p().

◆ iter()

◆ map()

void map ( const C &  c,
const F &  f,
D &  d 
)
inline

#include <include/elm/data/util.h>

Map the elements of a collection to element of another collection using the function f.

Parameters
cOriginal collection (must implement concept::Collection).
fTransforming function (must implement concept::Function).
dFilled collection (must implement concept::MutableCollection).

Referenced by Map< Pair< K, K >, T, segment_comparator_t >::copy(), Map< Pair< K, K >, T, segment_comparator_t >::equals(), Map< Pair< K, K >, T, segment_comparator_t >::operator!=(), Map< Pair< K, K >, T, segment_comparator_t >::operator=(), and Map< Pair< K, K >, T, segment_comparator_t >::operator==().

◆ mismatch() [1/2]

Pair< typename C1::Iter, typename C2::Iter > mismatch ( const C1 &  c1,
const C2 &  c2 
)

#include <include/elm/data/util.h>

Find the point of difference of two collection. Starting from the first element of the two collections, progress until either finding the end of a collection, or until the first different element of the collections.

Parameters
c1First collection.
c2Second collection.
Returns
Pair of iterators to the difference point (if any).
Parameters
C1Type of first collection.
C2Type of second collection.

References elm::pair().

◆ mismatch() [2/2]

Pair< typename C1::Iter, typename C2::Iter > mismatch ( const C1 &  c1,
const C2 &  c2,
p 
)

#include <include/elm/data/util.h>

Find the point of difference of two collection. Starting from the first element of the two collections, progress until either finding the end of a collection, or until the first different element of the collections. To test if two elements matches or not, the function p is used.

Parameters
c1First collection.
c2Second collection.
pMatch predicate to decide if two elements are different. Must support the call p(element1, element2).
Returns
Pair of iterators to the difference point (if any).
Parameters
C1Type of first collection.
C2Type of second collection.
PType of predicate.

References elm::io::p(), and elm::pair().

◆ product()

typename C::t product ( const C &  c)
inline

#include <include/elm/data/util.h>

Perform the product of the items of collection c. An implementation of operator '*' must exist for these items.

Parameters
cCollection to multiply together.
Returns
Result of item product.

References elm::fold(), and elm::io::p().

◆ quicksort()

void quicksort ( A &  array,
const C &  c = Comparator<typename A::t>() 
)

#include <include/elm/data/quicksort.h>

s

Sort the given array using quicksort algorithm (average complexity O(N log(N)) ).

Parameters
arrayArray containing the values to sort.
cComparator to use (rely on ELM default comparator if not provided).
TType of values.
AType of array (must implement Array concept).
CType of comparator (must implement Comparator or Compare concept).

References elm::max(), and elm::swap().

◆ range()

Range< I > range ( const I &  begin,
const I &  end 
)

#include <include/elm/data/Range.h>

Creates a range from the iterator b to iterator e.

Parameters
bFirst position of the range (inclusive).
eOne position after the last position of the range (exclusive).
Returns
Range from b to e.

Fast way to build a range.

Parameters
beginIterator on the first element of the collection.
endEnd iterator past the last element of the collection (may be ended).
Returns
Built range.
See also
Range

Referenced by Plugger::available(), and elm::select().

◆ sum()

typename C::t sum ( const C &  c)
inline

#include <include/elm/data/util.h>

Perform the sum of the items of collection c. An implementation of operator '+' must exist for these items.

Parameters
cCollection to sum up.
Returns
Result of item sum.

References elm::fold().

elm::equals
bool equals(const C1 &c1, const C2 &c2)
Definition: util.h:107