00001
00002
00159
00160
00161
00162 #include "pbori_defs.h"
00163
00164
00165 #include "pbori_traits.h"
00166
00167
00168 #include <string>
00169 #include <sstream>
00170
00171
00172
00173 #ifdef HAVE_TR1_UNORDERED_MAP
00174 # include <tr1/unordered_map>
00175 #else
00176 # ifdef HAVE_UNORDERED_MAP
00177 # include <unordered_map>
00178 # else
00179 # ifdef HAVE_HASH_MAP
00180 # include <ext/hash_map>
00181 # else
00182 # include <map>
00183 # endif
00184 # endif
00185 #endif
00186
00187 #ifndef pbori_func_h_
00188 #define pbori_func_h_
00189
00190 BEGIN_NAMESPACE_PBORI
00191
00194 template <class ListType, class ValueType = typename ListType::value_type >
00195 class push_back {
00196 public:
00197
00198 ListType
00199 operator()(ListType theList, const ValueType& elt) const {
00200 theList.push_back(elt);
00201 return theList;
00202 }
00203 };
00204
00207 template <class RhsType, class LhsType = typename RhsType::idx_type >
00208 class change_idx {
00209 public:
00210
00211 RhsType operator() (const RhsType& rhs, const LhsType& lhs) const {
00212 return (rhs.change(lhs));
00213 }
00214
00215 };
00216
00219 template <class RhsType = void,
00220 class LhsType = typename pbori_traits<RhsType>::idx_type >
00221 class change_assign;
00222
00223
00224 template <class RhsType, class LhsType>
00225 class change_assign {
00226 public:
00227
00228 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00229 return (rhs.changeAssign(lhs));
00230 }
00231
00232 };
00233
00234
00235 template<>
00236 class change_assign<void, pbori_traits<void>::idx_type> {
00237 public:
00238
00239 template <class RhsType, class LhsType>
00240 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00241 return (rhs.changeAssign(lhs));
00242 }
00243
00244 };
00245
00248 template <class RhsType, class LhsType = typename RhsType::idx_type>
00249 class subset1_assign {
00250 public:
00251
00252 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00253 (rhs.subset1Assign(lhs));
00254 return rhs;
00255 }
00256 };
00257
00260 template <class RhsType, class LhsType>
00261 class subset0_assign {
00262 public:
00263
00264 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00265 return (rhs.subset0Assign(lhs));
00266 }
00267 };
00270 template <class RhsType,
00271 class LhsType = typename pbori_traits<RhsType>::idx_type >
00272 class unite_assign:
00273 public std::binary_function<RhsType&, const LhsType&, RhsType&> {
00274
00275 public:
00276 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00277 return (rhs.uniteAssign(lhs));
00278 }
00279 };
00280
00281
00282
00288
00289 template <unsigned int ITH, unsigned int NLEN = ITH>
00290 class project_ith;
00291
00294 template <unsigned int NLEN>
00295 class project_ith<0, NLEN> {
00296
00297 public:
00299 template <class ValueType>
00300 void operator() (const ValueType&, ...) const { }
00301 };
00302
00305 template <unsigned int NLEN>
00306 class project_ith<1, NLEN> {
00307
00308 public:
00310 template <class ValueType>
00311 const ValueType& operator() (const ValueType& value, ...) const {
00312 return value;
00313 }
00314
00316 template <class ValueType>
00317 ValueType& operator() (ValueType& value, ...) const {
00318 return value;
00319 }
00320 };
00321
00322
00325 template <unsigned int NLEN>
00326 class project_ith<2, NLEN> {
00327
00328 public:
00330 template <class FirstType, class ValueType>
00331 const ValueType&
00332 operator() (const FirstType&, const ValueType& value, ...) const {
00333 return value;
00334 }
00335
00337 template <class FirstType, class ValueType>
00338 ValueType& operator() (const FirstType&, ValueType& value, ...) const {
00339 return value;
00340 }
00341 };
00342
00343
00346 template <unsigned int NLEN>
00347 class project_ith<3, NLEN> {
00348
00349 public:
00351 template <class FirstType, class SecondType, class ValueType>
00352 const ValueType&
00353 operator() (const FirstType&, const SecondType&,
00354 const ValueType& value, ...) const {
00355 return value;
00356 }
00357
00359 template <class FirstType, class SecondType, class ValueType>
00360 ValueType& operator() (const FirstType&, const SecondType&,
00361 ValueType& value, ...) const {
00362 return value;
00363 }
00364 };
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00384 class dummy_iterator {
00385 public:
00386
00388 typedef dummy_iterator self;
00389
00390 template <class Type>
00391 const self& operator=(const Type&) const { return *this;}
00392
00393 const self& operator*() const { return *this;}
00394 const self& operator++() const { return *this;}
00395 const self& operator++(int) const { return *this;}
00396 };
00397
00398 template <>
00399 class pbori_traits<dummy_iterator>:
00400 public CTypes {
00401 };
00402
00408 template <class IntType, IntType INTCONST, class ResultType = IntType>
00409 struct integral_constant {
00410
00411 typedef ResultType result_type;
00412 result_type operator()(...) const { return INTCONST; }
00413 };
00414
00418 template <class BinaryOp, class FirstOp, class SecondOp>
00419 class binary_composition:
00420 public BinaryOp {
00421
00422 public:
00423
00425
00426 typedef BinaryOp base;
00427 typedef FirstOp first_op_type;
00428 typedef SecondOp second_op_type;
00430
00431
00432 binary_composition(const base& binop = base(),
00433 const first_op_type& unop1 = first_op_type(),
00434 const second_op_type& unop2 = second_op_type() ):
00435 base(binop), first_op(unop1), second_op(unop2) {}
00436
00438 typedef typename base::result_type result_type;
00439
00441 template <class FirstType, class SecondType>
00442 result_type operator()(const FirstType& first,
00443 const SecondType& second) const {
00444 return base::operator()(first_op(first), second_op(second));
00445 }
00446
00448 template <class FirstType, class SecondType>
00449 result_type operator()(FirstType& first,
00450 const SecondType& second) const {
00451 return base::operator()(first_op(first), second_op(second));
00452 }
00453
00455 template <class FirstType, class SecondType>
00456 result_type operator()(const FirstType& first,
00457 SecondType& second) const {
00458 return base::operator()(first_op(first), second_op(second));
00459 }
00460
00461 protected:
00462 first_op_type first_op;
00463 second_op_type second_op;
00464 };
00465
00469 template <class BinaryOp, class UnaryOperation>
00470 class symmetric_composition:
00471 public binary_composition<BinaryOp, UnaryOperation, UnaryOperation> {
00472
00473 public:
00474
00476
00477 typedef BinaryOp binary_op_type;
00478 typedef UnaryOperation unary_op_type;
00479 typedef binary_composition<binary_op_type, unary_op_type, unary_op_type>
00480 base;
00482
00483
00484 symmetric_composition(const binary_op_type& binop = binary_op_type(),
00485 const unary_op_type& unop = unary_op_type() ):
00486 base(binop, unop, unop) {}
00487 };
00488
00491 template<class ValueType>
00492 class maximum_iteration {
00493 public:
00494 maximum_iteration(ValueType & init) : max(init){}
00495
00496 ValueType& operator()(const ValueType& val) const {
00497 return max = std::max(max, val);
00498 }
00499
00500 private:
00501 ValueType & max;
00502 };
00503
00506 template <class DDType>
00507 class dd_add_assign {
00508 public:
00509
00510 DDType& operator()(DDType& lhs, const DDType& rhs) const {
00511
00512 return
00513 #ifdef PBORI_ADD_BY_ITE
00514 lhs.iteAssign(lhs.diff(rhs), rhs);
00515
00516 # elif defined(PBORI_ADD_BY_OR)
00517 (lhs = (lhs.diff(rhs)).unite(rhs.diff(lhs)));
00518
00519 # elif defined(PBORI_ADD_BY_UNION)
00520 (lhs = lhs.unite(rhs).diff( lhs.intersect(rhs) ) );
00521 # elif defined(PBORI_ADD_BY_EXTRA_XOR) || defined(PBORI_ADD_BY_XOR)
00522 (lhs = lhs.Xor(rhs));
00523 #endif
00524 }
00525 };
00526
00529 template <class DDType, class IdxType = typename DDType::idx_type>
00530 class times_indexed_var {
00531 public:
00532
00533 DDType& operator()(DDType& lhs, IdxType idx) const {
00534
00535
00536 DDType tmp( lhs.subset0(idx) );
00537
00538
00539 lhs.diffAssign(tmp);
00540
00541
00542 dd_add_assign<DDType>()(lhs, tmp.change(idx));
00543
00544 return lhs;
00545 }
00546
00547 };
00548
00551 template <class DDType, class IdxType = typename DDType::idx_type>
00552 class append_indexed_divisor {
00553 public:
00554
00555 DDType& operator()(DDType& lhs, IdxType idx) const {
00556
00557 lhs.uniteAssign( lhs.change(idx) );
00558 return lhs;
00559 }
00560
00561 };
00562
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00581 template <class RhsType = void,
00582 class LhsType = typename pbori_traits<RhsType>::idx_type >
00583 class inserts;
00584
00585 template <class RhsType, class LhsType>
00586 class inserts:
00587 public std::binary_function<RhsType&, const LhsType&, RhsType&> {
00588 public:
00589
00590 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00591 rhs.insert(lhs);
00592 return rhs;
00593 }
00594 };
00595
00596 template <>
00597 class inserts<void, pbori_traits<void>::idx_type> {
00598 public:
00599 template <class RhsType, class LhsType>
00600 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00601 rhs.insert(lhs);
00602 return rhs;
00603 }
00604 };
00605
00606
00609 template <class RhsType = void,
00610 class LhsType = typename pbori_traits<RhsType>::idx_type >
00611 class insert_assign;
00612
00613 template <class RhsType, class LhsType>
00614 class insert_assign:
00615 public std::binary_function<RhsType&, const LhsType&, RhsType&> {
00616 public:
00617
00618 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00619 rhs.insertAssign(lhs);
00620 return rhs;
00621 }
00622 };
00623
00624 template <>
00625 class insert_assign<void, pbori_traits<void>::idx_type> {
00626 public:
00627 template <class RhsType, class LhsType>
00628 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00629 rhs.insertAssign(lhs);
00630 return rhs;
00631 }
00632 };
00633
00634
00635
00638 template <class RhsType = void,
00639 class LhsType = typename pbori_traits<RhsType>::idx_type >
00640 class removes;
00641
00642
00643 template <class RhsType, class LhsType>
00644 class removes:
00645 public std::binary_function<RhsType&, const LhsType&, RhsType&> {
00646 public:
00647
00648 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00649 rhs.remove(lhs);
00650 return rhs;
00651 }
00652 };
00653
00654
00655 template <>
00656 class removes<void, pbori_traits<void>::idx_type> {
00657 public:
00658
00659 template <class RhsType, class LhsType>
00660 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00661 rhs.remove(lhs);
00662 return rhs;
00663 }
00664 };
00665
00668 template <class RhsType = void,
00669 class LhsType = typename pbori_traits<RhsType>::idx_type >
00670 class remove_assign;
00671
00672
00673 template <class RhsType, class LhsType>
00674 class remove_assign:
00675 public std::binary_function<RhsType&, const LhsType&, RhsType&> {
00676 public:
00677
00678 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00679 rhs.removeAssign(lhs);
00680 return rhs;
00681 }
00682 };
00683
00684
00685 template <>
00686 class remove_assign<void, pbori_traits<void>::idx_type> {
00687 public:
00688
00689 template <class RhsType, class LhsType>
00690 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00691 rhs.removeAssign(lhs);
00692 return rhs;
00693 }
00694 };
00695
00698 template <class ListType, class RhsType, class LhsType>
00699 class insert_second_to_list {
00700 public:
00701
00702 insert_second_to_list(ListType& theList__):
00703 theList(theList__) {};
00704
00705 RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
00706 theList.insert(lhs);
00707 return rhs;
00708 }
00709
00710 private:
00711 ListType& theList;
00712 };
00713
00714
00718 template <class Type1, class Type2>
00719 class is_same_type;
00720
00721 template <class Type>
00722 class is_same_type<Type, Type>:
00723 public integral_constant<CTypes::bool_type, true> {};
00724
00725 template <class Type1, class Type2>
00726 class is_same_type:
00727 public integral_constant<CTypes::bool_type, false> {};
00728
00729
00733 template <class Type1, class Type2, class ThenType, class ElseType>
00734 class on_same_type;
00735
00736 template <class Type, class ThenType, class ElseType>
00737 class on_same_type<Type, Type, ThenType, ElseType> {
00738 public:
00739 typedef ThenType type;
00740 };
00741
00742 template <class Type1, class Type2, class ThenType, class ElseType>
00743 class on_same_type {
00744 public:
00745 typedef ElseType type;
00746 };
00747
00748
00752 struct internal_tag {};
00753
00757 template<class Type>
00758 struct type_tag {};
00759
00760 template <class Type>
00761 class hashes {
00762 public:
00763
00764 typedef typename Type::hash_type hash_type;
00765
00766 hash_type operator() (const Type& rhs) const{
00767 return rhs.hash();
00768 }
00769 };
00770
00771 template <class Type>
00772 class generate_index_map {
00773
00774 typedef typename Type::idx_type idx_type;
00775 public:
00777
00778 #ifdef HAVE_TR1_UNORDERED_MAP
00779 typedef std::tr1::unordered_map<Type, idx_type, hashes<Type> > type;
00780 #else
00781 # ifdef HAVE_UNORDERED_MAP
00782 typedef std::unordered_map<Type, idx_type, hashes<Type> > type;
00783 # else
00784 # ifdef HAVE_HASH_MAP
00785 typedef __gnu_cxx::hash_map<Type, idx_type, hashes<Type> > type;
00786 # else
00787 typedef std::map<Type, idx_type> type;
00788 # endif
00789 # endif
00790 #endif
00791 };
00792
00796 template <class ListType>
00797 class sizes_less:
00798 public std::binary_function<const ListType&, const ListType&, bool> {
00799
00800 public:
00801 bool operator()(const ListType& lhs, const ListType& rhs) const {
00802 return (lhs.size() < rhs.size());
00803 }
00804 };
00805
00809 template <class BiIterator>
00810 class reversed_iteration_adaptor {
00811 public:
00812
00814 typedef BiIterator iterator;
00815
00817 typedef reversed_iteration_adaptor<iterator> self;
00819
00820 typedef std::bidirectional_iterator_tag iterator_category;
00821 typedef typename std::iterator_traits<iterator>::difference_type
00822 difference_type;
00823 typedef typename std::iterator_traits<iterator>::pointer pointer;
00824 typedef typename std::iterator_traits<iterator>::reference reference;
00825 typedef typename std::iterator_traits<iterator>::value_type value_type;
00827
00829 reversed_iteration_adaptor(const iterator& iter):
00830 m_iter(iter) {}
00831
00833
00834 reference operator*() const {
00835 return *m_iter;
00836 }
00837
00839 self& operator++() {
00840 --m_iter;
00841 return *this;
00842 }
00843
00845 self& operator--() {
00846 ++m_iter;
00847 return *this;
00848 }
00849
00850 bool operator==(const self& rhs) const {
00851 return m_iter == rhs.m_iter;
00852 }
00853
00854 bool operator!=(const self& rhs) const {
00855 return m_iter != rhs.m_iter;
00856 }
00857 iterator get() const {
00858 return m_iter;
00859 }
00860
00861 protected:
00862 iterator m_iter;
00863 };
00864
00865
00866 template <class DDType>
00867 class navigates:
00868 public std::unary_function<DDType, typename DDType::navigator> {
00869 public:
00871 typedef DDType dd_type;
00872
00874 typedef typename DDType::navigator navigator;
00875
00877 typedef std::unary_function<dd_type, navigator> base;
00878
00880 typename base::result_type operator()(const dd_type& rhs) const{
00881 return rhs.navigation();
00882 }
00883
00884 };
00885
00886
00887 template <class ValueType>
00888 class default_value {
00889 public:
00890 typedef ValueType value_type;
00891
00892 value_type operator()(...) const{
00893 return value_type();
00894 }
00895
00896 };
00897
00898 template <template<class> class BindType, class BinaryFunction,
00899 class ValueType, class ConstantOp>
00900 class constant_binder_base :
00901 public BindType<BinaryFunction>{
00902 public:
00903 typedef BinaryFunction bin_op;
00904 typedef ConstantOp const_type;
00905 typedef BindType<bin_op> base;
00906
00907 typedef ValueType value_type;
00908
00909 constant_binder_base(const bin_op& op = bin_op()): base(op, const_type()()) {}
00910 };
00911
00912 template <class BinaryFunction, class ConstantOp>
00913 class constant_binder2nd :
00914 public constant_binder_base<std::binder2nd, BinaryFunction,
00915 typename BinaryFunction::second_argument_type,
00916 ConstantOp> {
00917 };
00918
00919
00920 template <class BinaryFunction, class ConstantOp>
00921 class constant_binder1st :
00922 public constant_binder_base<std::binder1st, BinaryFunction,
00923 typename BinaryFunction::first_argument_type,
00924 ConstantOp> {
00925 };
00926
00927 template <template<class> class BindType,
00928 class BinaryFunction, class ValueType>
00929 class default_binder_base :
00930 public BindType<BinaryFunction>{
00931 public:
00932 typedef BinaryFunction bin_op;
00933 typedef BindType<bin_op> base;
00934
00935 typedef ValueType value_type;
00936
00937 default_binder_base(const value_type& val): base(bin_op(), val) {}
00938 };
00939
00940 template <class BinaryFunction>
00941 class default_binder2nd :
00942 public default_binder_base<std::binder2nd, BinaryFunction,
00943 typename BinaryFunction::second_argument_type> {
00944 public:
00945 typedef default_binder_base<std::binder2nd, BinaryFunction,
00946 typename BinaryFunction::second_argument_type>
00947 base;
00948
00949 default_binder2nd(const typename base::value_type& val): base(val) {}
00950 };
00951
00952
00953 template <class BinaryFunction>
00954 class default_binder1st :
00955 public default_binder_base<std::binder1st, BinaryFunction,
00956 typename BinaryFunction::first_argument_type> {
00957 };
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00977 template <class ManagerType,
00978 class IdxType = typename ManagerType::idx_type,
00979 class VarNameType = typename ManagerType::const_varname_reference>
00980 class variable_name {
00981 public:
00982 typedef ManagerType manager_type;
00983 typedef IdxType idx_type;
00984 typedef VarNameType varname_type;
00985
00987 variable_name(const manager_type& mgr): m_mgr(mgr) {}
00988
00990 varname_type operator()(idx_type idx) const{
00991 return m_mgr.getName(idx);
00992 }
00993
00994 protected:
00996 const manager_type& m_mgr;
00997 };
00998
00999 template <class MapType, class VariableType, class TermType, class NodeType>
01000 class mapped_new_node {
01001 public:
01002 typedef MapType map_type;
01003 typedef NodeType node_type;
01004
01005 typedef typename node_type::idx_type idx_type;
01006
01007 mapped_new_node(const map_type& the_map): m_map(the_map) {}
01008
01009 NodeType operator()(idx_type idx,
01010 const node_type& first, const node_type& second) const{
01011 return ((TermType)VariableType(m_map[idx]))*first + second;
01012 }
01013
01014
01015
01016 private:
01017 const map_type& m_map;
01018 };
01019
01020
01025 template <class NewType>
01026 struct pbori_base;
01027
01028
01029
01030 template <class DDType>
01031 class get_node {
01032
01033 public:
01034 typename DDType::node_type operator()(const DDType& rhs) const {
01035 return rhs.getNode();
01036 }
01037 };
01038
01039 template<unsigned ErrorNumber = CUDD_INTERNAL_ERROR>
01040 struct handle_error {
01041 typedef mgrcore_traits<Cudd>::errorfunc_type errorfunc_type;
01042
01043 handle_error(errorfunc_type errfunc): m_errfunc(errfunc) {}
01044
01045 bool found(unsigned err) const {
01046 if UNLIKELY(err == ErrorNumber) {
01047 m_errfunc(cudd_error_traits<ErrorNumber>()());
01048 return true;
01049 }
01050 return false;
01051 }
01052
01053 void operator()(unsigned err) const {
01054 if UNLIKELY(err == ErrorNumber)
01055 m_errfunc(cudd_error_traits<ErrorNumber>()());
01056 else
01057 reinterpret_cast<const handle_error<ErrorNumber - 1>&>(*this)(err);
01058 }
01059
01060 protected:
01061 const errorfunc_type m_errfunc;
01062 };
01063
01064
01065 template<>
01066 struct handle_error<0> {
01067 typedef mgrcore_traits<Cudd>::errorfunc_type errorfunc_type;
01068
01069 handle_error(errorfunc_type errfunc): m_errfunc(errfunc) {}
01070
01071 void operator()(unsigned err) const {
01072 if LIKELY(err == 0)
01073 m_errfunc(cudd_error_traits<0>()());
01074 }
01075 protected:
01076 errorfunc_type m_errfunc;
01077 };
01078
01079
01080 END_NAMESPACE_PBORI
01081
01082 #endif