PolyBoRi
pbori_func.h
Go to the documentation of this file.
1 // -*- c++ -*-
2 //*****************************************************************************
13 //*****************************************************************************
14 
15 #ifndef polybori_routines_pbori_func_h_
16 #define polybori_routines_pbori_func_h_
17 
18 // get polybori definitions
19 #include <polybori/pbori_defs.h>
20 
21 // get polybori properties
22 #include <polybori/common/traits.h>
23 
24 // get standard string and string stream functionality
25 #include <string>
26 #include <sstream>
27 
28 
29 #ifdef PBORI_HAVE_TR1_UNORDERED_MAP
30 # include <tr1/unordered_map>
31 #else
32 # ifdef PBORI_HAVE_UNORDERED_MAP
33 # include <unordered_map>
34 # else
35 # ifdef PBORI_HAVE_HASH_MAP
36 # include <ext/hash_map>
37 # else
38 # include <map>
39 # endif
40 # endif
41 #endif
42 
44 
47 template <class ListType, class ValueType = typename ListType::value_type >
48 class push_back {
49 public:
50 
51  ListType
52  operator()(ListType theList, const ValueType& elt) const {
53  theList.push_back(elt);
54  return theList;
55  }
56 };
57 
60 template <class RhsType, class LhsType = typename RhsType::idx_type >
61 class change_idx {
62 public:
63 
64  RhsType operator() (const RhsType& rhs, const LhsType& lhs) const {
65  return (rhs.change(lhs));
66  }
67 
68 };
69 
72 template <class RhsType = void,
73  class LhsType = typename pbori_traits<RhsType>::idx_type >
75 
76 // default variant
77 template <class RhsType, class LhsType>
78 class change_assign {
79 public:
80 
81  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
82  return (rhs = rhs.change(lhs));
83  }
84 
85 };
86 
87 // template specialization
88 template<>
89 class change_assign<void, pbori_traits<void>::idx_type> {
90 public:
91 
92  template <class RhsType, class LhsType>
93  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
94  return (rhs = rhs.change(lhs));
95  }
96 
97 };
98 
101 template <class RhsType, class LhsType = typename RhsType::idx_type>
103 public:
104 
105  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
106 
107  rhs = rhs.subset1(lhs);
108  return rhs;
109  }
110 };
111 
114 template <class RhsType, class LhsType>
116 public:
117 
118  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
119  return (rhs = rhs.subset0(lhs));
120  }
121 };
124 template <class RhsType,
125  class LhsType = typename pbori_traits<RhsType>::idx_type >
127  public std::binary_function<RhsType&, const LhsType&, RhsType&> {
128 
129 public:
130  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
131  return (rhs = rhs.unite(lhs));
132  }
133 };
134 
135 
136 // @class project_ith
142 
143 template <unsigned int ITH, unsigned int NLEN = ITH>
145 
148 template <unsigned int NLEN>
149 class project_ith<0, NLEN> {
150 
151 public:
153  template <class ValueType>
154  void operator() (const ValueType&, ...) const { }
155 };
156 
159 template <unsigned int NLEN>
160 class project_ith<1, NLEN> {
161 
162 public:
164  template <class ValueType>
165  const ValueType& operator() (const ValueType& value, ...) const {
166  return value;
167  }
168 
170  template <class ValueType>
171  ValueType& operator() (ValueType& value, ...) const {
172  return value;
173  }
174 };
175 
176 
179 template <unsigned int NLEN>
180 class project_ith<2, NLEN> {
181 
182 public:
184  template <class FirstType, class ValueType>
185  const ValueType&
186  operator() (const FirstType&, const ValueType& value, ...) const {
187  return value;
188  }
189 
191  template <class FirstType, class ValueType>
192  ValueType& operator() (const FirstType&, ValueType& value, ...) const {
193  return value;
194  }
195 };
196 
197 
200 template <unsigned int NLEN>
201 class project_ith<3, NLEN> {
202 
203 public:
205  template <class FirstType, class SecondType, class ValueType>
206  const ValueType&
207  operator() (const FirstType&, const SecondType&,
208  const ValueType& value, ...) const {
209  return value;
210  }
211 
213  template <class FirstType, class SecondType, class ValueType>
214  ValueType& operator() (const FirstType&, const SecondType&,
215  ValueType& value, ...) const {
216  return value;
217  }
218 };
219 
220 /*
221 class print_all {
222 public:
223 
224  print_all(std::ostream& os_):os(os_){}
225 
226  template<class Type>
227  Type& operator()(Type& val){
228  std::copy(val.begin(), val.end(),
229  std::ostream_iterator<typename Type::value_type>(os, ", "));
230  return val;
231  }
232  std::ostream& os;
233 };
234 */
235 
239 public:
240 
242  typedef dummy_iterator self;
243 
244  template <class Type>
245  const self& operator=(const Type&) const { return *this;}
246 
247  const self& operator*() const { return *this;}
248  const self& operator++() const { return *this;}
249  const self& operator++(int) const { return *this;}
250 };
251 
252 template <>
254  public CTypes {
255 };
256 
262 template <class IntType, IntType INTCONST, class ResultType = IntType>
264 
265  typedef ResultType result_type;
266  enum { result = INTCONST };
267  result_type operator()(...) const { return result; }
268 };
269 
273 template <class BinaryOp, class FirstOp, class SecondOp>
275  public BinaryOp {
276 
277 public:
278 
280 
281  typedef BinaryOp base;
282  typedef FirstOp first_op_type;
283  typedef SecondOp second_op_type;
285 
286  // Constructor
287  binary_composition(const base& binop = base(),
288  const first_op_type& unop1 = first_op_type(),
289  const second_op_type& unop2 = second_op_type() ):
290  base(binop), first_op(unop1), second_op(unop2) {}
291 
293  typedef typename base::result_type result_type;
294 
296  template <class FirstType, class SecondType>
297  result_type operator()(const FirstType& first,
298  const SecondType& second) const {
299  return base::operator()(first_op(first), second_op(second));
300  }
301 
303  template <class FirstType, class SecondType>
304  result_type operator()(FirstType& first,
305  const SecondType& second) const {
306  return base::operator()(first_op(first), second_op(second));
307  }
308 
310  template <class FirstType, class SecondType>
311  result_type operator()(const FirstType& first,
312  SecondType& second) const {
313  return base::operator()(first_op(first), second_op(second));
314  }
315 
316 protected:
319 };
320 
324 template <class BinaryOp, class UnaryOperation>
326  public binary_composition<BinaryOp, UnaryOperation, UnaryOperation> {
327 
328 public:
329 
331 
332  typedef BinaryOp binary_op_type;
333  typedef UnaryOperation unary_op_type;
337 
338  // Constructor
340  const unary_op_type& unop = unary_op_type() ):
341  base(binop, unop, unop) {}
342 };
343 
346 template<class ValueType>
348 public:
349  maximum_iteration(ValueType & init) : max(init){}
350 
351  ValueType& operator()(const ValueType& val) const {
352  return max = std::max(max, val);
353  }
354 
355 private:
356  ValueType & max;
357 };
358 
361 template <class DDType>
363 public:
364 
365  DDType& operator()(DDType& lhs, const DDType& rhs) const {
366  // several possible implementations
367  return
368 #if defined(PBORI_ADD_BY_OR)
369  (lhs = (lhs.diff(rhs)).unite(rhs.diff(lhs)));
370 
371 # elif defined(PBORI_ADD_BY_UNION)
372  (lhs = lhs.unite(rhs).diff( lhs.intersect(rhs) ) );
373 # elif defined(PBORI_ADD_BY_EXTRA_XOR) || defined(PBORI_ADD_BY_XOR)
374  (lhs = lhs.Xor(rhs));
375 #endif
376  }
377 };
378 
381 template <class DDType, class IdxType = typename DDType::idx_type>
383 public:
384 
385  DDType& operator()(DDType& lhs, IdxType idx) const {
386 
387  // get all terms not containing the variable with index idx
388  DDType tmp( lhs.subset0(idx) );
389 
390  // get the complementary terms
391  lhs = lhs.diff(tmp);
392 
393  // construct polynomial terms
394  dd_add_assign<DDType>()(lhs, tmp.change(idx));
395 
396  return lhs;
397  }
398 
399 };
400 
403 template <class DDType, class IdxType = typename DDType::idx_type>
405 public:
406 
407  DDType& operator()(DDType& lhs, IdxType idx) const {
408 
409  lhs = lhs.unite( lhs.change(idx) );
410  return lhs;
411  }
412 
413 };
414 
417 // template <class RhsType = void,
418 // class LhsType = typename RhsType::value_type >
419 // class inserts:
420 // public std::binary_function<RhsType&, const LhsType&, RhsType&> {
421 // public:
422 
423 // RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
424 // rhs.insert(lhs);
425 // return rhs;
426 // }
427 
428 // };
429 
430 
433 template <class RhsType = void,
434  class LhsType = typename pbori_traits<RhsType>::idx_type >
435 class inserts;
436 
437 template <class RhsType, class LhsType>
438 class inserts:
439  public std::binary_function<RhsType&, const LhsType&, RhsType&> {
440 public:
441 
442  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
443  rhs.insert(lhs);
444  return rhs;
445  }
446 };
447 
448 template <>
449 class inserts<void, pbori_traits<void>::idx_type> {
450 public:
451 template <class RhsType, class LhsType>
452  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
453  rhs.insert(lhs);
454  return rhs;
455  }
456 };
457 
458 
461 template <class RhsType = void,
462  class LhsType = typename pbori_traits<RhsType>::idx_type >
464 
465 template <class RhsType, class LhsType>
466 class insert_assign:
467  public std::binary_function<RhsType&, const LhsType&, RhsType&> {
468 public:
469 
470  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
471  rhs.insertAssign(lhs);
472  return rhs;
473  }
474 };
475 
476 template <>
477 class insert_assign<void, pbori_traits<void>::idx_type> {
478 public:
479 template <class RhsType, class LhsType>
480  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
481  rhs.insertAssign(lhs);
482  return rhs;
483  }
484 };
485 
486 
487 
490 template <class RhsType = void,
491  class LhsType = typename pbori_traits<RhsType>::idx_type >
492 class removes;
493 
494 
495 template <class RhsType, class LhsType>
496 class removes:
497  public std::binary_function<RhsType&, const LhsType&, RhsType&> {
498 public:
499 
500  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
501  rhs.remove(lhs);
502  return rhs;
503  }
504 };
505 
506 
507 template <>
508 class removes<void, pbori_traits<void>::idx_type> {
509 public:
510 
511  template <class RhsType, class LhsType>
512  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
513  rhs.remove(lhs);
514  return rhs;
515  }
516 };
517 
520 template <class RhsType = void,
521  class LhsType = typename pbori_traits<RhsType>::idx_type >
523 
524 
525 template <class RhsType, class LhsType>
526 class remove_assign:
527  public std::binary_function<RhsType&, const LhsType&, RhsType&> {
528 public:
529 
530  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
531  rhs.removeAssign(lhs);
532  return rhs;
533  }
534 };
535 
536 
537 template <>
538 class remove_assign<void, pbori_traits<void>::idx_type> {
539 public:
540 
541  template <class RhsType, class LhsType>
542  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
543  rhs.removeAssign(lhs);
544  return rhs;
545  }
546 };
547 
550 template <class ListType, class RhsType, class LhsType>
552 public:
553 
554  insert_second_to_list(ListType& theList__):
555  theList(theList__) {};
556 
557  RhsType& operator() (RhsType& rhs, const LhsType& lhs) const {
558  theList.insert(lhs);
559  return rhs;
560  }
561 
562 private:
563  ListType& theList;
564 };
565 
566 
570 template <class Type1, class Type2>
572 
573 template <class Type>
574 class is_same_type<Type, Type>:
575  public integral_constant<CTypes::bool_type, true> {};
576 
577 template <class Type1, class Type2>
578 class is_same_type:
579  public integral_constant<CTypes::bool_type, false> {};
580 
581 template <class Type>
582 class is_valid:
583  public is_same_type<Type, valid_tag> {};
584 
588 template <class Type1, class Type2, class ThenType, class ElseType>
590 
591 template <class Type, class ThenType, class ElseType>
592 class on_same_type<Type, Type, ThenType, ElseType> {
593 public:
594  typedef ThenType type;
595 };
596 
597 template <class Type1, class Type2, class ThenType, class ElseType>
598 class on_same_type {
599 public:
600  typedef ElseType type;
601 };
602 
603 
607 struct internal_tag {};
608 
612 template<class Type>
613 struct type_tag {};
614 
615 template <class Type>
616 class hashes {
617 public:
618 
619  typedef typename Type::hash_type hash_type;
620 
621  hash_type operator() (const Type& rhs) const{
622  return rhs.hash();
623  }
624 };
625 
626 template <class Type>
628 
629  typedef typename Type::idx_type idx_type;
630 public:
632 
633 #ifdef PBORI_HAVE_TR1_UNORDERED_MAP
634  typedef std::tr1::unordered_map<Type, idx_type, hashes<Type> > type;
635 #else
636 # ifdef PBORI_HAVE_UNORDERED_MAP
637  typedef std::unordered_map<Type, idx_type, hashes<Type> > type;
638 # else
639 # ifdef PBORI_HAVE_HASH_MAP
640  typedef __gnu_cxx::hash_map<Type, idx_type, hashes<Type> > type;
641 # else
642  typedef std::map<Type, idx_type> type;
643 # endif
644 # endif
645 #endif
646 };
647 
651 template <class ListType>
653  public std::binary_function<const ListType&, const ListType&, bool> {
654 
655 public:
656  bool operator()(const ListType& lhs, const ListType& rhs) const {
657  return (lhs.size() < rhs.size());
658  }
659 };
660 
664 template <class BiIterator>
666 public:
667 
669  typedef BiIterator iterator;
670 
674 
675  typedef std::bidirectional_iterator_tag iterator_category;
676  typedef typename std::iterator_traits<iterator>::difference_type
678  typedef typename std::iterator_traits<iterator>::pointer pointer;
679  typedef typename std::iterator_traits<iterator>::reference reference;
680  typedef typename std::iterator_traits<iterator>::value_type value_type;
682 
685  m_iter(iter) {}
686 
688 
690  return *m_iter;
691  }
692 
694  self& operator++() {
695  --m_iter;
696  return *this;
697  }
698 
700  self& operator--() {
701  ++m_iter;
702  return *this;
703  }
704 
705  bool operator==(const self& rhs) const {
706  return m_iter == rhs.m_iter;
707  }
708 
709  bool operator!=(const self& rhs) const {
710  return m_iter != rhs.m_iter;
711  }
712  iterator get() const {
713  return m_iter;
714  }
715 
716 protected:
718 };
719 
720 
721 template <class DDType>
722 class navigates:
723  public std::unary_function<DDType, typename DDType::navigator> {
724 public:
726  typedef DDType dd_type;
727 
729  typedef typename DDType::navigator navigator;
730 
732  typedef std::unary_function<dd_type, navigator> base;
733 
735  typename base::result_type operator()(const dd_type& rhs) const{
736  return rhs.navigation();
737  }
738 
739 };
740 
741 
742 template <class ValueType>
744 public:
745  typedef ValueType value_type;
746 
747  value_type operator()(...) const{
748  return value_type();
749  }
750 
751 };
752 
753 template <template<class> class BindType, class BinaryFunction,
754  class ValueType, class ConstantOp>
756  public BindType<BinaryFunction>{
757 public:
758  typedef BinaryFunction bin_op;
759  typedef ConstantOp const_type;
760  typedef BindType<bin_op> base;
761 
762  typedef ValueType value_type;
763 
764  constant_binder_base(const bin_op& op = bin_op()): base(op, const_type()()) {}
765 };
766 
767 template <class BinaryFunction, class ConstantOp>
769  public constant_binder_base<std::binder2nd, BinaryFunction,
770  typename BinaryFunction::second_argument_type,
771  ConstantOp> {
772 };
773 
774 
775 template <class BinaryFunction, class ConstantOp>
777  public constant_binder_base<std::binder1st, BinaryFunction,
778  typename BinaryFunction::first_argument_type,
779  ConstantOp> {
780 };
781 
782 template <template<class> class BindType,
783  class BinaryFunction, class ValueType>
785  public BindType<BinaryFunction>{
786 public:
787  typedef BinaryFunction bin_op;
788  typedef BindType<bin_op> base;
789 
790  typedef ValueType value_type;
791 
792  default_binder_base(const value_type& val): base(bin_op(), val) {}
793 };
794 
795 template <class BinaryFunction>
797  public default_binder_base<std::binder2nd, BinaryFunction,
798  typename BinaryFunction::second_argument_type> {
799 public:
800  typedef default_binder_base<std::binder2nd, BinaryFunction,
801  typename BinaryFunction::second_argument_type>
803 
804  default_binder2nd(const typename base::value_type& val): base(val) {}
805 };
806 
807 
808 template <class BinaryFunction>
810  public default_binder_base<std::binder1st, BinaryFunction,
811  typename BinaryFunction::first_argument_type> {
812 };
813 
814 // /** @class property_owner
815 // * @brief defines generic base for properties
816 // **/
817 // template <class ValidityTag>
818 // class property_owner {
819 // public:
820 
821 // /// Set marker for validity
822 // typedef typename
823 // on_same_type<ValidityTag, valid_tag, valid_tag, invalid_tag>::type property;
824 
825 // /// Generate Boolean member function
826 // is_same_type<property, valid_tag> hasProperty;
827 // };
828 
832 template <class ManagerType,
833  class IdxType = typename ManagerType::idx_type,
834  class VarNameType = typename ManagerType::const_varname_reference>
836 public:
837  typedef ManagerType manager_type;
838  typedef IdxType idx_type;
839  typedef VarNameType varname_type;
840 
842  variable_name(const manager_type& mgr): m_mgr(mgr) {}
843 
846  return m_mgr.getVariableName(idx);
847  }
848 
849 protected:
852 };
853 
854 template <class MapType, class VariableType, class TermType, class NodeType>
856 public:
857  typedef MapType map_type;
858  typedef NodeType node_type;
859 
860  typedef typename node_type::idx_type idx_type;
861 
862  mapped_new_node(const map_type& the_map): m_map(the_map) {}
863 
864  NodeType operator()(idx_type idx,
865  const node_type& first, const node_type& second) const{
866  return ((TermType)VariableType(m_map[idx]))*first + second;
867  }
868 
869 
870 
871 private:
872  const map_type& m_map;
873 };
874 
875 
880 template <class NewType>
881 struct pbori_base;
882 
883 
884 
885 template <class DDType>
886 class get_node {
887 
888 public:
889  typename DDType::node_type operator()(const DDType& rhs) const {
890  return rhs.getNode();
891  }
892 };
893 
894 // template<unsigned ErrorNumber = CUDD_INTERNAL_ERROR>
895 // struct handle_error {
896 // typedef mgrcore_traits<Cudd>::errorfunc_type errorfunc_type;
897 
898 // handle_error(errorfunc_type errfunc): m_errfunc(errfunc) {}
899 
900 // bool found(unsigned err) const {
901 // if PBORI_UNLIKELY(err == ErrorNumber) {
902 // m_errfunc(cudd_error_traits<ErrorNumber>()());
903 // return true;
904 // }
905 // return false;
906 // }
907 
908 // void operator()(unsigned err) const {
909 // if PBORI_UNLIKELY(err == ErrorNumber)
910 // m_errfunc(cudd_error_traits<ErrorNumber>()());
911 // else
912 // reinterpret_cast<const handle_error<ErrorNumber - 1>&>(*this)(err);
913 // }
914 
915 // protected:
916 // const errorfunc_type m_errfunc;
917 // };
918 
919 
920 // template<>
921 // struct handle_error<0> {
922 // typedef mgrcore_traits<Cudd>::errorfunc_type errorfunc_type;
923 
924 // handle_error(errorfunc_type errfunc): m_errfunc(errfunc) {}
925 
926 // void operator()(unsigned err) const {
927 // if PBORI_LIKELY(err == 0)
928 // m_errfunc(cudd_error_traits<0>()());
929 // }
930 // protected:
931 // errorfunc_type m_errfunc;
932 // };
933 
934 
936 
937 #endif