]> www.ginac.de Git - ginac.git/blobdiff - ginac/ex.h
series expansion behaviour fixed.
[ginac.git] / ginac / ex.h
index 3c8094b1b405b1717f5cc05ce8ae74f0563055a7..e9f09fccd9b5153743c3e641348f89be0e5bb037 100644 (file)
@@ -67,12 +67,10 @@ class scalar_products;
 class ex
 {
        friend class archive_node;
-       friend bool are_ex_trivially_equal(const ex &, const ex &);
-       template<class T> friend const T &ex_to(const ex &);
-       template<class T> friend bool is_a(const ex &);
-       template<class T> friend bool is_exactly_a(const ex &);
-       
-// member functions
+       friend inline bool are_ex_trivially_equal(const ex &, const ex &);
+       template<class T> friend inline const T &ex_to(const ex &);
+       template<class T> friend inline bool is_a(const ex &);
+       template<class T> friend inline bool is_exactly_a(const ex &);
        
        // default ctor, dtor, copy ctor, assignment operator and helpers
 public:
@@ -475,11 +473,6 @@ inline bool is_zero(const ex & thisex)
 inline void swap(ex & e1, ex & e2)
 { e1.swap(e2); }
 
-// This makes STL algorithms use the more efficient swap operation for ex objects
-inline void iter_swap(std::vector<ex>::iterator i1, std::vector<ex>::iterator i2)
-{ i1->swap(*i2); }
-
-
 /* Function objects for STL sort() etc. */
 struct ex_is_less : public std::binary_function<ex, ex, bool> {
        bool operator() (const ex &lh, const ex &rh) const { return lh.compare(rh) < 0; }
@@ -546,7 +539,57 @@ inline ex ex::map(ex (*f)(const ex & e)) const
        return bp->map(fcn);
 }
 
+// convenience type checker template functions
+
+/** Check if ex is a handle to a T, including base classes. */
+template <class T>
+inline bool is_a(const ex &obj)
+{
+       return is_a<T>(*obj.bp);
+}
+
+/** Check if ex is a handle to a T, not including base classes. */
+template <class T>
+inline bool is_exactly_a(const ex &obj)
+{
+       return is_exactly_a<T>(*obj.bp);
+}
+
+/** Return a reference to the basic-derived class T object embedded in an
+ *  expression.  This is fast but unsafe: the result is undefined if the
+ *  expression does not contain a T object at its top level.  Hence, you
+ *  should generally check the type of e first.
+ *
+ *  @param e expression
+ *  @return reference to object of class T
+ *  @see is_exactly_a<class T>() */
+template <class T>
+inline const T &ex_to(const ex &e)
+{
+       GINAC_ASSERT(is_a<T>(e));
+       return static_cast<const T &>(*e.bp);
+}
 
 } // namespace GiNaC
 
+
+// Specializations of Standard Library algorithms
+namespace std {
+
+/** Specialization of std::swap() for ex objects. */
+template <>
+inline void swap(GiNaC::ex &a, GiNaC::ex &b)
+{
+       a.swap(b);
+}
+
+/** Specialization of std::iter_swap() for vector<ex> iterators. */
+template <>
+inline void iter_swap(vector<GiNaC::ex>::iterator i1, vector<GiNaC::ex>::iterator i2)
+{
+       i1->swap(*i2);
+}
+
+} // namespace std
+
 #endif // ndef __GINAC_EX_H__