dynamic& dynamic::operator=(dynamic&& o) noexcept { if (&o != this) { if (type_ == o.type_) { #define FB_X(T) *getAddress<T>() = std::move(*o.getAddress<T>()) FB_DYNAMIC_APPLY(type_, FB_X); #undef FB_X } else { destroy(); #define FB_X(T) new (getAddress<T>()) T(std::move(*o.getAddress<T>())) FB_DYNAMIC_APPLY(o.type_, FB_X); #undef FB_X type_ = o.type_; } } return *this; }
void dynamic::destroy() noexcept { // This short-circuit speeds up some microbenchmarks. if (type_ == NULLT) return; #define FB_X(T) detail::Destroy::destroy(getAddress<T>()) FB_DYNAMIC_APPLY(type_, FB_X); #undef FB_X type_ = NULLT; u_.nul = nullptr; }
bool dynamic::operator<(dynamic const& o) const { if (UNLIKELY(type_ == OBJECT || o.type_ == OBJECT)) { throw_exception<TypeError>("object", type_); } if (type_ != o.type_) { return type_ < o.type_; } #define FB_X(T) return CompareOp<T>::comp(*getAddress<T>(), *o.getAddress<T>()) FB_DYNAMIC_APPLY(type_, FB_X); #undef FB_X }
bool dynamic::operator==(dynamic const& o) const { if (type() != o.type()) { if (isNumber() && o.isNumber()) { auto& integ = isInt() ? *this : o; auto& doubl = isInt() ? o : *this; return integ.asInt() == doubl.asDouble(); } return false; } #define FB_X(T) return *getAddress<T>() == *o.getAddress<T>(); FB_DYNAMIC_APPLY(type_, FB_X); #undef FB_X }
char const* dynamic::typeName(Type t) { #define FB_X(T) return TypeInfo<T>::name FB_DYNAMIC_APPLY(t, FB_X); #undef FB_X }