Comparing Script Objects
When implementing a container for script objects, you need a way to compare elements —
for operator==, operator<=>, std::sort, or deduplication.
AngelScript classes can define opEquals and opCmp methods,
but calling them from C++ requires discovering them at runtime.
container/compare.hpp provides tools to inspect a script type for these methods
and invoke them through a uniform interface.
Note
The content of this file is designed for library developers implementing containers. If you are not building a custom container for script objects, you likely do not need these APIs.
Discovering Comparators
Call get_comparator with an asITypeInfo* to scan the type’s methods.
It looks for methods matching these signatures:
bool opEquals(const T&in) constint opCmp(const T&in) const
#include <asbind20/container/compare.hpp>
asITypeInfo* ti = /* ... */;
auto result = asbind20::container::get_comparator(ti);
auto status = result.get_status();
if(status.opCmp >= 0) {
// type has opCmp
}
if(status.opEquals >= 0) {
// type has opEquals
}
if(!status.good()) {
// neither method found — type is not comparable
}
asbind20::container::script_element_comparator cmp = result.get();
Using the Comparator
Once obtained, script_element_comparator provides eq() and compare()
that invoke the discovered script methods. Both take a script context and two const void*
pointers to the elements.
asIScriptContext* ctx = /* ... */;
const void* lhs = /* pointer to first element */;
const void* rhs = /* pointer to second element */;
// Check equality — uses opEquals when available, otherwise falls back to opCmp() == 0
if(cmp.eq(ctx, lhs, rhs)) {
// elements are equal
}
// Compare — returns std::partial_ordering (unordered if comparison fails or is unavailable)
std::partial_ordering ord = cmp.compare(ctx, lhs, rhs);
if(ord < 0) {
// lhs < rhs
} else if(ord == 0) {
// lhs == rhs
} else if(ord > 0) {
// lhs > rhs
}
// For more control, invoke the underlying script_method objects directly:
auto eq_result = cmp.invoke_eq(ctx, lhs, rhs);
if(eq_result.has_value() && eq_result.value()) {
// ...
}
Checking Availability
if(cmp.has_opEquals()) { /* opEquals is available */ }
if(cmp.has_opCmp()) { /* opCmp is available */ }
if(cmp) { /* at least one comparison method exists */ }
Integration with Containers
A typical pattern for a container implementing operator==:
template <typeinfo_policy TypeInfoPolicy>
bool my_container::operator==(const my_container& other) const
{
if(this->size() != other.size())
return false;
auto cmp = container::get_comparator(this->element_type_info()).get();
if(!cmp)
return false; // not comparable — treat as not equal
request_context ctx(this->get_engine());
for(std::size_t i = 0; i < this->size(); ++i) {
if(!cmp.eq(ctx, (*this)[i], other[i]))
return false;
}
return true;
}
-
class script_element_comparator
Public Types
-
using opEquals_type = script_method<bool(const void*)>
-
using opCmp_type = script_method<int(const void*)>
Public Functions
-
script_element_comparator() = default
-
script_element_comparator(const script_element_comparator&) = default
-
script_element_comparator &operator=(const script_element_comparator&) = default
-
inline script_element_comparator(asIScriptFunction *opCmp, asIScriptFunction *opEquals)
-
inline const opEquals_type &get_opEquals() const noexcept
-
inline bool has_opEquals() const noexcept
-
inline const opCmp_type &get_opCmp() const noexcept
-
inline bool has_opCmp() const noexcept
-
inline auto invoke_eq(asIScriptContext *ctx, const void *lhs, const void *rhs) const -> script_invoke_result<bool>
-
inline auto invoke_compare(asIScriptContext *ctx, const void *lhs, const void *rhs) const -> script_invoke_result<int>
-
inline std::partial_ordering compare(asIScriptContext *ctx, const void *lhs, const void *rhs) const
Comparing two script objects.
- Parameters:
ctx – Script context
lhs – Left object
rhs – Right object
- Returns:
std::partial_ordering Object relationship, or
partial_ordering::unorderedwhen error occurred.
-
inline bool eq(asIScriptContext *ctx, const void *lhs, const void *rhs) const
-
inline explicit operator bool() const noexcept
-
using opEquals_type = script_method<bool(const void*)>
-
class get_comparator_result
Public Types
-
using error_type = status::error_type
Public Functions
-
get_comparator_result() = delete
-
get_comparator_result(const get_comparator_result&) = default
-
~get_comparator_result() = default
-
get_comparator_result &operator=(const get_comparator_result&) = default
-
inline script_element_comparator get() const
-
inline explicit operator bool() const noexcept
-
inline explicit operator script_element_comparator() const
-
using error_type = status::error_type
-
inline get_comparator_result asbind20::container::get_comparator(asITypeInfo *ti)