xo-facet: typeseq strongly typed

This commit is contained in:
Roland Conybeare 2026-01-02 09:52:16 -05:00
commit fb14fcad15
31 changed files with 151 additions and 72 deletions

View file

@ -7,6 +7,7 @@
#include "AllocInfo.hpp"
#include "cmpresult.hpp"
#include "typeseq.hpp"
#include <xo/facet/obj.hpp>
namespace xo {
@ -22,11 +23,12 @@ namespace xo {
**/
struct AAllocIterator {
using obj_AAllocIterator = xo::facet::obj<AAllocIterator>;
using typeseq = xo::facet::typeseq;
/** @defgroup mm-allociterator-methods AllocIterator methods **/
///@{
/** RTTI: unique id# for actual runtime *data* representation **/
virtual int32_t _typeseq() const noexcept = 0;
virtual typeseq _typeseq() const noexcept = 0;
/** retrieve AllocInfo for current iterator position
**/
virtual AllocInfo deref(Copaque d) const noexcept = 0;

View file

@ -9,6 +9,7 @@
#include "AllocInfo.hpp"
//#include "AllocIterator.hpp"
#include "AllocRange.hpp"
#include "typeseq.hpp"
#include <xo/facet/obj.hpp>
#include <xo/facet/facet_implementation.hpp>
#include <xo/facet/typeseq.hpp>
@ -40,6 +41,8 @@ namespace xo {
using header_type = std::uint64_t;
/** iterator range. These are forward iterators over allocs **/
using range_type = AllocRange;
/** sequence number identifying a datatype **/
using typeseq = xo::facet::typeseq;
///@}
/*
@ -58,7 +61,7 @@ namespace xo {
///@{
/** RTTI: unique id# for actual runtime data representation **/
virtual int32_t _typeseq() const noexcept = 0;
virtual typeseq _typeseq() const noexcept = 0;
/** optional name for allocator @p d .
* Allows labeling allocators, for diagnostics/instrumentation.
**/

View file

@ -1,4 +1,4 @@
/** @file IAllocIter_Any.hpp
/** @file IAllocIterator_Any.hpp
*
* @author Roland Conybeare, Dec 2025
**/
@ -20,10 +20,12 @@ namespace xo {
* @brief AllocIterator implementation for empty variant instance
**/
struct IAllocIterator_Any : public AAllocIterator {
using typeseq = xo::facet::typeseq;
const AAllocIterator * iface() const { return std::launder(this); }
// from AAllocIterator
int32_t _typeseq() const noexcept override { return s_typeseq; }
typeseq _typeseq() const noexcept override { return s_typeseq; }
// const methods
[[noreturn]] AllocInfo deref(Copaque) const noexcept override { _fatal(); }
@ -37,10 +39,10 @@ namespace xo {
[[noreturn]] static void _fatal();
public:
static int32_t s_typeseq;
static typeseq s_typeseq;
static bool _valid;
};
} /*namespace mm*/
} /*namespace xo*/
/* end IAllocIter_Any.hpp */
/* end IAllocIterator_Any.hpp */

View file

@ -18,6 +18,7 @@ namespace xo {
typename IAllocIterator_DRepr>
struct IAllocIterator_Xfer : public AAllocIterator {
using Impl = IAllocIterator_DRepr;
using typeseq = xo::facet::typeseq;
static const DRepr & _dcast(Copaque d) { return *(const DRepr *)d; }
static DRepr & _dcast(Opaque d) { return *(DRepr *)d; }
@ -26,7 +27,7 @@ namespace xo {
// const methods
int32_t _typeseq() const noexcept override { return s_typeseq; }
typeseq _typeseq() const noexcept override { return s_typeseq; }
AllocInfo deref(Copaque d)
const noexcept override { return I::deref(_dcast(d)); }
cmpresult compare(Copaque d,
@ -42,12 +43,12 @@ namespace xo {
using I = Impl;
public:
static int32_t s_typeseq;
static typeseq s_typeseq;
static bool _valid;
};
template <typename DRepr, typename IAllocIterator_DRepr>
int32_t
xo::facet::typeseq
IAllocIterator_Xfer<DRepr, IAllocIterator_DRepr>::s_typeseq
= facet::typeseq::id<DRepr>();

View file

@ -7,6 +7,7 @@
#include "AAllocator.hpp"
#include "AllocIterator.hpp"
#include "typeseq.hpp"
#include <xo/facet/obj.hpp>
namespace xo {
@ -30,7 +31,7 @@ namespace xo {
const AAllocator * iface() const { return std::launder(this); }
// from AAllocator
int32_t _typeseq() const noexcept override { return s_typeseq; }
typeseq _typeseq() const noexcept override { return s_typeseq; }
// const methods
[[noreturn]] std::string_view name(Copaque) const noexcept override { _fatal(); }
@ -58,7 +59,7 @@ namespace xo {
[[noreturn]] static void _fatal();
public:
static int32_t s_typeseq;
static typeseq s_typeseq;
static bool _valid;
};
}

View file

@ -25,6 +25,7 @@ namespace xo {
using Impl = IAllocator_DRepr;
using size_type = AAllocator::size_type;
using value_type = AAllocator::value_type;
using typeseq = AAllocator::typeseq;
///@}
/** @defgroup mm-allocator-xfer-methods IAllocator_Xfer methods **/
@ -38,7 +39,7 @@ namespace xo {
// const methods
/** return typeseq for @tparam DRepr **/
int32_t _typeseq() const noexcept override { return s_typeseq; }
typeseq _typeseq() const noexcept override { return s_typeseq; }
std::string_view name(Copaque d) const noexcept override { return I::name(_dcast(d)); }
size_type reserved(Copaque d) const noexcept override { return I::reserved(_dcast(d)); }
size_type size(Copaque d) const noexcept override { return I::size(_dcast(d)); }
@ -75,12 +76,12 @@ namespace xo {
using I = Impl;
public:
static int32_t s_typeseq;
static xo::facet::typeseq s_typeseq;
static bool _valid;
};
template <typename DRepr, typename IAllocator_DRepr>
int32_t
xo::facet::typeseq
IAllocator_Xfer<DRepr, IAllocator_DRepr>::s_typeseq = facet::typeseq::id<DRepr>();
template <typename DRepr, typename IAllocator_DRepr>

View file

@ -17,11 +17,12 @@ namespace xo {
public:
using ObjectType = Object;
using DataPtr = Object::DataPtr;
using typeseq = xo::facet::typeseq;
RAllocIterator() {}
RAllocIterator(Object::DataPtr data) : Object{std::move(data)} {}
int32_t _typeseq() const noexcept { return O::iface()->_typeseq(); }
typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); }
AllocInfo deref() const noexcept { return O::iface()->deref(O::data()); }
cmpresult compare(const obj<AAllocIterator> & other) const noexcept {
return O::iface()->compare(O::data(), other); }

View file

@ -20,6 +20,7 @@ namespace xo {
public:
using ObjectType = Object;
using DataPtr = Object::DataPtr;
using typeseq = xo::facet::typeseq;
using size_type = std::size_t;
using value_type = std::byte *;
using range_type = AAllocator::range_type;
@ -27,7 +28,7 @@ namespace xo {
RAllocator() {}
RAllocator(Object::DataPtr data) : Object{std::move(data)} {}
int32_t _typeseq() const noexcept { return O::iface()->_typeseq(); }
typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); }
std::string_view name() const noexcept { return O::iface()->name(O::data()); }
size_type reserved() const noexcept { return O::iface()->reserved(O::data()); }
size_type size() const noexcept { return O::iface()->size(O::data()); }

View file

@ -24,7 +24,7 @@ namespace xo {
/** optional name, for diagnostics **/
std::string name_;
/** desired arena size -- hard max = reserved virtual memory **/
std::size_t size_;
std::size_t size_ = 0;
/** hugepage size -- using huge pages relieves some TLB pressure
* (provided you use their full extent :)
**/

View file

@ -46,14 +46,13 @@ namespace xo {
// end of hugeppage-aligned range starting at aligned_base
byte * aligned_hi = aligned_base + target_z;
#ifdef NOT_YET
log && log("acquired memory [lo,hi) using mmap",
xtag("lo", base),
xtag("aligned_lo", aligned_base),
xtag("req_z", req_z),
xtag("target_z", target_z),
xtag("hi", (byte *)(base) + z));
#endif
xtag("aligned_hi", aligned_hi),
xtag("hi", hi));
// 3. assess mmap success
{
@ -109,7 +108,7 @@ namespace xo {
DArena
DArena::map(const ArenaConfig & cfg)
{
//scope log(XO_DEBUG(debug_flag), xtag("name", name));
scope log(XO_DEBUG(true));
/* vm page size. 4KB, probably */
size_t page_z = getpagesize();
@ -122,6 +121,9 @@ namespace xo {
*/
size_t align_z = (enable_hugepage_flag ? cfg.hugepage_z_ : page_z);
log && log(xtag("page_z", page_z),
xtag("align_z", align_z));
auto [lo, hi] = map_aligned_range(cfg.size_,
align_z,
enable_hugepage_flag);

View file

@ -26,7 +26,7 @@ namespace xo {
std::terminate();
}
int32_t
typeseq
IAllocIterator_Any::s_typeseq = typeseq::id<DVariantPlaceholder>();
bool

View file

@ -27,7 +27,7 @@ namespace xo {
std::terminate();
}
int32_t
typeseq
IAllocator_Any::s_typeseq = typeseq::id<DVariantPlaceholder>();
bool

View file

@ -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;
};

View file

@ -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*/

View file

@ -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()); }

View file

@ -31,9 +31,10 @@ namespace xo {
* A collector implementation will also support the @ref AAllocator facet, see also
**/
struct ACollector {
using typeseq = xo::facet::typeseq;
using size_type = std::size_t;
virtual int32_t _typeseq() const noexcept = 0;
virtual typeseq _typeseq() const noexcept = 0;
virtual size_type allocated(Copaque d,
generation g, role r) const noexcept = 0;
@ -50,8 +51,10 @@ namespace xo {
* @c AGCObject_Xfer<DFoo,AGCObject_DFoo> for some @c DFoo
* in which case calls through @c std::launder(&iface)
* will properly act on @c DFoo.
*
* Return false if installation fails (e.g. memory exhausted)
**/
virtual void install_type(Opaque d, int32_t tseq, IGCObject_Any & iface) = 0;
virtual bool install_type(Opaque d, const AGCObject & iface) = 0;
virtual void add_gc_root(Opaque d, int32_t tseq, Opaque * root) = 0;
/** evacuate @p *lhs, that refers to state with interface @p lhs_iface,

View file

@ -26,10 +26,11 @@ namespace xo {
* by ACollector
**/
struct AGCObject {
using typeseq = xo::facet::typeseq;
using size_type = std::size_t;
/** RTTI: unique id# for actual runtime data representation **/
virtual int32_t _typeseq() const noexcept = 0;
virtual typeseq _typeseq() const noexcept = 0;
virtual size_type shallow_size(Copaque d) const noexcept = 0;
virtual Opaque shallow_copy(Copaque d,

View file

@ -6,6 +6,7 @@
#pragma once
#include "ACollector.hpp"
#include "AGCObject.hpp"
//#include <cassert>
namespace xo {
@ -34,7 +35,7 @@ namespace xo {
[[noreturn]] size_type committed(Copaque, generation, role) const noexcept override { _fatal(); }
// non-const methods
[[noreturn]] void install_type(Opaque, int32_t, IGCObject_Any &) noexcept override { _fatal(); }
[[noreturn]] bool install_type(Opaque, const AGCObject &) noexcept override { _fatal(); }
[[noreturn]] void add_gc_root(Opaque, int32_t, Opaque *) override { _fatal(); }
[[noreturn]] void forward_inplace(Opaque, AGCObject *, void **) override { _fatal(); }
@ -42,7 +43,7 @@ namespace xo {
[[noreturn]] static void _fatal();
public:
static int32_t s_typeseq;
static typeseq s_typeseq;
static bool _valid;
};
} /*namespace mm*/

View file

@ -41,8 +41,7 @@ namespace xo {
static size_type reserved(const DX1Collector & d, generation g, role r);
static size_type committed(const DX1Collector & d, generation g, role r);
static void install_type(DX1Collector & d,
int32_t seq, IGCObject_Any & iface);
static bool install_type(DX1Collector & d, const AGCObject & iface);
static void add_gc_root(DX1Collector & d, int32_t tseq, Opaque * root);
static void forward_inplace(DX1Collector & d, AGCObject * lhs_iface, void ** lhs_data);

View file

@ -6,6 +6,7 @@
#pragma once
#include "ACollector.hpp"
#include "AGCObject.hpp"
namespace xo {
namespace mm {
@ -30,7 +31,7 @@ namespace xo {
// const methods
int32_t _typeseq() const noexcept override { return s_typeseq; }
typeseq _typeseq() const noexcept override { return s_typeseq; }
size_type allocated(Copaque d, generation g, role r) const noexcept override {
return I::allocated(_dcast(d), g, r);
}
@ -43,8 +44,8 @@ namespace xo {
// non-const methods
void install_type(Opaque d, int32_t tseq, IGCObject_Any & iface) override {
I::install_type(_dcast(d), tseq, iface);
bool install_type(Opaque d, const AGCObject & iface) override {
return I::install_type(_dcast(d), iface);
}
void add_gc_root(Opaque d, int32_t tseq, Opaque * root) override {
I::add_gc_root(_dcast(d), tseq, root);
@ -57,12 +58,12 @@ namespace xo {
using I = Impl;
public:
static int32_t s_typeseq;
static typeseq s_typeseq;
static bool _valid;
};
template <typename DRepr, typename ICollector_DRepr>
int32_t
xo::facet::typeseq
ICollector_Xfer<DRepr, ICollector_DRepr>::s_typeseq = facet::typeseq::id<DRepr>();
template <typename DRepr, typename ICollector_DRepr>

View file

@ -24,12 +24,13 @@ namespace xo {
* @brief AGCObject implementation for empty variant instance
**/
struct IGCObject_Any : public AGCObject {
using typeseq = xo::facet::typeseq;
using size_type = std::size_t;
const AGCObject * iface() const { return std::launder(this); }
// from AGCObject
int32_t _typeseq() const noexcept override { return s_typeseq; }
typeseq _typeseq() const noexcept override { return s_typeseq; }
[[noreturn]] size_type shallow_size(Copaque) const noexcept override { _fatal(); }
[[noreturn]] Opaque shallow_copy(Copaque,
@ -41,7 +42,7 @@ namespace xo {
[[noreturn]] static void _fatal();
public:
static int32_t s_typeseq;
static typeseq s_typeseq;
static bool _valid;
};
} /*namespace mm*/

View file

@ -27,7 +27,7 @@ namespace xo {
// const methods
int32_t _typeseq() const noexcept override { return s_typeseq; }
typeseq _typeseq() const noexcept override { return s_typeseq; }
size_type shallow_size(Copaque d) const noexcept override {
return I::shallow_size(_dcast(d));
}
@ -46,12 +46,12 @@ namespace xo {
using I = Impl;
public:
static int32_t s_typeseq;
static typeseq s_typeseq;
static bool _valid;
};
template <typename DRepr, typename IGCObject_DRepr>
int32_t
xo::facet::typeseq
IGCObject_Xfer<DRepr, IGCObject_DRepr>::s_typeseq = facet::typeseq::id<DRepr>();
template <typename DRepr, typename IGCObject_DRepr>

View file

@ -27,7 +27,7 @@ namespace xo {
size_type reserved(generation g, role r) const noexcept { return O::iface()->reserved(O::data(), g, r); }
size_type committed(generation g, role r) const noexcept { return O::iface()->committed(O::data(), g, r); }
void install_type(int32_t tseq, IGCObject_Any & iface) { return O::iface()->install_type(O::data(), tseq, iface); }
bool install_type(const AGCObject & iface) { return O::iface()->install_type(O::data(), iface); }
void add_gc_root(int32_t tseq, Opaque * root) { O::iface()->add_gc_root(O::data(), tseq, root); }
void forward_inplace(AGCObject * lhs_iface, void ** lhs_data) { O::iface()->forward_inplace(O::data(), lhs_iface, lhs_data); }

View file

@ -18,12 +18,13 @@ namespace xo {
public:
using ObjectType = Object;
using DataPtr = Object::DataPtr;
using typeseq = xo::facet::typeseq;
using size_type = std::size_t;
RGCObject() = default;
RGCObject(Object::DataPtr data) : Object{std::move(data)} {}
int32_t _typeseq() const noexcept { return O::iface()->_typeseq(); }
typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); }
size_type shallow_size() const noexcept { O::iface()->shallow_size(O::data()); }
Opaque shallow_copy(obj<AAllocator> mm) const noexcept { O::iface()->shallow_copy(O::data(), mm); }
size_type forward_children() noexcept { O::iface()->forward_children(O::data()); }

View file

@ -13,9 +13,12 @@
#include <xo/indentlog/scope.hpp>
#include <cassert>
#include <cstdint>
#include <sys/mman.h>
#include <unistd.h> // for ::getpagesize()
namespace xo {
using xo::mm::AAllocator;
using xo::facet::typeseq;
using xo::facet::with_facet;
namespace mm {
@ -61,6 +64,19 @@ namespace xo {
config_.arena_config_.header_.age_bits_ +
config_.arena_config_.header_.tseq_bits_ <= 64);
size_t page_z = getpagesize();
/* 1MB reserved address space enough for up to 128k distinct types.
* In this case don't want to use hugepages since actual #of types
* likely << .size/8
*/
object_types_ = DArena::map(
ArenaConfig{
.name_ = "x1-object-types",
.size_ = cfg.object_types_z_,
.hugepage_z_ = page_z,
.store_header_flag_ = false});
for (uint32_t igen = 0, ngen = cfg.n_generation_; igen < ngen; ++igen) {
space_storage_[0][igen] = DArena::map(cfg.arena_config_);
space_storage_[1][igen] = DArena::map(cfg.arena_config_);
@ -103,7 +119,7 @@ namespace xo {
accumulate_total_aux(const DX1Collector & d,
size_t (DArena::* get_stat_fn)() const) noexcept
{
size_t z = 0;
size_t z = (d.object_types_.*get_stat_fn)();
for (role ri : role::all()) {
for (generation gj{0}; gj < d.config_.n_generation_; ++gj) {
@ -182,6 +198,23 @@ namespace xo {
return config_.arena_config_.header_.is_forwarding_tseq(hdr);
}
bool
DX1Collector::install_type(const AGCObject & meta) noexcept
{
typeseq tseq = meta._typeseq();
bool ok = object_types_.expand(sizeof(AGCObject) * (tseq.seqno() + 1));
if (!ok)
return false;
AGCObject * v = reinterpret_cast<AGCObject *>(object_types_.lo_);
/* explicitly copying vtable pointer here */
std::memcpy((void*)&(v[tseq.seqno()]), (void*)&meta, sizeof(AGCObject));
return true;
}
auto
DX1Collector::alloc(size_type z) noexcept -> value_type
{

View file

@ -27,7 +27,7 @@ namespace xo {
std::terminate();
}
int32_t
typeseq
ICollector_Any::s_typeseq = typeseq::id<DVariantPlaceholder>();
bool

View file

@ -47,16 +47,11 @@ namespace xo {
return stat_helper(d, &DArena::committed, g, r);
}
void
bool
ICollector_DX1Collector::install_type(DX1Collector & d,
std::int32_t tseq,
IGCObject_Any & iface)
const AGCObject & iface)
{
(void)d;
(void)tseq;
(void)iface;
assert(false);
return d.install_type(iface);
}
void

View file

@ -22,7 +22,7 @@ namespace xo {
std::terminate();
}
int32_t
typeseq
IGCObject_Any::s_typeseq = typeseq::id<DVariantPlaceholder>();
bool

View file

@ -34,6 +34,8 @@ public:
/** @defgroup scm-sequence-type-traits **/
///@{
// types
/** integer identifying a type **/
using typeseq = xo::facet::typeseq;
/** type for length of a sequence **/
using size_type = std::size_t;
/** facet for types with GC support **/
@ -44,7 +46,7 @@ public:
///@{
// const methods
/** RTTI: unique id# for actual runtime data representation **/
virtual int32_t _typeseq() const noexcept = 0;
virtual typeseq _typeseq() const noexcept = 0;
/** true iff sequence is empty **/
virtual bool is_empty(Copaque data) const noexcept = 0;
/** true iff sequence is finite **/
@ -72,4 +74,4 @@ using ISequence_ImplType = xo::facet::FacetImplType<ASequence, DRepr>;
} /*namespace scm*/
} /*namespace xo*/
/* */
/* */

View file

@ -38,7 +38,7 @@ namespace scm {
// from ASequence
// const methods
int32_t _typeseq() const noexcept override { return s_typeseq; }
typeseq _typeseq() const noexcept override { return s_typeseq; }
bool is_empty(Copaque data) const noexcept override {
return I::is_empty(_dcast(data));
}
@ -61,7 +61,7 @@ namespace scm {
///@{
/** typeseq for template parameter DRepr **/
static int32_t s_typeseq;
static typeseq s_typeseq;
/** true iff satisfies facet implementation **/
static bool _valid;
@ -69,7 +69,7 @@ namespace scm {
};
template <typename DRepr, typename ISequence_DRepr>
int32_t
xo::facet::typeseq
ISequence_Xfer<DRepr, ISequence_DRepr>::s_typeseq
= xo::facet::typeseq::id<DRepr>();
@ -82,4 +82,4 @@ namespace scm {
} /*namespace scm */
} /*namespace xo*/
/* end ISequence_Xfer.hpp */
/* end ISequence_Xfer.hpp */

View file

@ -25,7 +25,7 @@ ISequence_Any::_fatal()
std::terminate();
}
int32_t
typeseq
ISequence_Any::s_typeseq = typeseq::id<DVariantPlaceholder>();
bool