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:
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; }
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__