X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?a=blobdiff_plain;f=ginac%2Futils.h;h=78334b17d25ac4047b5a7d35eef4e83841b0edb1;hb=20c5db11ca1de4246138ece93605463e94f3b769;hp=29eef7cad8753edd12f12af3430ba13ddad58fd2;hpb=c5ca06e3a25226684028dec4bd8cba0833998be6;p=ginac.git diff --git a/ginac/utils.h b/ginac/utils.h index 29eef7ca..78334b17 100644 --- a/ginac/utils.h +++ b/ginac/utils.h @@ -28,37 +28,18 @@ #include #include -#include -#if defined(HAVE_SSTREAM) -#include -#elif defined(HAVE_STRSTREAM) -#include -#else -#error Need either sstream or strstream -#endif #include "assertion.h" namespace GiNaC { -// This should be obsoleted once is widely deployed. -template -std::string ToString(const T & t) -{ -#if defined(HAVE_SSTREAM) - std::ostringstream buf; - buf << t << std::ends; - return buf.str(); -#else - char buf[256]; - std::ostrstream(buf,sizeof(buf)) << t << std::ends; - return buf; -#endif -} - /** Exception class thrown by classes which provide their own series expansion * to signal that ordinary Taylor expansion is safe. */ class do_taylor {}; +/** Exception class thrown by functions to signal unimplemented functionality + * so the expression may just be .hold() */ +class dunno {}; + /** Exception class thrown when a singularity is encountered. */ class pole_error : public std::domain_error { public: @@ -183,8 +164,8 @@ int permutation_sign(It first, It last) return sign; } -template -int permutation_sign(It first, It last, Cmp comp) +template +int permutation_sign(It first, It last, Cmp comp, Swap swapit) { if (first == last) return 0; @@ -200,7 +181,7 @@ int permutation_sign(It first, It last, Cmp comp) bool swapped = false; while (i != first) { if (comp(*i, *other)) { - std::iter_swap(other, i); + swapit(*other, *i); flag = other; swapped = true; sign = -sign; @@ -219,7 +200,7 @@ int permutation_sign(It first, It last, Cmp comp) swapped = false; while (i != last) { if (comp(*other, *i)) { - std::iter_swap(i, other); + swapit(*i, *other); flag = other; swapped = true; sign = -sign; @@ -237,8 +218,8 @@ int permutation_sign(It first, It last, Cmp comp) } /* Implementation of shaker sort, only compares adjacent elements. */ -template -void shaker_sort(It first, It last, Cmp comp) +template +void shaker_sort(It first, It last, Cmp comp, Swap swapit) { if (first == last) return; @@ -253,7 +234,7 @@ void shaker_sort(It first, It last, Cmp comp) bool swapped = false; while (i != first) { if (comp(*i, *other)) { - std::iter_swap(other, i); + swapit(*other, *i); flag = other; swapped = true; } @@ -270,7 +251,7 @@ void shaker_sort(It first, It last, Cmp comp) swapped = false; while (i != last) { if (comp(*other, *i)) { - std::iter_swap(i, other); + swapit(*i, *other); flag = other; swapped = true; } @@ -284,8 +265,8 @@ void shaker_sort(It first, It last, Cmp comp) } /* In-place cyclic permutation of a container (no copying, only swapping). */ -template -void cyclic_permutation(It first, It last, It new_first) +template +void cyclic_permutation(It first, It last, It new_first, Swap swapit) { unsigned num = last - first; again: @@ -296,7 +277,7 @@ again: if (num1 >= num2) { It a = first, b = new_first; while (b != last) { - std::iter_swap(a, b); + swapit(*a, *b); ++a; ++b; } if (num1 > num2) { @@ -308,7 +289,7 @@ again: It a = new_first, b = last; do { --a; --b; - std::iter_swap(a, b); + swapit(*a, *b); } while (a != first); last -= num1; num = num2; @@ -316,14 +297,6 @@ again: } } -/* Function objects for STL sort() etc. */ -struct ex_is_less : public std::binary_function { - bool operator() (const ex &lh, const ex &rh) const { return lh.compare(rh) < 0; } -}; - -struct ex_is_equal : public std::binary_function { - bool operator() (const ex &lh, const ex &rh) const { return lh.is_equal(rh); } -}; // Collection of `construct on first use' wrappers for safely avoiding // internal object replication without running into the `static @@ -485,7 +458,7 @@ int classname::compare_same_type(const basic & other) const \ void classname::print(const print_context & c, unsigned level) const \ { \ debugmsg(#classname " print", LOGLEVEL_PRINT); \ - if (is_of_type(c, print_tree)) \ + if (is_a(c)) \ inherited::print(c, level); \ else \ c.s << text; \ @@ -495,14 +468,30 @@ void classname::print(const print_context & c, unsigned level) const \ void classname::print(const print_context & c, unsigned level) const \ { \ debugmsg(#classname " print", LOGLEVEL_PRINT); \ - if (is_of_type(c, print_tree)) \ + if (is_a(c)) \ inherited::print(c, level); \ - else if (is_of_type(c, print_latex)) \ + else if (is_a(c)) \ c.s << latex; \ else \ c.s << text; \ } +// Obsolete convenience macros. TO BE PHASED OUT SOON! +// Use the inlined template functions in basic.h instead. (FIXME: remove them) + +#define is_of_type(OBJ,TYPE) \ + (dynamic_cast(&OBJ)!=0) + +#define is_exactly_of_type(OBJ,TYPE) \ + ((OBJ).tinfo()==GiNaC::TINFO_##TYPE) + +#define is_ex_of_type(OBJ,TYPE) \ + (dynamic_cast((OBJ).bp)!=0) + +#define is_ex_exactly_of_type(OBJ,TYPE) \ + ((*(OBJ).bp).tinfo()==GiNaC::TINFO_##TYPE) + } // namespace GiNaC + #endif // ndef __GINAC_UTILS_H__