PolyBoRi
pbori_func.h
Go to the documentation of this file.
00001 // -*- c++ -*-
00002 //*****************************************************************************
00013 //*****************************************************************************
00014 
00015 #ifndef polybori_routines_pbori_func_h_
00016 #define polybori_routines_pbori_func_h_
00017 
00018 // get polybori definitions
00019 #include <polybori/pbori_defs.h>
00020 
00021 // get polybori properties
00022 #include <polybori/common/traits.h>
00023 
00024 // get standard string and string stream functionality
00025 #include <string>
00026 #include <sstream>
00027 
00028 
00029 #ifdef PBORI_HAVE_TR1_UNORDERED_MAP
00030 #  include <tr1/unordered_map>
00031 #else 
00032 #  ifdef PBORI_HAVE_UNORDERED_MAP
00033 #    include <unordered_map>
00034 #  else
00035 #    ifdef PBORI_HAVE_HASH_MAP
00036 #      include <ext/hash_map>
00037 #    else
00038 #     include <map>
00039 #    endif
00040 #  endif
00041 #endif
00042 
00043 BEGIN_NAMESPACE_PBORI
00044 
00047 template <class ListType, class ValueType = typename ListType::value_type >
00048 class push_back {
00049 public:
00050 
00051   ListType
00052   operator()(ListType theList, const ValueType& elt) const {
00053     theList.push_back(elt);
00054     return theList;
00055   }
00056 };
00057 
00060 template <class RhsType, class LhsType = typename RhsType::idx_type >
00061 class change_idx {
00062 public:
00063 
00064   RhsType operator() (const RhsType& rhs, const LhsType& lhs) const {
00065     return (rhs.change(lhs));
00066   } 
00067 
00068 };
00069 
00072 template <class RhsType = void,
00073           class LhsType = typename pbori_traits<RhsType>::idx_type >
00074 class change_assign;
00075 
00076 // default variant
00077 template <class RhsType, class LhsType>
00078 class change_assign {
00079 public:
00080 
00081   RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00082     return (rhs = rhs.change(lhs));
00083   } 
00084 
00085 };
00086 
00087 // template specialization
00088 template<>
00089 class change_assign<void, pbori_traits<void>::idx_type> {
00090 public:
00091 
00092   template <class RhsType, class LhsType>
00093   RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00094     return (rhs = rhs.change(lhs));
00095   } 
00096 
00097 };
00098 
00101 template <class RhsType, class LhsType = typename RhsType::idx_type>
00102 class subset1_assign {
00103 public:
00104 
00105   RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00106 
00107     rhs = rhs.subset1(lhs);
00108     return rhs;
00109   } 
00110 };
00111 
00114 template <class RhsType, class LhsType>
00115 class subset0_assign {
00116 public:
00117 
00118   RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00119     return (rhs = rhs.subset0(lhs));
00120   } 
00121 };
00124 template <class RhsType,
00125           class LhsType = typename pbori_traits<RhsType>::idx_type >
00126 class unite_assign:
00127   public std::binary_function<RhsType&, const LhsType&, RhsType&> {
00128 
00129 public:
00130   RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00131     return (rhs = rhs.unite(lhs));
00132   } 
00133 };
00134 
00135 
00136 // @class project_ith
00142 
00143 template <unsigned int ITH, unsigned int NLEN = ITH>
00144 class project_ith;
00145 
00148 template <unsigned int NLEN>
00149 class project_ith<0, NLEN> {
00150 
00151 public:
00153   template <class ValueType>
00154   void operator() (const ValueType&, ...) const { } 
00155 };
00156 
00159 template <unsigned int NLEN>
00160 class project_ith<1, NLEN> {
00161 
00162 public:
00164   template <class ValueType>
00165   const ValueType& operator() (const ValueType& value, ...) const {
00166     return value;
00167   } 
00168 
00170   template <class ValueType>
00171   ValueType& operator() (ValueType& value, ...) const {
00172     return value;
00173   } 
00174 };
00175 
00176 
00179 template <unsigned int NLEN>
00180 class project_ith<2, NLEN> {
00181 
00182 public:
00184   template <class FirstType, class ValueType>
00185   const ValueType& 
00186   operator() (const FirstType&, const ValueType& value, ...) const {
00187     return value;
00188   } 
00189 
00191   template <class FirstType, class ValueType>
00192   ValueType& operator() (const FirstType&, ValueType& value, ...) const {
00193     return value;
00194   } 
00195 };
00196 
00197 
00200 template <unsigned int NLEN>
00201 class project_ith<3, NLEN> {
00202 
00203 public:
00205   template <class FirstType, class SecondType, class ValueType>
00206   const ValueType& 
00207   operator() (const FirstType&, const SecondType&, 
00208               const ValueType& value, ...) const {
00209     return value;
00210   } 
00211 
00213   template <class FirstType, class SecondType, class ValueType>
00214   ValueType& operator() (const FirstType&, const SecondType&, 
00215                          ValueType& value, ...) const {
00216     return value;
00217   } 
00218 };
00219 
00220 /*
00221 class print_all {
00222 public:
00223 
00224   print_all(std::ostream& os_):os(os_){}
00225 
00226   template<class Type>
00227   Type& operator()(Type& val){
00228     std::copy(val.begin(), val.end(), 
00229          std::ostream_iterator<typename  Type::value_type>(os, ", "));
00230     return val;
00231   }
00232   std::ostream& os;
00233 };
00234 */
00235 
00238 class dummy_iterator {
00239 public:
00240 
00242   typedef dummy_iterator self;
00243 
00244   template <class Type>
00245   const self& operator=(const Type&) const { return *this;}
00246 
00247   const self& operator*() const { return *this;}
00248   const self& operator++() const { return *this;}
00249   const self& operator++(int) const { return *this;}
00250 };
00251 
00252 template <>
00253 class pbori_traits<dummy_iterator>:
00254   public CTypes {
00255 };
00256 
00262 template <class IntType, IntType INTCONST, class ResultType = IntType>
00263 struct integral_constant {
00264 
00265   typedef ResultType result_type;
00266   enum { result = INTCONST };
00267   result_type operator()(...) const { return result; }
00268 };
00269 
00273 template <class BinaryOp, class FirstOp, class SecondOp>
00274 class binary_composition:
00275   public BinaryOp {
00276 
00277 public:
00278 
00280 
00281   typedef BinaryOp base;
00282   typedef FirstOp first_op_type;
00283   typedef SecondOp second_op_type;
00285 
00286   // Constructor
00287   binary_composition(const base& binop = base(),
00288                      const first_op_type& unop1 = first_op_type(),
00289                      const second_op_type& unop2 = second_op_type() ): 
00290     base(binop), first_op(unop1), second_op(unop2) {}
00291 
00293   typedef typename base::result_type result_type;
00294 
00296   template <class FirstType, class SecondType>
00297   result_type operator()(const FirstType& first, 
00298                          const SecondType& second) const {
00299     return base::operator()(first_op(first), second_op(second));
00300   }
00301 
00303   template <class FirstType, class SecondType>
00304   result_type operator()(FirstType& first, 
00305                          const SecondType& second) const {
00306     return base::operator()(first_op(first), second_op(second));
00307   }
00308 
00310   template <class FirstType, class SecondType>
00311   result_type operator()(const FirstType& first, 
00312                          SecondType& second) const {
00313     return base::operator()(first_op(first), second_op(second));
00314   }
00315 
00316 protected:
00317   first_op_type first_op;
00318   second_op_type second_op;
00319 };
00320 
00324 template <class BinaryOp, class UnaryOperation>
00325 class symmetric_composition:
00326   public binary_composition<BinaryOp, UnaryOperation, UnaryOperation>  {
00327 
00328 public:
00329 
00331 
00332   typedef BinaryOp binary_op_type;
00333   typedef UnaryOperation unary_op_type;
00334   typedef binary_composition<binary_op_type, unary_op_type, unary_op_type>
00335   base;
00337 
00338   // Constructor
00339   symmetric_composition(const binary_op_type& binop = binary_op_type(),
00340                      const unary_op_type& unop = unary_op_type() ): 
00341     base(binop, unop, unop) {}
00342 };
00343 
00346 template<class ValueType>
00347 class maximum_iteration {
00348 public:
00349   maximum_iteration(ValueType & init) : max(init){}
00350 
00351   ValueType& operator()(const ValueType& val) const {
00352     return max = std::max(max, val);
00353   }
00354 
00355 private:
00356   ValueType & max;
00357 };
00358 
00361 template <class DDType>
00362 class dd_add_assign {
00363 public:
00364 
00365   DDType& operator()(DDType& lhs, const DDType& rhs) const {
00366     // several possible implementations
00367     return 
00368 #if defined(PBORI_ADD_BY_OR)
00369       (lhs = (lhs.diff(rhs)).unite(rhs.diff(lhs)));
00370 
00371 # elif defined(PBORI_ADD_BY_UNION)
00372       (lhs = lhs.unite(rhs).diff( lhs.intersect(rhs) ) );
00373 # elif defined(PBORI_ADD_BY_EXTRA_XOR) || defined(PBORI_ADD_BY_XOR)
00374       (lhs = lhs.Xor(rhs));
00375 #endif
00376   }
00377 };
00378 
00381 template <class DDType, class IdxType = typename DDType::idx_type>
00382 class times_indexed_var {
00383 public:
00384 
00385   DDType& operator()(DDType& lhs, IdxType idx) const {
00386 
00387   // get all terms not containing the variable with index idx
00388     DDType tmp( lhs.subset0(idx) );
00389 
00390     // get the complementary terms
00391     lhs = lhs.diff(tmp);
00392 
00393     // construct polynomial terms
00394     dd_add_assign<DDType>()(lhs, tmp.change(idx));
00395 
00396     return lhs;
00397   }
00398 
00399 };
00400 
00403 template <class DDType, class IdxType = typename DDType::idx_type>
00404 class append_indexed_divisor {
00405 public:
00406 
00407   DDType& operator()(DDType& lhs, IdxType idx) const {
00408 
00409     lhs = lhs.unite( lhs.change(idx) );
00410     return lhs;
00411   }
00412 
00413 };
00414 
00417 // template <class RhsType = void,
00418 //           class LhsType = typename RhsType::value_type >
00419 // class inserts:
00420 //   public std::binary_function<RhsType&, const LhsType&, RhsType&> {
00421 // public:
00422 
00423 //   RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00424 //     rhs.insert(lhs);
00425 //     return rhs;
00426 //   } 
00427 
00428 // };
00429 
00430 
00433 template <class RhsType = void,
00434           class LhsType = typename pbori_traits<RhsType>::idx_type >
00435 class inserts;
00436 
00437 template <class RhsType, class LhsType>
00438 class inserts:
00439   public std::binary_function<RhsType&, const LhsType&, RhsType&> {
00440 public:
00441 
00442   RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00443     rhs.insert(lhs);
00444     return rhs;
00445   } 
00446 };
00447 
00448 template <>
00449 class inserts<void,  pbori_traits<void>::idx_type> {
00450 public:
00451 template <class RhsType, class LhsType>
00452   RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00453     rhs.insert(lhs);
00454     return rhs;
00455   } 
00456 };
00457 
00458 
00461 template <class RhsType = void,
00462           class LhsType = typename pbori_traits<RhsType>::idx_type >
00463 class insert_assign;
00464 
00465 template <class RhsType, class LhsType>
00466 class insert_assign:
00467   public std::binary_function<RhsType&, const LhsType&, RhsType&> {
00468 public:
00469 
00470   RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00471     rhs.insertAssign(lhs);
00472     return rhs;
00473   } 
00474 };
00475 
00476 template <>
00477 class insert_assign<void,  pbori_traits<void>::idx_type> {
00478 public:
00479 template <class RhsType, class LhsType>
00480   RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00481     rhs.insertAssign(lhs);
00482     return rhs;
00483   } 
00484 };
00485 
00486 
00487 
00490 template <class RhsType = void,
00491           class LhsType = typename pbori_traits<RhsType>::idx_type >
00492 class removes;
00493 
00494 
00495 template <class RhsType, class LhsType>
00496 class removes:
00497   public std::binary_function<RhsType&, const LhsType&, RhsType&> {
00498 public:
00499 
00500   RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00501     rhs.remove(lhs);
00502     return rhs;
00503   } 
00504 };
00505 
00506 
00507 template <>
00508 class removes<void,  pbori_traits<void>::idx_type> {
00509 public:
00510 
00511   template <class RhsType, class LhsType>
00512   RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00513     rhs.remove(lhs);
00514     return rhs;
00515   } 
00516 };
00517 
00520 template <class RhsType = void,
00521           class LhsType = typename pbori_traits<RhsType>::idx_type >
00522 class remove_assign;
00523 
00524 
00525 template <class RhsType, class LhsType>
00526 class remove_assign:
00527   public std::binary_function<RhsType&, const LhsType&, RhsType&> {
00528 public:
00529 
00530   RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00531     rhs.removeAssign(lhs);
00532     return rhs;
00533   } 
00534 };
00535 
00536 
00537 template <>
00538 class remove_assign<void,  pbori_traits<void>::idx_type> {
00539 public:
00540 
00541   template <class RhsType, class LhsType>
00542   RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00543     rhs.removeAssign(lhs);
00544     return rhs;
00545   } 
00546 };
00547 
00550 template <class ListType, class RhsType, class LhsType>
00551 class insert_second_to_list {
00552 public:
00553 
00554   insert_second_to_list(ListType& theList__):
00555     theList(theList__) {};
00556 
00557   RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00558     theList.insert(lhs);
00559     return rhs;
00560   } 
00561 
00562 private:
00563   ListType& theList;
00564 };
00565 
00566 
00570 template <class Type1, class Type2>
00571 class is_same_type;
00572 
00573 template <class Type>
00574 class is_same_type<Type, Type>:
00575   public integral_constant<CTypes::bool_type, true> {}; 
00576 
00577 template <class Type1, class Type2>
00578 class is_same_type:
00579   public integral_constant<CTypes::bool_type, false> {};
00580 
00581 template <class Type>
00582 class is_valid:
00583   public is_same_type<Type, valid_tag> {};
00584 
00588 template <class Type1, class Type2, class ThenType, class ElseType>
00589 class on_same_type;
00590 
00591 template <class Type, class ThenType, class ElseType>
00592 class on_same_type<Type, Type, ThenType, ElseType> {
00593 public:
00594   typedef ThenType type;
00595 };
00596 
00597 template <class Type1, class Type2, class ThenType, class ElseType>
00598 class on_same_type {
00599 public:
00600   typedef ElseType type;
00601 };
00602 
00603 
00607 struct internal_tag {};
00608 
00612 template<class Type>
00613 struct type_tag {};
00614 
00615 template <class Type>
00616 class hashes {
00617 public:
00618 
00619   typedef typename Type::hash_type hash_type;
00620 
00621   hash_type operator() (const Type& rhs) const{
00622     return rhs.hash();
00623   }
00624 };
00625 
00626 template <class Type>
00627 class generate_index_map {
00628 
00629   typedef typename Type::idx_type idx_type;
00630 public:
00632 
00633 #ifdef PBORI_HAVE_TR1_UNORDERED_MAP
00634   typedef std::tr1::unordered_map<Type, idx_type, hashes<Type> > type;
00635 #else
00636 #  ifdef PBORI_HAVE_UNORDERED_MAP
00637      typedef std::unordered_map<Type, idx_type, hashes<Type> > type;
00638 #  else
00639 #    ifdef PBORI_HAVE_HASH_MAP
00640       typedef __gnu_cxx::hash_map<Type, idx_type, hashes<Type> > type;
00641 #    else
00642        typedef std::map<Type, idx_type> type;
00643 #    endif
00644 #  endif
00645 #endif
00646 };
00647 
00651 template <class ListType>
00652 class sizes_less:
00653   public std::binary_function<const ListType&, const ListType&, bool> {
00654 
00655 public:
00656   bool operator()(const ListType& lhs, const ListType& rhs) const {
00657     return (lhs.size() < rhs.size());
00658   }    
00659 };
00660 
00664 template <class BiIterator>
00665 class reversed_iteration_adaptor {
00666 public:
00667 
00669   typedef BiIterator iterator;
00670 
00672   typedef reversed_iteration_adaptor<iterator> self;
00674 
00675   typedef std::bidirectional_iterator_tag iterator_category;
00676   typedef typename std::iterator_traits<iterator>::difference_type 
00677   difference_type;
00678   typedef typename std::iterator_traits<iterator>::pointer  pointer;
00679   typedef typename std::iterator_traits<iterator>::reference  reference;
00680   typedef typename std::iterator_traits<iterator>::value_type value_type;
00682 
00684   reversed_iteration_adaptor(const iterator& iter):
00685     m_iter(iter) {}
00686 
00688 
00689   reference operator*() const {
00690     return *m_iter;
00691   }
00692 
00694   self& operator++() {
00695     --m_iter;
00696     return *this;
00697   }
00698 
00700   self& operator--() {
00701     ++m_iter;
00702     return *this;
00703   }
00704 
00705   bool operator==(const self& rhs) const {
00706     return m_iter == rhs.m_iter;
00707   }
00708 
00709   bool operator!=(const self& rhs) const {
00710     return m_iter != rhs.m_iter;
00711   }
00712   iterator get() const {
00713     return m_iter;
00714   }
00715 
00716 protected:
00717   iterator m_iter;
00718 };
00719 
00720 
00721 template <class DDType>
00722 class navigates:
00723   public std::unary_function<DDType, typename DDType::navigator> {
00724 public:
00726   typedef DDType dd_type;
00727 
00729   typedef typename DDType::navigator navigator;
00730 
00732   typedef std::unary_function<dd_type, navigator> base;
00733 
00735   typename base::result_type operator()(const dd_type& rhs) const{
00736     return rhs.navigation();
00737   }
00738 
00739 };
00740 
00741 
00742 template <class ValueType>
00743 class default_value {
00744 public:
00745   typedef ValueType value_type;
00746 
00747   value_type operator()(...) const{
00748     return value_type();
00749   }
00750 
00751 };
00752 
00753 template <template<class> class BindType, class BinaryFunction, 
00754           class ValueType, class ConstantOp>
00755 class constant_binder_base :
00756   public BindType<BinaryFunction>{
00757 public:
00758   typedef BinaryFunction bin_op; 
00759   typedef ConstantOp const_type;
00760   typedef BindType<bin_op> base;
00761 
00762   typedef ValueType value_type;
00763 
00764   constant_binder_base(const bin_op& op = bin_op()): base(op, const_type()()) {}
00765 };
00766 
00767 template <class BinaryFunction, class ConstantOp>
00768 class constant_binder2nd :
00769   public constant_binder_base<std::binder2nd, BinaryFunction,
00770                               typename BinaryFunction::second_argument_type,
00771                               ConstantOp> {
00772 };
00773 
00774 
00775 template <class BinaryFunction, class ConstantOp>
00776 class constant_binder1st :
00777   public constant_binder_base<std::binder1st, BinaryFunction,
00778                               typename BinaryFunction::first_argument_type,
00779                               ConstantOp> {
00780 };
00781 
00782 template <template<class> class BindType,
00783           class BinaryFunction, class ValueType>
00784 class default_binder_base :
00785   public BindType<BinaryFunction>{
00786 public:
00787   typedef BinaryFunction bin_op; 
00788   typedef BindType<bin_op> base;
00789 
00790   typedef ValueType value_type;
00791 
00792   default_binder_base(const value_type&  val): base(bin_op(), val) {}
00793 };
00794 
00795 template <class BinaryFunction>
00796 class default_binder2nd :
00797   public default_binder_base<std::binder2nd, BinaryFunction,
00798                               typename BinaryFunction::second_argument_type> {
00799 public:
00800   typedef default_binder_base<std::binder2nd, BinaryFunction,
00801                               typename BinaryFunction::second_argument_type>
00802   base;
00803 
00804   default_binder2nd(const typename base::value_type&  val): base(val) {}
00805 };
00806 
00807 
00808 template <class BinaryFunction>
00809 class default_binder1st :
00810   public default_binder_base<std::binder1st, BinaryFunction,
00811                               typename BinaryFunction::first_argument_type> {
00812 };
00813 
00814 // /** @class property_owner
00815 //  *  @brief defines generic base for properties
00816 //  **/
00817 // template <class ValidityTag>
00818 // class property_owner {
00819 // public:
00820 
00821 //   /// Set marker for validity
00822 //   typedef typename 
00823 //   on_same_type<ValidityTag, valid_tag, valid_tag, invalid_tag>::type property;
00824 
00825 //   /// Generate Boolean member function
00826 //   is_same_type<property, valid_tag> hasProperty;
00827 // };
00828 
00832 template <class ManagerType, 
00833           class IdxType = typename ManagerType::idx_type,
00834           class VarNameType = typename ManagerType::const_varname_reference>
00835 class variable_name {
00836 public:
00837   typedef ManagerType manager_type;
00838   typedef IdxType idx_type;
00839   typedef VarNameType varname_type;
00840 
00842   variable_name(const manager_type& mgr): m_mgr(mgr) {}
00843 
00845   varname_type operator()(idx_type idx) const{
00846     return m_mgr.getVariableName(idx);
00847   }
00848 
00849 protected:
00851   const manager_type& m_mgr;
00852 };
00853 
00854 template <class MapType, class VariableType, class TermType, class NodeType>
00855 class mapped_new_node {
00856 public:
00857   typedef MapType map_type;
00858   typedef NodeType node_type;
00859 
00860   typedef typename node_type::idx_type idx_type;
00861 
00862   mapped_new_node(const map_type& the_map): m_map(the_map) {}
00863 
00864   NodeType operator()(idx_type idx,
00865                       const node_type& first, const node_type&  second) const{
00866     return ((TermType)VariableType(m_map[idx]))*first +  second;
00867   }
00868 
00869 
00870 
00871 private:
00872   const map_type& m_map;
00873 };
00874 
00875 
00880 template <class NewType>
00881 struct pbori_base;
00882 
00883 
00884 
00885 template <class DDType>
00886 class get_node {
00887 
00888 public:
00889   typename DDType::node_type operator()(const DDType& rhs) const {
00890     return rhs.getNode();
00891   }
00892 };
00893 
00894 // template<unsigned ErrorNumber = CUDD_INTERNAL_ERROR>
00895 // struct handle_error {
00896 //   typedef mgrcore_traits<Cudd>::errorfunc_type errorfunc_type;
00897 
00898 //   handle_error(errorfunc_type errfunc): m_errfunc(errfunc) {}
00899 
00900 //   bool found(unsigned err) const {
00901 //     if PBORI_UNLIKELY(err == ErrorNumber) {
00902 //       m_errfunc(cudd_error_traits<ErrorNumber>()());
00903 //       return true;
00904 //     }
00905 //     return false;        
00906 //   }
00907 
00908 //   void operator()(unsigned err) const {
00909 //     if PBORI_UNLIKELY(err == ErrorNumber) 
00910 //       m_errfunc(cudd_error_traits<ErrorNumber>()());
00911 //     else
00912 //       reinterpret_cast<const handle_error<ErrorNumber - 1>&>(*this)(err);
00913 //   }
00914 
00915 // protected: 
00916 //   const errorfunc_type m_errfunc;
00917 // };
00918 
00919 
00920 // template<>
00921 // struct handle_error<0> {
00922 //   typedef mgrcore_traits<Cudd>::errorfunc_type errorfunc_type;
00923 
00924 //   handle_error(errorfunc_type errfunc): m_errfunc(errfunc) {}
00925 
00926 //   void operator()(unsigned err) const {
00927 //     if PBORI_LIKELY(err == 0)
00928 //       m_errfunc(cudd_error_traits<0>()());
00929 //   }
00930 // protected: 
00931 //   errorfunc_type m_errfunc;
00932 // };
00933 
00934 
00935 END_NAMESPACE_PBORI
00936 
00937 #endif