+/** Comparison policy: use std::equal_to/std::less (defaults to operators
+ * == and <) to compare structures. */
+template <class T>
+class compare_std_less {
+protected:
+ static bool struct_is_equal(const T * t1, const T * t2)
+ {
+ return std::equal_to<T>()(*t1, *t2);
+ }
+
+ static int struct_compare(const T * t1, const T * t2)
+ {
+ if (std::less<T>()(*t1, *t2))
+ return -1;
+ else if (std::less<T>()(*t2, *t1))
+ return 1;
+ else
+ return 0;
+ }
+
+ // disallow destruction of structure through a compare_std_less*
+protected:
+ ~compare_std_less() {}
+};
+
+
+/** Comparison policy: use bit-wise comparison to compare structures. */
+template <class T>
+class compare_bitwise {
+protected:
+ static bool struct_is_equal(const T * t1, const T * t2)
+ {
+ const char * cp1 = reinterpret_cast<const char *>(t1);
+ const char * cp2 = reinterpret_cast<const char *>(t2);
+
+ return std::equal(cp1, cp1 + sizeof(T), cp2);
+ }
+
+ static int struct_compare(const T * t1, const T * t2)
+ {
+ const unsigned char * cp1 = reinterpret_cast<const unsigned char *>(t1);
+ const unsigned char * cp2 = reinterpret_cast<const unsigned char *>(t2);
+ typedef std::pair<const unsigned char *, const unsigned char *> cppair;
+
+ cppair res = std::mismatch(cp1, cp1 + sizeof(T), cp2);
+
+ if (res.first == cp1 + sizeof(T))
+ return 0;
+ else if (*res.first < *res.second)
+ return -1;
+ else
+ return 1;
+ }
+
+ // disallow destruction of structure through a compare_bitwise*
+protected:
+ ~compare_bitwise() {}
+};
+
+
+// Select default comparison policy
+template <class T, template <class> class ComparisonPolicy = compare_all_equal> class structure;
+
+
+/** Wrapper template for making GiNaC classes out of C++ structures. */
+template <class T, template <class> class ComparisonPolicy>
+class structure : public basic, public ComparisonPolicy<T> {