00001
00002
00013
00014
00015 #ifndef polybori_routines_pbori_func_h_
00016 #define polybori_routines_pbori_func_h_
00017
00018
00019 #include <polybori/pbori_defs.h>
00020
00021
00022 #include <polybori/common/traits.h>
00023
00024
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
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
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
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
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
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
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
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
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
00388 DDType tmp( lhs.subset0(idx) );
00389
00390
00391 lhs = lhs.diff(tmp);
00392
00393
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
00418
00419
00420
00421
00422
00423
00424
00425
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
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
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
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935 END_NAMESPACE_PBORI
00936
00937 #endif