summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hodge <tpg@mutabah.net>2015-03-30 17:52:31 +0800
committerJohn Hodge <tpg@mutabah.net>2015-03-30 17:52:31 +0800
commitace202ef3d35cb5010e9164900c2c825dd6d3e8e (patch)
tree62fb10e28e795aef13c82d7717384b1affb3c3da
parent86e4115964dee385d167fda110ed700012168d06 (diff)
downloadmrust-ace202ef3d35cb5010e9164900c2c825dd6d3e8e.tar.gz
Add ordering to TypeRef and Path (to generalise operator== and operator<
-rw-r--r--src/ast/path.cpp24
-rw-r--r--src/ast/path.hpp6
-rw-r--r--src/common.hpp53
-rw-r--r--src/types.cpp39
-rw-r--r--src/types.hpp6
5 files changed, 105 insertions, 23 deletions
diff --git a/src/ast/path.cpp b/src/ast/path.cpp
index c06a63a4..381685a9 100644
--- a/src/ast/path.cpp
+++ b/src/ast/path.cpp
@@ -25,9 +25,14 @@ const ::std::vector<TypeRef>& PathNode::args() const
{
return m_params;
}
-bool PathNode::operator==(const PathNode& x) const
+Ordering PathNode::ord(const PathNode& x) const
{
- return m_name == x.m_name && m_params == x.m_params;
+ Ordering rv;
+ rv = ::ord(m_name, x.m_name);
+ if(rv != OrdEqual) return rv;
+ rv = ::ord(m_params, x.m_params);
+ if(rv != OrdEqual) return rv;
+ return OrdEqual;
}
::std::ostream& operator<<(::std::ostream& os, const PathNode& pn) {
os << pn.m_name;
@@ -356,9 +361,20 @@ Path& Path::operator+=(const Path& other)
return *this;
}
-bool Path::operator==(const Path& x) const
+Ordering Path::ord(const Path& x) const
{
- return m_class == x.m_class && m_crate == x.m_crate && m_nodes == x.m_nodes;
+ Ordering rv;
+
+ rv = ::ord( (unsigned)m_class, (unsigned)x.m_class );
+ if( rv != OrdEqual ) return rv;
+
+ rv = ::ord( m_crate, x.m_crate );
+ if( rv != OrdEqual ) return rv;
+
+ rv = ::ord( m_nodes, x.m_nodes );
+ if( rv != OrdEqual ) return rv;
+
+ return OrdEqual;
}
void Path::print_pretty(::std::ostream& os) const
diff --git a/src/ast/path.hpp b/src/ast/path.hpp
index 1e70389d..94af94da 100644
--- a/src/ast/path.hpp
+++ b/src/ast/path.hpp
@@ -134,7 +134,8 @@ public:
::std::vector<TypeRef>& args() { return m_params; }
const ::std::vector<TypeRef>& args() const;
- bool operator==(const PathNode& x) const;
+ Ordering ord(const PathNode& x) const;
+ bool operator==(const PathNode& x) const { return ord(x) == OrdEqual; }
void print_pretty(::std::ostream& os) const;
friend ::std::ostream& operator<<(::std::ostream& os, const PathNode& pn);
@@ -263,7 +264,8 @@ public:
PathNode& operator[](int idx) { if(idx>=0) return m_nodes[idx]; else return m_nodes[size()+idx]; }
const PathNode& operator[](int idx) const { if(idx>=0) return m_nodes[idx]; else return m_nodes[size()+idx]; }
- bool operator==(const Path& x) const;
+ Ordering ord(const Path& x) const;
+ bool operator==(const Path& x) const { return ord(x) == OrdEqual; }
SERIALISABLE_PROTOTYPES();
void print_pretty(::std::ostream& os) const;
diff --git a/src/common.hpp b/src/common.hpp
index c39f8c07..4c8d5f23 100644
--- a/src/common.hpp
+++ b/src/common.hpp
@@ -15,6 +15,59 @@
#include "include/rustic.hpp" // slice and option
#include "include/compile_error.hpp"
+enum Ordering
+{
+ OrdLess,
+ OrdEqual,
+ OrdGreater,
+};
+template<typename T>
+Ordering ord(const ::std::vector<T>& l, const ::std::vector<T>& r)
+{
+ unsigned int i = 0;
+ for(const auto& it : l)
+ {
+ if( i > r.size() )
+ return OrdGreater;
+
+ auto rv = it.ord(r[i]);
+ if( rv != OrdEqual )
+ return rv;
+
+ i ++;
+ }
+
+ return OrdEqual;
+}
+static inline Ordering ord(bool l, bool r)
+{
+ if(l == r)
+ return OrdEqual;
+ else if( l )
+ return OrdGreater;
+ else
+ return OrdLess;
+}
+static inline Ordering ord(unsigned l, unsigned r)
+{
+ if(l == r)
+ return OrdEqual;
+ else if( l > r )
+ return OrdGreater;
+ else
+ return OrdLess;
+}
+static inline Ordering ord(const ::std::string& l, const ::std::string& r)
+{
+ if(l == r)
+ return OrdEqual;
+ else if( l > r )
+ return OrdGreater;
+ else
+ return OrdLess;
+}
+
+
template <typename T>
struct LList
{
diff --git a/src/types.cpp b/src/types.cpp
index 0d38ae26..a5b6d6ee 100644
--- a/src/types.cpp
+++ b/src/types.cpp
@@ -315,42 +315,51 @@ bool TypeRef::is_concrete() const
throw ::std::runtime_error( FMT("BUGCHECK - Invalid type class on " << *this) );
}
-bool TypeRef::operator==(const TypeRef& x) const
+Ordering TypeRef::ord(const TypeRef& x) const
{
- if(m_class != x.m_class)
- return false;
+ Ordering rv;
+
+ rv = ::ord( (unsigned)m_class, (unsigned)x.m_class );
+ if(rv != OrdEqual) return rv;
+
switch(m_class)
{
case TypeRef::NONE:
- return true;
+ return OrdEqual;
case TypeRef::ANY:
case TypeRef::UNIT:
- return true;
+ return OrdEqual;
case TypeRef::PRIMITIVE:
- return m_core_type == x.m_core_type;
+ rv = ::ord( (unsigned)m_core_type, (unsigned)x.m_core_type );
+ if(rv != OrdEqual) return rv;
+ return OrdEqual;
case TypeRef::FUNCTION:
- if( m_path[0].name() != x.m_path[0].name() )
- return false;
+ rv = ::ord(m_path[0].name(),x.m_path[0].name());
+ if(rv != OrdEqual) return rv;
+ return OrdEqual;
case TypeRef::TUPLE:
- return m_inner_types == x.m_inner_types;
+ return ::ord(m_inner_types, x.m_inner_types);
+ //return m_inner_types == x.m_inner_types;
case TypeRef::REFERENCE:
case TypeRef::POINTER:
- return m_is_inner_mutable == x.m_is_inner_mutable && m_inner_types == x.m_inner_types;
+ rv = ::ord(m_is_inner_mutable, x.m_is_inner_mutable);
+ if(rv != OrdEqual) return rv;
+ return ::ord(m_inner_types, x.m_inner_types);
case TypeRef::ARRAY:
- if(m_inner_types[0] != x.m_inner_types[0])
- return false;
+ rv = m_inner_types[0].ord( x.m_inner_types[0] );
+ if(rv != OrdEqual) return rv;
if(m_size_expr.get())
{
throw ::std::runtime_error("TODO: Sized array comparisons");
}
- return true;
+ return OrdEqual;
case TypeRef::GENERIC:
DEBUG(*this << " == " << x);
throw ::std::runtime_error("BUGCHECK - Can't compare generic type");
case TypeRef::PATH:
- return m_path == x.m_path;
+ return m_path.ord( x.m_path );
case TypeRef::MULTIDST:
- return m_inner_types == x.m_inner_types;
+ return ::ord(m_inner_types, x.m_inner_types);
}
throw ::std::runtime_error(FMT("BUGCHECK - Unhandled TypeRef class '" << m_class << "'"));
}
diff --git a/src/types.hpp b/src/types.hpp
index 5f7c6111..38f2b26b 100644
--- a/src/types.hpp
+++ b/src/types.hpp
@@ -188,8 +188,10 @@ public:
void add_trait(TypeRef trait) { assert(is_wildcard()); m_inner_types.push_back( ::std::move(trait) ); }
const ::std::vector<TypeRef>& traits() const { assert(is_wildcard()); return m_inner_types; }
- bool operator==(const TypeRef& x) const;
- bool operator!=(const TypeRef& x) const { return !(*this == x); }
+ Ordering ord(const TypeRef& x) const;
+ bool operator==(const TypeRef& x) const { return ord(x) == OrdEqual; }
+ bool operator!=(const TypeRef& x) const { return ord(x) != OrdEqual; }
+ bool operator<(const TypeRef& x) const { return ord(x) == OrdLess; };
PrettyPrintType print_pretty() const { return PrettyPrintType(*this); }