Loading...
Searching...
No Matches
pair_set.h
Go to the documentation of this file.
#ifndef _RHEOLEF_PAIR_SET_H
#define _RHEOLEF_PAIR_SET_H
//
// This file is part of Rheolef.
//
// Copyright (C) 2000-2009 Pierre Saramito <Pierre.Saramito@imag.fr>
//
// Rheolef is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// Rheolef is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Rheolef; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// =========================================================================
// same as index_set, but with a pair<size_t,T> instead of a size_t
// wrapper around map<size_t,T> with goodies such as union as a+b
//
// motivation: this class is useful for disarray<pair_set,M>
// to send/receive variable-sized lists via MPI correctly
// disarray<pair_set,M> is used by the asr class
// send & receive of such lists are used to assembly a global matrix locally
// when computing the csr*csr product
//
// author: Pierre.Saramito@imag.fr
//
// date: 19 mai 2012
//
#include "rheolef/communicator.h"
#include "rheolef/pretty_name.h"
#include "rheolef/msg_util.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wparentheses"
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#ifdef _RHEOLEF_HAVE_MPI
#include "rheolef/mpi_pair_datatype.h"
#endif // _RHEOLEF_HAVE_MPI
#include <boost/serialization/map.hpp>
#include <boost/serialization/base_object.hpp>
#pragma GCC diagnostic pop
namespace rheolef {
/*Class:
NAME: pair_set - a set of (index,value) pair (@PACKAGE@-@VERSION@)
SYNOPSIS:
A class for: l = @{(0,3.3),...(7,8.2)@} i.e. a wrapper for STL @code{map<size_t,T>} with
some assignment operators, such as l1 += l2.
This class is suitable for use with the @code{disarray<T>} class,
as @code{disarray<pair_set>} (@pxref{disarray class}).
TODO:
template <T,A> with A=std::allocator or heap_allocator
difficulty: get heap_allocator<T> or std::allocator<T> and then requires
heap_allocator<pair<size_t,T>> or std::allocator<>pair<size_t,T>>
for std::map
AUTHOR: Pierre.Saramito@imag.fr
DATE: date: 19 may 2012
End:
*/
//<verbatim:
template<class T, class A = std::allocator<std::pair<std::size_t,T> > >
class pair_set: public std::map<std::size_t, T, std::less<std::size_t> > {
// TODO: use A extra-arg for std::map for heap_allocator
public:
// typedefs:
typedef std::size_t size_type;
typedef std::pair<size_type,T> pair_type;
typedef std::pair<const size_type,T> const_pair_type;
typedef pair_type value_type;
typedef std::map<size_type, T, std::less<size_type> > // TODO: use allocator_type for heap_allocator
base;
#ifdef TODO
typedef typename base::allocator_type allocator_type;
#endif // TODO
typedef A allocator_type;
typedef typename base::iterator iterator;
typedef typename base::const_iterator const_iterator;
// allocators:
pair_set (const A& alloc = A());
pair_set (const pair_set<T,A>& x, const A& alloc = A());
pair_set<T,A>& operator= (const pair_set<T,A>& x);
void clear ();
// basic algebra: semantic of a sparse vector
pair_set<T,A>& operator+= (const pair_type& x); // c := a union {x}
template<class B>
pair_set<T,A>& operator+= (const pair_set<T,B>& b); // c := a union b
// boost mpi:
template <class Archive>
void serialize (Archive& ar, const unsigned int version);
};
// io:
template <class T, class A>
std::istream& operator>> (std::istream& is, pair_set<T,A>& a);
template <class T, class A>
std::ostream& operator<< (std::ostream& os, const pair_set<T,A>& b);
//>verbatim:
namespace details {
// for boost mpi and disarray<pair_set>:
template <class T, class A>
struct default_set_op_traits<pair_set<T,A> > {
using type = details::generic_set_plus_op;
};
template <class T, class A>
struct is_container<pair_set<T,A> > : std::true_type {
typedef std::true_type type;
};
#ifdef _RHEOLEF_HAVE_MPI
// convert boost::mpl::false_ and true_ to std::false_type and true_type...
template <class T, class A>
struct is_container_of_mpi_datatype<pair_set<T,A> >
: std::conditional<
boost::mpi::is_mpi_datatype<T>::value
,std::true_type
,std::false_type
>::type
{
typedef
typename std::conditional<
boost::mpi::is_mpi_datatype<T>::value
,std::true_type
,std::false_type>
::type
type;
};
#endif // _RHEOLEF_HAVE_MPI
} // namespace details
// -------------------------------------------------------------------
// inlined
// -------------------------------------------------------------------
template <class T, class A>
inline
pair_set<T,A>::pair_set (const A& alloc)
: base (std::less<size_type>()) // TODO: use alloc extra-arg for base=std::map for heap_allocator
{
}
template <class T, class A>
inline
void
pair_set<T,A>::clear ()
{
base::clear();
}
template <class T, class A>
inline
pair_set<T,A>&
pair_set<T,A>::operator+= (const pair_type& x)
{
iterator p = base::find(x.first);
if (p == base::end()) {
// insert a new element
base::insert (x);
} else {
// increment an existing element
(*p).second += x.second;
}
return *this;
}
template <class T, class A>
template <class Archive>
void
pair_set<T,A>::serialize (Archive& ar, const unsigned int version)
{
ar & boost::serialization::base_object<base>(*this);
}
// -------------------------------------------------------------------
// not inlined
// -------------------------------------------------------------------
template <class T, class A>
pair_set<T,A>::pair_set (const pair_set& a, const A& alloc)
: base(std::less<size_type>()) // TODO: use a.get_allocator() extra-arg for base=std::map for heap_allocator
{
for (const_iterator iter = a.base::begin(), last = a.base::end(); iter != last; iter++) {
base::insert (*iter);
}
}
template <class T, class A>
pair_set<T,A>&
pair_set<T,A>::operator= (const pair_set<T,A>& a)
{
base::clear();
for (const_iterator iter = a.base::begin(), last = a.base::end(); iter != last; iter++) {
base::insert (*iter);
}
return *this;
}
template <class T, class A>
template <class B>
pair_set<T,A>&
pair_set<T,A>::operator+= (const pair_set<T,B>& b)
{
for (typename pair_set<T,B>::const_iterator iter = b.begin(), last = b.end(); iter != last; iter++) {
operator+= (*iter);
}
return *this;
}
template <class T, class A>
std::istream&
operator>> (std::istream& is, pair_set<T,A>& a)
{
typedef typename pair_set<T,A>::size_type size_type;
typedef typename pair_set<T,A>::pair_type pair_type;
size_type n;
is >> n;
a.clear();
for (size_type i = 0; i < n; i++) {
pair_type xi;
is >> xi.first >> xi.second;
a.insert (xi);
}
return is;
}
template <class T, class A>
std::ostream&
operator<< (std::ostream& os, const pair_set<T,A>& a)
{
typedef typename pair_set<T,A>::size_type size_type;
typedef typename pair_set<T,A>::const_iterator const_iterator;
os << a.size() << "\t";
for (const_iterator iter = a.begin(), last = a.end(); iter != last; iter++) {
os << " " << (*iter).first << " " << (*iter).second;
}
return os;
}
} // namespace rheolef
#endif // _RHEOLEF_PAIR_SET_H
rheolef::pair_set
Definition pair_set.h:72
rheolef::pair_set::pair_set
pair_set(const pair_set< T, A > &x, const A &alloc=A())
rheolef::pair_set< T, A >::base
std::map< size_type, T, std::less< size_type > > base
Definition pair_set.h:83
rheolef::pair_set< T, A >::value_type
pair_type value_type
Definition pair_set.h:81
rheolef::pair_set< T, A >::iterator
base::iterator iterator
Definition pair_set.h:88
rheolef::pair_set::pair_set
pair_set(const A &alloc=A())
Definition pair_set.h:151
rheolef::pair_set::operator+=
pair_set< T, A > & operator+=(const pair_type &x)
Definition pair_set.h:165
rheolef::pair_set< T, A >::const_pair_type
std::pair< const size_type, T > const_pair_type
Definition pair_set.h:80
rheolef::pair_set::serialize
void serialize(Archive &ar, const unsigned int version)
Definition pair_set.h:180
rheolef::pair_set< T, A >::pair_type
std::pair< size_type, T > pair_type
Definition pair_set.h:79
rheolef::pair_set< T, A >::size_type
std::size_t size_type
Definition pair_set.h:78
rheolef::pair_set< T, A >::const_iterator
base::const_iterator const_iterator
Definition pair_set.h:89
rheolef::pair_set::operator=
pair_set< T, A > & operator=(const pair_set< T, A > &x)
Definition pair_set.h:197
rheolef::pair_set::clear
void clear()
Definition pair_set.h:158
rheolef::pair_set< T, A >::allocator_type
base::allocator_type allocator_type
Definition pair_set.h:85
T
Expr1::float_type T
Definition field_expr.h:230
rheolef::details
Definition compiler_eigen.h:39
rheolef
This file is part of Rheolef.
Definition compiler_eigen.h:39
rheolef::operator<<
std::ostream & operator<<(std::ostream &os, const catchmark &m)
Definition catchmark.h:99
rheolef::operator+=
std::enable_if< details::is_rheolef_arithmetic< U >::value, ad3_basic< T > & >::type operator+=(ad3_basic< T > &a, const U &b)
Definition ad3.h:286
rheolef::operator>>
std::istream & operator>>(std::istream &is, const catchmark &m)
Definition catchmark.h:88
std
STL namespace.
A
Definition diffusion_isotropic.h:25
p
Definition sphere.icc:25
rheolef::const_iterator
Definition field_expr_recursive.h:593
rheolef::details::default_set_op_traits< pair_set< T, A > >::type
details::generic_set_plus_op type
Definition pair_set.h:120
rheolef::details::is_container< pair_set< T, A > >::type
std::true_type type
Definition pair_set.h:124
rheolef::details::is_container_of_mpi_datatype< pair_set< T, A > >::type
std::conditional< boost::mpi::is_mpi_datatype< T >::value, std::true_type, std::false_type >::type type
Definition pair_set.h:142
rheolef::details::is_container_of_mpi_datatype
Definition msg_util.h:240
rheolef::details::is_container
Definition msg_util.h:235