xo-facet: typeseq strongly typed
This commit is contained in:
parent
9fc5a7b101
commit
0c06430703
3 changed files with 39 additions and 11 deletions
|
|
@ -70,7 +70,7 @@ namespace xo {
|
|||
"Abstract facet expected to have trivial dtor since no state");
|
||||
static_assert
|
||||
(requires(T & facet) {
|
||||
{ facet._typeseq() } -> std::convertible_to<std::int32_t>; },
|
||||
{ facet._typeseq().seqno() } -> std::convertible_to<std::int32_t>; },
|
||||
"Abstract facet must provide a _typeseq() method for safe downcasting");
|
||||
return true;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdint>
|
||||
|
||||
namespace xo {
|
||||
|
|
@ -15,6 +16,8 @@ namespace xo {
|
|||
*/
|
||||
template<typename Tag = class typeseq_tag>
|
||||
struct typeseq_impl {
|
||||
explicit typeseq_impl(int32_t s) : seqno_{s} {}
|
||||
|
||||
/** Can't have this be constexpr.
|
||||
* We need ids in shared libraries to be generated
|
||||
* at load time to avoid false positives
|
||||
|
|
@ -28,7 +31,7 @@ namespace xo {
|
|||
* when using clang.
|
||||
**/
|
||||
template <typename T>
|
||||
static int32_t id() {
|
||||
static typeseq_impl<Tag> id() {
|
||||
static bool armed = true;
|
||||
static int32_t id = 0;
|
||||
|
||||
|
|
@ -37,15 +40,40 @@ namespace xo {
|
|||
id = ++s_next_id;
|
||||
}
|
||||
|
||||
return id;
|
||||
return typeseq_impl(id);
|
||||
|
||||
}
|
||||
|
||||
int32_t seqno() const { return seqno_; }
|
||||
|
||||
private:
|
||||
static int32_t s_next_id;
|
||||
|
||||
int32_t seqno_;
|
||||
};
|
||||
|
||||
template <typename Tag>
|
||||
int32_t typeseq_impl<Tag>::s_next_id = 0;
|
||||
|
||||
template <typename Tag>
|
||||
inline bool
|
||||
operator==(const typeseq_impl<Tag> & lhs, const typeseq_impl<Tag> & rhs) {
|
||||
return lhs.seqno() == rhs.seqno();
|
||||
}
|
||||
|
||||
template <typename Tag>
|
||||
inline bool
|
||||
operator!=(const typeseq_impl<Tag> & lhs, const typeseq_impl<Tag> & rhs) {
|
||||
return lhs.seqno() != rhs.seqno();
|
||||
}
|
||||
|
||||
template <typename Tag>
|
||||
inline std::ostream &
|
||||
operator<<(std::ostream & s, const typeseq_impl<Tag> & x) {
|
||||
s << x.seqno();
|
||||
return s;
|
||||
}
|
||||
|
||||
using typeseq = typeseq_impl<>;
|
||||
}
|
||||
} /*namespace xo*/
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ namespace xo {
|
|||
using TypeErasedIface = struct IComplex_Any;
|
||||
|
||||
/** RTTI: reports unique id# for actual runtime data representation **/
|
||||
virtual int32_t _typeseq() const = 0;
|
||||
virtual typeseq _typeseq() const = 0;
|
||||
|
||||
virtual double xcoord(void * data) const = 0;
|
||||
virtual double ycoord(void * data) const = 0;
|
||||
|
|
@ -61,7 +61,7 @@ namespace xo {
|
|||
|
||||
// from AComplex
|
||||
|
||||
virtual int32_t _typeseq() const final override { return s_typeseq; }
|
||||
virtual typeseq _typeseq() const final override { return s_typeseq; }
|
||||
|
||||
virtual double xcoord(void * data) const final override { return Impl::xcoord(*(DRepr*)data); }
|
||||
virtual double ycoord(void * data) const final override { return Impl::ycoord(*(DRepr*)data); }
|
||||
|
|
@ -70,12 +70,12 @@ namespace xo {
|
|||
|
||||
virtual void destruct_data(void * data) const final override { Impl::destruct_data(*(DRepr*)data); }
|
||||
|
||||
static int32_t s_typeseq;
|
||||
static typeseq s_typeseq;
|
||||
static bool _valid;
|
||||
};
|
||||
|
||||
template <typename DRepr>
|
||||
int32_t
|
||||
typeseq
|
||||
IComplex_Xfer<DRepr>::s_typeseq = typeseq::id<DRepr>();
|
||||
|
||||
template <typename DRepr>
|
||||
|
|
@ -96,7 +96,7 @@ namespace xo {
|
|||
* such as IComplex_RectCoords or IComplex_PolarCoords.
|
||||
**/
|
||||
struct IComplex_Any : public AComplex {
|
||||
virtual int32_t _typeseq() const final override { return s_typeseq; }
|
||||
virtual typeseq _typeseq() const final override { return s_typeseq; }
|
||||
|
||||
virtual double xcoord(void *) const final override { assert(false); return 0.0; }
|
||||
virtual double ycoord(void *) const final override { assert(false); return 0.0; }
|
||||
|
|
@ -105,11 +105,11 @@ namespace xo {
|
|||
|
||||
virtual void destruct_data(void *) const final override { assert(false); }
|
||||
|
||||
static int32_t s_typeseq;
|
||||
static typeseq s_typeseq;
|
||||
static bool _valid;
|
||||
};
|
||||
|
||||
int32_t
|
||||
typeseq
|
||||
IComplex_Any::s_typeseq = typeseq::id<DVariantPlaceholder>();
|
||||
|
||||
bool
|
||||
|
|
@ -190,7 +190,7 @@ namespace xo {
|
|||
RComplex() {}
|
||||
RComplex(Object::DataPtr data) : Object{std::move(data)} {}
|
||||
|
||||
int32_t _typeseq() const { return Object::iface()->_typeseq(); }
|
||||
typeseq _typeseq() const { return Object::iface()->_typeseq(); }
|
||||
double xcoord() const { return Object::iface()->xcoord(Object::data()); }
|
||||
double ycoord() const { return Object::iface()->ycoord(Object::data()); }
|
||||
double argument() const { return Object::iface()->argument(Object::data()); }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue