pbori_func.h
Go to the documentation of this file.
// -*- c++ -*-
//*****************************************************************************
//*****************************************************************************
#ifndef polybori_routines_pbori_func_h_
#define polybori_routines_pbori_func_h_
// get polybori definitions
#include <polybori/pbori_defs.h>
// get polybori properties
#include <polybori/common/traits.h>
// get standard string and string stream functionality
#include <string>
#include <sstream>
#ifdef PBORI_HAVE_TR1_UNORDERED_MAP
# include <tr1/unordered_map>
#else
# ifdef PBORI_HAVE_UNORDERED_MAP
# include <unordered_map>
# else
# ifdef PBORI_HAVE_HASH_MAP
# include <ext/hash_map>
# else
# include <map>
# endif
# endif
#endif
BEGIN_NAMESPACE_PBORI
template <class ListType, class ValueType = typename ListType::value_type >
class push_back {
public:
ListType
operator()(ListType theList, const ValueType& elt) const {
theList.push_back(elt);
return theList;
}
};
template <class RhsType, class LhsType = typename RhsType::idx_type >
class change_idx {
public:
RhsType operator() (const RhsType& rhs, const LhsType& lhs) const {
return (rhs.change(lhs));
}
};
template <class RhsType = void,
class LhsType = typename pbori_traits<RhsType>::idx_type >
class change_assign;
// default variant
template <class RhsType, class LhsType>
class change_assign {
public:
RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
return (rhs = rhs.change(lhs));
}
};
// template specialization
template<>
class change_assign<void, pbori_traits<void>::idx_type> {
public:
template <class RhsType, class LhsType>
RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
return (rhs = rhs.change(lhs));
}
};
template <class RhsType, class LhsType = typename RhsType::idx_type>
class subset1_assign {
public:
RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
rhs = rhs.subset1(lhs);
return rhs;
}
};
template <class RhsType, class LhsType>
class subset0_assign {
public:
RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
return (rhs = rhs.subset0(lhs));
}
};
template <class RhsType,
class LhsType = typename pbori_traits<RhsType>::idx_type >
class unite_assign:
public std::binary_function<RhsType&, const LhsType&, RhsType&> {
public:
RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
return (rhs = rhs.unite(lhs));
}
};
// @class project_ith
template <unsigned int ITH, unsigned int NLEN = ITH>
class project_ith;
template <unsigned int NLEN>
class project_ith<0, NLEN> {
public:
template <class ValueType>
void operator() (const ValueType&, ...) const { }
};
template <unsigned int NLEN>
class project_ith<1, NLEN> {
public:
template <class ValueType>
const ValueType& operator() (const ValueType& value, ...) const {
return value;
}
template <class ValueType>
ValueType& operator() (ValueType& value, ...) const {
return value;
}
};
template <unsigned int NLEN>
class project_ith<2, NLEN> {
public:
template <class FirstType, class ValueType>
const ValueType&
operator() (const FirstType&, const ValueType& value, ...) const {
return value;
}
template <class FirstType, class ValueType>
ValueType& operator() (const FirstType&, ValueType& value, ...) const {
return value;
}
};
template <unsigned int NLEN>
class project_ith<3, NLEN> {
public:
template <class FirstType, class SecondType, class ValueType>
const ValueType&
operator() (const FirstType&, const SecondType&,
const ValueType& value, ...) const {
return value;
}
template <class FirstType, class SecondType, class ValueType>
ValueType& operator() (const FirstType&, const SecondType&,
ValueType& value, ...) const {
return value;
}
};
/*
class print_all {
public:
print_all(std::ostream& os_):os(os_){}
template<class Type>
Type& operator()(Type& val){
std::copy(val.begin(), val.end(),
std::ostream_iterator<typename Type::value_type>(os, ", "));
return val;
}
std::ostream& os;
};
*/
class dummy_iterator {
public:
typedef dummy_iterator self;
template <class Type>
const self& operator=(const Type&) const { return *this;}
const self& operator*() const { return *this;}
const self& operator++() const { return *this;}
const self& operator++(int) const { return *this;}
};
template <>
class pbori_traits<dummy_iterator>:
public CTypes {
};
template <class IntType, IntType INTCONST, class ResultType = IntType>
struct integral_constant {
typedef ResultType result_type;
enum { result = INTCONST };
result_type operator()(...) const { return result; }
};
template <class BinaryOp, class FirstOp, class SecondOp>
class binary_composition:
public BinaryOp {
public:
typedef BinaryOp base;
typedef FirstOp first_op_type;
typedef SecondOp second_op_type;
// Constructor
binary_composition(const base& binop = base(),
const first_op_type& unop1 = first_op_type(),
const second_op_type& unop2 = second_op_type() ):
base(binop), first_op(unop1), second_op(unop2) {}
typedef typename base::result_type result_type;
template <class FirstType, class SecondType>
result_type operator()(const FirstType& first,
const SecondType& second) const {
return base::operator()(first_op(first), second_op(second));
}
template <class FirstType, class SecondType>
result_type operator()(FirstType& first,
const SecondType& second) const {
return base::operator()(first_op(first), second_op(second));
}
template <class FirstType, class SecondType>
result_type operator()(const FirstType& first,
SecondType& second) const {
return base::operator()(first_op(first), second_op(second));
}
protected:
first_op_type first_op;
second_op_type second_op;
};
template <class BinaryOp, class UnaryOperation>
class symmetric_composition:
public binary_composition<BinaryOp, UnaryOperation, UnaryOperation> {
public:
typedef BinaryOp binary_op_type;
typedef UnaryOperation unary_op_type;
typedef binary_composition<binary_op_type, unary_op_type, unary_op_type>
base;
// Constructor
symmetric_composition(const binary_op_type& binop = binary_op_type(),
const unary_op_type& unop = unary_op_type() ):
base(binop, unop, unop) {}
};
template<class ValueType>
class maximum_iteration {
public:
maximum_iteration(ValueType & init) : max(init){}
ValueType& operator()(const ValueType& val) const {
return max = std::max(max, val);
}
private:
ValueType & max;
};
template <class DDType>
class dd_add_assign {
public:
DDType& operator()(DDType& lhs, const DDType& rhs) const {
// several possible implementations
return
#if defined(PBORI_ADD_BY_OR)
(lhs = (lhs.diff(rhs)).unite(rhs.diff(lhs)));
# elif defined(PBORI_ADD_BY_UNION)
(lhs = lhs.unite(rhs).diff( lhs.intersect(rhs) ) );
# elif defined(PBORI_ADD_BY_EXTRA_XOR) || defined(PBORI_ADD_BY_XOR)
(lhs = lhs.Xor(rhs));
#endif
}
};
template <class DDType, class IdxType = typename DDType::idx_type>
class times_indexed_var {
public:
DDType& operator()(DDType& lhs, IdxType idx) const {
// get all terms not containing the variable with index idx
DDType tmp( lhs.subset0(idx) );
// get the complementary terms
lhs = lhs.diff(tmp);
// construct polynomial terms
dd_add_assign<DDType>()(lhs, tmp.change(idx));
return lhs;
}
};
template <class DDType, class IdxType = typename DDType::idx_type>
class append_indexed_divisor {
public:
DDType& operator()(DDType& lhs, IdxType idx) const {
lhs = lhs.unite( lhs.change(idx) );
return lhs;
}
};
// template <class RhsType = void,
// class LhsType = typename RhsType::value_type >
// class inserts:
// public std::binary_function<RhsType&, const LhsType&, RhsType&> {
// public:
// RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
// rhs.insert(lhs);
// return rhs;
// }
// };
template <class RhsType = void,
class LhsType = typename pbori_traits<RhsType>::idx_type >
class inserts;
template <class RhsType, class LhsType>
class inserts:
public std::binary_function<RhsType&, const LhsType&, RhsType&> {
public:
RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
rhs.insert(lhs);
return rhs;
}
};
template <>
class inserts<void, pbori_traits<void>::idx_type> {
public:
template <class RhsType, class LhsType>
RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
rhs.insert(lhs);
return rhs;
}
};
template <class RhsType = void,
class LhsType = typename pbori_traits<RhsType>::idx_type >
class insert_assign;
template <class RhsType, class LhsType>
class insert_assign:
public std::binary_function<RhsType&, const LhsType&, RhsType&> {
public:
RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
rhs.insertAssign(lhs);
return rhs;
}
};
template <>
class insert_assign<void, pbori_traits<void>::idx_type> {
public:
template <class RhsType, class LhsType>
RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
rhs.insertAssign(lhs);
return rhs;
}
};
template <class RhsType = void,
class LhsType = typename pbori_traits<RhsType>::idx_type >
class removes;
template <class RhsType, class LhsType>
class removes:
public std::binary_function<RhsType&, const LhsType&, RhsType&> {
public:
RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
rhs.remove(lhs);
return rhs;
}
};
template <>
class removes<void, pbori_traits<void>::idx_type> {
public:
template <class RhsType, class LhsType>
RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
rhs.remove(lhs);
return rhs;
}
};
template <class RhsType = void,
class LhsType = typename pbori_traits<RhsType>::idx_type >
class remove_assign;
template <class RhsType, class LhsType>
class remove_assign:
public std::binary_function<RhsType&, const LhsType&, RhsType&> {
public:
RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
rhs.removeAssign(lhs);
return rhs;
}
};
template <>
class remove_assign<void, pbori_traits<void>::idx_type> {
public:
template <class RhsType, class LhsType>
RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
rhs.removeAssign(lhs);
return rhs;
}
};
template <class ListType, class RhsType, class LhsType>
class insert_second_to_list {
public:
insert_second_to_list(ListType& theList__):
theList(theList__) {};
RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
theList.insert(lhs);
return rhs;
}
private:
ListType& theList;
};
template <class Type1, class Type2>
class is_same_type;
template <class Type>
class is_same_type<Type, Type>:
public integral_constant<CTypes::bool_type, true> {};
template <class Type1, class Type2>
class is_same_type:
public integral_constant<CTypes::bool_type, false> {};
template <class Type>
class is_valid:
public is_same_type<Type, valid_tag> {};
template <class Type1, class Type2, class ThenType, class ElseType>
class on_same_type;
template <class Type, class ThenType, class ElseType>
class on_same_type<Type, Type, ThenType, ElseType> {
public:
typedef ThenType type;
};
template <class Type1, class Type2, class ThenType, class ElseType>
class on_same_type {
public:
typedef ElseType type;
};
struct internal_tag {};
template<class Type>
struct type_tag {};
template <class Type>
class hashes {
public:
typedef typename Type::hash_type hash_type;
hash_type operator() (const Type& rhs) const{
return rhs.hash();
}
};
template <class Type>
class generate_index_map {
typedef typename Type::idx_type idx_type;
public:
#ifdef PBORI_HAVE_TR1_UNORDERED_MAP
typedef std::tr1::unordered_map<Type, idx_type, hashes<Type> > type;
#else
# ifdef PBORI_HAVE_UNORDERED_MAP
typedef std::unordered_map<Type, idx_type, hashes<Type> > type;
# else
# ifdef PBORI_HAVE_HASH_MAP
typedef __gnu_cxx::hash_map<Type, idx_type, hashes<Type> > type;
# else
typedef std::map<Type, idx_type> type;
# endif
# endif
#endif
};
template <class ListType>
class sizes_less:
public std::binary_function<const ListType&, const ListType&, bool> {
public:
bool operator()(const ListType& lhs, const ListType& rhs) const {
return (lhs.size() < rhs.size());
}
};
template <class BiIterator>
class reversed_iteration_adaptor {
public:
typedef BiIterator iterator;
typedef reversed_iteration_adaptor<iterator> self;
typedef std::bidirectional_iterator_tag iterator_category;
typedef typename std::iterator_traits<iterator>::difference_type
difference_type;
typedef typename std::iterator_traits<iterator>::pointer pointer;
typedef typename std::iterator_traits<iterator>::reference reference;
typedef typename std::iterator_traits<iterator>::value_type value_type;
reversed_iteration_adaptor(const iterator& iter):
m_iter(iter) {}
reference operator*() const {
return *m_iter;
}
self& operator++() {
--m_iter;
return *this;
}
self& operator--() {
++m_iter;
return *this;
}
bool operator==(const self& rhs) const {
return m_iter == rhs.m_iter;
}
bool operator!=(const self& rhs) const {
return m_iter != rhs.m_iter;
}
iterator get() const {
return m_iter;
}
protected:
iterator m_iter;
};
template <class DDType>
class navigates:
public std::unary_function<DDType, typename DDType::navigator> {
public:
typedef DDType dd_type;
typedef typename DDType::navigator navigator;
typedef std::unary_function<dd_type, navigator> base;
typename base::result_type operator()(const dd_type& rhs) const{
return rhs.navigation();
}
};
template <class ValueType>
class default_value {
public:
typedef ValueType value_type;
value_type operator()(...) const{
return value_type();
}
};
template <template<class> class BindType, class BinaryFunction,
class ValueType, class ConstantOp>
class constant_binder_base :
public BindType<BinaryFunction>{
public:
typedef BinaryFunction bin_op;
typedef ConstantOp const_type;
typedef BindType<bin_op> base;
typedef ValueType value_type;
constant_binder_base(const bin_op& op = bin_op()): base(op, const_type()()) {}
};
template <class BinaryFunction, class ConstantOp>
class constant_binder2nd :
public constant_binder_base<std::binder2nd, BinaryFunction,
typename BinaryFunction::second_argument_type,
ConstantOp> {
};
template <class BinaryFunction, class ConstantOp>
class constant_binder1st :
public constant_binder_base<std::binder1st, BinaryFunction,
typename BinaryFunction::first_argument_type,
ConstantOp> {
};
template <template<class> class BindType,
class BinaryFunction, class ValueType>
class default_binder_base :
public BindType<BinaryFunction>{
public:
typedef BinaryFunction bin_op;
typedef BindType<bin_op> base;
typedef ValueType value_type;
default_binder_base(const value_type& val): base(bin_op(), val) {}
};
template <class BinaryFunction>
class default_binder2nd :
public default_binder_base<std::binder2nd, BinaryFunction,
typename BinaryFunction::second_argument_type> {
public:
typedef default_binder_base<std::binder2nd, BinaryFunction,
typename BinaryFunction::second_argument_type>
base;
default_binder2nd(const typename base::value_type& val): base(val) {}
};
template <class BinaryFunction>
class default_binder1st :
public default_binder_base<std::binder1st, BinaryFunction,
typename BinaryFunction::first_argument_type> {
};
// /** @class property_owner
// * @brief defines generic base for properties
// **/
// template <class ValidityTag>
// class property_owner {
// public:
// /// Set marker for validity
// typedef typename
// on_same_type<ValidityTag, valid_tag, valid_tag, invalid_tag>::type property;
// /// Generate Boolean member function
// is_same_type<property, valid_tag> hasProperty;
// };
template <class ManagerType,
class IdxType = typename ManagerType::idx_type,
class VarNameType = typename ManagerType::const_varname_reference>
class variable_name {
public:
typedef ManagerType manager_type;
typedef IdxType idx_type;
typedef VarNameType varname_type;
variable_name(const manager_type& mgr): m_mgr(mgr) {}
varname_type operator()(idx_type idx) const{
return m_mgr.getVariableName(idx);
}
protected:
const manager_type& m_mgr;
};
template <class MapType, class VariableType, class TermType, class NodeType>
class mapped_new_node {
public:
typedef MapType map_type;
typedef NodeType node_type;
typedef typename node_type::idx_type idx_type;
mapped_new_node(const map_type& the_map): m_map(the_map) {}
NodeType operator()(idx_type idx,
const node_type& first, const node_type& second) const{
return ((TermType)VariableType(m_map[idx]))*first + second;
}
private:
const map_type& m_map;
};
template <class NewType>
struct pbori_base;
template <class DDType>
class get_node {
public:
typename DDType::node_type operator()(const DDType& rhs) const {
return rhs.getNode();
}
};
// template<unsigned ErrorNumber = CUDD_INTERNAL_ERROR>
// struct handle_error {
// typedef mgrcore_traits<Cudd>::errorfunc_type errorfunc_type;
// handle_error(errorfunc_type errfunc): m_errfunc(errfunc) {}
// bool found(unsigned err) const {
// if PBORI_UNLIKELY(err == ErrorNumber) {
// m_errfunc(cudd_error_traits<ErrorNumber>()());
// return true;
// }
// return false;
// }
// void operator()(unsigned err) const {
// if PBORI_UNLIKELY(err == ErrorNumber)
// m_errfunc(cudd_error_traits<ErrorNumber>()());
// else
// reinterpret_cast<const handle_error<ErrorNumber - 1>&>(*this)(err);
// }
// protected:
// const errorfunc_type m_errfunc;
// };
// template<>
// struct handle_error<0> {
// typedef mgrcore_traits<Cudd>::errorfunc_type errorfunc_type;
// handle_error(errorfunc_type errfunc): m_errfunc(errfunc) {}
// void operator()(unsigned err) const {
// if PBORI_LIKELY(err == 0)
// m_errfunc(cudd_error_traits<0>()());
// }
// protected:
// errorfunc_type m_errfunc;
// };
END_NAMESPACE_PBORI
#endif