cosmo

Trait

Traits

Traits are classes containing unimplemented methods, while you can provide default impls:

trait Unsigned(T: Type) {
assert(IsUnsigned(T.value));
def asUint64(self): u64 = staticCast(u64, self.value);
}
trait Unsigned(T: Type) {
assert(IsUnsigned(T.value));
def asUint64(self): u64 = staticCast(u64, self.value);
}
template <typename T>
struct UnsignedConcept {
virtual uint64_t asUint64() = 0;
virtual ~UnsignedConcept() = default;
};
template <typename T>
struct UnsignedModel: public UnsignedConcept<T> {
T& self;
UnsignedModel(T& self) : self(self) { static_assert(IsUnsigned<T::ValueT>::value); }
uint64_t asUint64() override {
return static_cast<uint64_t>(self.value);
}
};
template <typename T>
struct UnsignedConcept {
virtual uint64_t asUint64() = 0;
virtual ~UnsignedConcept() = default;
};
template <typename T>
struct UnsignedModel: public UnsignedConcept<T> {
T& self;
UnsignedModel(T& self) : self(self) { static_assert(IsUnsigned<T::ValueT>::value); }
uint64_t asUint64() override {
return static_cast<uint64_t>(self.value);
}
};

Trait Implementations

As you see, traits are dispatched in some C++ magic concepts.

impl(T <: U32 | U16 | U8) Unsigned(T) for T {
def asUint64(self): u64 = staticCast(u64, self);
}
impl(T <: U32 | U16 | U8) Unsigned(T) for T {
def asUint64(self): u64 = staticCast(u64, self);
}
template <typename T, typename Cond>
struct TModel;
template <typename T>
struct TModel<T, std::enable_if<std::is_same<T, uint32_t | uint16_t | uint8_t>>>: public UnsignedConcept<T> {
T& self;
UnsignedModel(T& self) : self(self) { }
uint64_t asUint64() override {
return static_cast<uint64_t>(self);
}
};
template <typename T, typename Cond>
struct TModel;
template <typename T>
struct TModel<T, std::enable_if<std::is_same<T, uint32_t | uint16_t | uint8_t>>>: public UnsignedConcept<T> {
T& self;
UnsignedModel(T& self) : self(self) { }
uint64_t asUint64() override {
return static_cast<uint64_t>(self);
}
};

Discussion

Templated implimpl introduces challenge on trait method resolving. Users who gets interested in this feature can check Rust: Trait solving.