xo-type: + DAtomicType [WIP]

This commit is contained in:
Roland Conybeare 2026-03-06 13:04:31 +11:00
commit c9944a27aa
31 changed files with 1262 additions and 0 deletions

70
CMakeLists.txt Normal file
View file

@ -0,0 +1,70 @@
# xo-type/CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(xo_type VERSION 1.0)
enable_language(CXX)
include(GNUInstallDirs)
include(cmake/xo-bootstrap-macros.cmake)
xo_cxx_toplevel_options3()
# ----------------------------------------------------------------
# c++ settings
# one-time project-specific c++ flags. usually empty
set(PROJECT_CXX_FLAGS "")
add_definitions(${PROJECT_CXX_FLAGS})
# ----------------------------------------------------------------
# facet code generation
xo_add_genfacet(
TARGET xo-type-facet-type
FACET Type
INPUT idl/Type.json5
OUTPUT_HPP_DIR include/xo/type
OUTPUT_IMPL_SUBDIR type
)
# ----------------------------------------------------------------
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-type-facetimpl-type-atomictype
FACET_PKG xo_type
FACET Type
REPR AtomicType
INPUT idl/IType_DAtomicType.json5
)
# note: manual target; generated code committed to git
xo_add_genfacetimpl(
TARGET xo-type-facetimpl-gcobject-atomictype
FACET_PKG xo_alloc2
FACET GCObject
REPR AtomicType
INPUT idl/IGCObject_DAtomicType.json5
)
# ----------------------------------------------------------------
xo_add_genfacet_all(xo-type-genfacet-all)
install(DIRECTORY idl/
DESTINATION share/${PROJECT_NAME}/idl
FILES_MATCHING PATTERN "*.json5")
# ----------------------------------------------------------------
# output targets
add_subdirectory(src/type)
add_subdirectory(utest)
# ----------------------------------------------------------------
# cmake export
xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets)
# end CMakeLists.txt

View file

@ -0,0 +1,41 @@
# ----------------------------------------------------------------
# for example:
# $ PREFIX=/usr/local # for example
# $ cmake -DCMAKE_MODULE_PATH=prefix -DCMAKE_INSTALL_PREFIX=$PREFIX -B .build
#
# will get
# CMAKE_MODULE_PATH
# from xo-cmake-config --cmake-module-path
#
# and expect .cmake macros in
# CMAKE_MODULE_PATH/xo_macros/xo_cxx.cmake
# ----------------------------------------------------------------
find_program(XO_CMAKE_CONFIG_EXECUTABLE NAMES xo-cmake-config REQUIRED)
if ("${XO_CMAKE_CONFIG_EXECUTABLE}" STREQUAL "XO_CMAKE_CONFIG_EXECUTABLE-NOT_FOUND")
message(FATAL "could not find xo-cmake-config executable")
endif()
message(STATUS "XO_CMAKE_CONFIG_EXECUTABLE=${XO_CMAKE_CONFIG_EXECUTABLE}")
if (XO_SUBMODULE_BUILD)
if (("${CMAKE_MODULE_PATH}" STREQUAL "") OR ("${CMAKE_MODULE_PATH}" STREQUAL prefix))
# local version of xo-cmake macros
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/xo-cmake/cmake")
message(STATUS "CMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}")
endif()
else()
if (("${CMAKE_MODULE_PATH}" STREQUAL "") OR ("${CMAKE_MODULE_PATH}" STREQUAL prefix))
# default to typical install location for xo-project-macros
execute_process(COMMAND ${XO_CMAKE_CONFIG_EXECUTABLE} --cmake-module-path OUTPUT_VARIABLE CMAKE_MODULE_PATH)
message(STATUS "CMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}")
endif()
endif()
# needs to have been installed somewhere on CMAKE_MODULE_PATH,
# (e.g. from xo-cmake with the same value for CMAKE_INSTALL_PREFIX)
#
include(xo_macros/xo_cxx)
xo_cxx_bootstrap_message()

View file

@ -0,0 +1,15 @@
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
find_dependency(xo_alloc2)
find_dependency(xo_facet)
# note: changes to find_dependency() calls here
# must coordinate with xo_dependency() calls
# in src/type/CMakeLists.txt
#
#find_dependency(xo_indentlog)
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Share.cmake")
check_required_components("@PROJECT_NAME@")

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/type",
output_hpp_dir: "include/xo/type",
output_impl_subdir: "atomic",
includes: [
],
local_types: [ ],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/GCObject.json5",
brief: "provide AGCObject interface for DAtomicType",
using_doxygen: true,
repr: "DAtomicType",
doc: [ "implement AGCObject for DAtomicType" ],
}

View file

@ -0,0 +1,16 @@
{
mode: "implementation",
output_cpp_dir: "src/type",
output_hpp_dir: "include/xo/type",
output_impl_subdir: "atomic",
includes: [],
local_types: [],
namespace1: "xo",
namespace2: "scm",
facet_idl: "idl/Type.json5",
brief: "provide AType interface for DAtomicType",
using_doxygen: true,
repr: "DAtomicType",
doc: [ "implement AType for DAtomicType" ],
}

53
idl/Type.json5 Normal file
View file

@ -0,0 +1,53 @@
{
mode: "facet",
output_cpp_dir: "src/type",
output_hpp_dir: "include/xo/type",
output_impl_subdir: "type",
includes: [
"<xo/type/Metatype.hpp>"
],
user_hpp_includes: [
],
namespace1: "xo",
namespace2: "scm", // TODO: change to project namespace if different
pretext: [
"// pretext if any"
],
facet: "Type",
detail_subdir: "type",
brief: "Representation for a Schematika type",
using_doxygen: true,
doc: [
"1. Ability to compare types as members of partial order",
"2. ..."
],
types: [
{
name: "obj_AType",
doc: [],
definition: "xo::facet::obj<AType>",
}
],
const_methods: [
{
name: "metatype",
doc: ["category for this type"],
return_type: "Metatype",
args: [],
const: true,
noexcept: true,
},
// TODO: define methods, e.g.:
// {
// name: "my_method",
// doc: ["description"],
// return_type: "bool",
// args: [],
// const: true,
// noexcept: true,
// },
],
nonconst_methods: [],
router_facet_explicit_content: [],
}

View file

@ -0,0 +1,12 @@
/** @file AtomicType.hpp
*
* @author Roland Conybeare, Mar 2026
**/
#pragma once
#include "DAtomicType.hpp"
#include "atomic/IType_DAtomicType.hpp"
#include "atomic/IGCObject_DAtomicType.hpp"
/* end AtomicType.hpp */

View file

@ -0,0 +1,48 @@
/** @file DAtomicType.hpp
*
* @author Roland Conybeare, Mar 2026
**/
#pragma once
#include "Metatype.hpp"
#include <xo/alloc2/Collector.hpp>
#include <xo/alloc2/Allocator.hpp>
namespace xo {
namespace scm {
/** @brief An atomic schematika type
*
* Types that are not parameterized by types or values.
* For example
* unit, bool, i64, f64
* are atomic in this sense.
**/
class DAtomicType {
public:
using ACollector = xo::mm::ACollector;
using AAllocator = xo::mm::AAllocator;
public:
explicit DAtomicType(Metatype m) : metatype_{m} {}
/** create instance using memory from @p mm with metatype @p mtype **/
static DAtomicType * _make(obj<AAllocator> mm, Metatype mtype);
Metatype metatype() const noexcept { return metatype_; }
/** @defgroup xo-scm-atomictype-gcobject-facet **/
///@{
std::size_t shallow_size() const noexcept;
DAtomicType * shallow_copy(obj<AAllocator> mm) const noexcept;
std::size_t forward_children(obj<ACollector> gc) noexcept;
///@}
private:
Metatype metatype_;
};
} /*namespace scm*/
} /*namespace xo*/
/* end DAtomicType.hpp */

View file

@ -0,0 +1,60 @@
/** @file Metatype.hpp
*
* @author Roland Conybeare, Mar 2026
**/
#pragma once
#include <iostream>
namespace xo {
namespace scm {
class Metatype {
public:
enum class code {
/* void */
t_unit,
t_bool,
t_i64,
t_f64,
t_str,
/* discriminated union */
t_sum,
/* list<T> */
t_list,
/* array<T> */
t_array,
/* function<T(U,V,...)> */
t_function,
/* struct<a:T,b:U,..> */
t_struct,
/* any type at all */
t_any,
};
public:
explicit Metatype(code x) : code_{x} {}
static Metatype unit() { return Metatype(code::t_unit); }
/** description string for this type category **/
const char * _descr() const noexcept;
code code() const noexcept { return code_; }
private:
enum code code_;
};
inline std::ostream &
operator<<(std::ostream & os, Metatype x) {
os << x._descr();
return os;
}
} /*namespace scm*/
} /*namespace xo*/
/* end Metatype.hpp */

22
include/xo/type/Type.hpp Normal file
View file

@ -0,0 +1,22 @@
/** @file Type.hpp
*
* Generated automagically from ingredients:
* 1. code generator:
* [xo-facet/codegen/genfacet]
* arguments:
* --input [idl/Type.json5]
* 2. jinja2 template for facet .hpp file:
* [facet.hpp.j2]
* 3. idl for facet methods
* [idl/Type.json5]
**/
#pragma once
#include "type/AType.hpp"
#include "type/IType_Any.hpp"
#include "type/IType_Xfer.hpp"
#include "type/RType.hpp"
/* end Type.hpp */

View file

@ -0,0 +1,65 @@
/** @file IGCObject_DAtomicType.hpp
*
* Generated automagically from ingredients:
* 1. code generator:
* [xo-facet/codegen/genfacet]
* arguments:
* --input [idl/IGCObject_DAtomicType.json5]
* 2. jinja2 template for abstract facet .hpp file:
* [iface_facet_repr.hpp.j2]
* 3. idl for facet methods
* [idl/IGCObject_DAtomicType.json5]
**/
#pragma once
#include "GCObject.hpp"
#include "DAtomicType.hpp"
namespace xo { namespace scm { class IGCObject_DAtomicType; } }
namespace xo {
namespace facet {
template <>
struct FacetImplementation<xo::mm::AGCObject,
xo::scm::DAtomicType>
{
using ImplType = xo::mm::IGCObject_Xfer
<xo::scm::DAtomicType,
xo::scm::IGCObject_DAtomicType>;
};
}
}
namespace xo {
namespace scm {
/** @class IGCObject_DAtomicType
**/
class IGCObject_DAtomicType {
public:
/** @defgroup scm-gcobject-datomictype-type-traits **/
///@{
using size_type = xo::mm::AGCObject::size_type;
using AAllocator = xo::mm::AGCObject::AAllocator;
using ACollector = xo::mm::AGCObject::ACollector;
using Copaque = xo::mm::AGCObject::Copaque;
using Opaque = xo::mm::AGCObject::Opaque;
///@}
/** @defgroup scm-gcobject-datomictype-methods **/
///@{
// const methods
/** memory consumption for this instance **/
static size_type shallow_size(const DAtomicType & self) noexcept;
/** copy instance using allocator **/
static Opaque shallow_copy(const DAtomicType & self, obj<AAllocator> mm) noexcept;
// non-const methods
/** during GC: forward immdiate children **/
static size_type forward_children(DAtomicType & self, obj<ACollector> gc) noexcept;
///@}
};
} /*namespace scm*/
} /*namespace xo*/
/* end */

View file

@ -0,0 +1,59 @@
/** @file IType_DAtomicType.hpp
*
* Generated automagically from ingredients:
* 1. code generator:
* [xo-facet/codegen/genfacet]
* arguments:
* --input [idl/IType_DAtomicType.json5]
* 2. jinja2 template for abstract facet .hpp file:
* [iface_facet_repr.hpp.j2]
* 3. idl for facet methods
* [idl/IType_DAtomicType.json5]
**/
#pragma once
#include "Type.hpp"
#include "DAtomicType.hpp"
namespace xo { namespace scm { class IType_DAtomicType; } }
namespace xo {
namespace facet {
template <>
struct FacetImplementation<xo::scm::AType,
xo::scm::DAtomicType>
{
using ImplType = xo::scm::IType_Xfer
<xo::scm::DAtomicType,
xo::scm::IType_DAtomicType>;
};
}
}
namespace xo {
namespace scm {
/** @class IType_DAtomicType
**/
class IType_DAtomicType {
public:
/** @defgroup scm-type-datomictype-type-traits **/
///@{
using obj_AType = xo::scm::AType::obj_AType;
using Copaque = xo::scm::AType::Copaque;
using Opaque = xo::scm::AType::Opaque;
///@}
/** @defgroup scm-type-datomictype-methods **/
///@{
// const methods
/** category for this type **/
static Metatype metatype(const DAtomicType & self) noexcept;
// non-const methods
///@}
};
} /*namespace scm*/
} /*namespace xo*/
/* end */

View file

@ -0,0 +1,21 @@
/** @file init_type.hpp
*
* @author Roland Conybeare, Jan 2026
**/
#pragma once
#include <xo/subsys/Subsystem.hpp>
namespace xo {
/* tag to represent the xo-expression2/ subsystem within ordered initialization */
enum S_type_tag {};
template <>
struct InitSubsys<S_type_tag> {
static void init();
static InitEvidence require();
};
} /*namespace xo*/
/* end init_type.hpp */

View file

@ -0,0 +1,77 @@
/** @file AType.hpp
*
* Generated automagically from ingredients:
* 1. code generator:
* [xo-facet/codegen/genfacet]
* arguments:
* --input [idl/Type.json5]
* 2. jinja2 template for abstract facet .hpp file:
* [abstract_facet.hpp.j2]
* 3. idl for facet methods
* [idl/Type.json5]
**/
#pragma once
// includes (via {facet_includes})
#include <xo/type/Metatype.hpp>
#include <xo/facet/obj.hpp>
#include <xo/facet/facet_implementation.hpp>
#include <xo/facet/typeseq.hpp>
// pretext if any
namespace xo {
namespace scm {
using Copaque = const void *;
using Opaque = void *;
/**
1. Ability to compare types as members of partial order
2. ...
**/
class AType {
public:
/** @defgroup scm-type-type-traits **/
///@{
// types
/** integer identifying a type **/
using typeseq = xo::facet::typeseq;
using Copaque = const void *;
using Opaque = void *;
/** **/
using obj_AType = xo::facet::obj<AType>;
///@}
/** @defgroup scm-type-methods **/
///@{
// const methods
/** RTTI: unique id# for actual runtime data representation **/
virtual typeseq _typeseq() const noexcept = 0;
/** destroy instance @p d; calls c++ dtor only for actual runtime type; does not recover memory **/
virtual void _drop(Opaque d) const noexcept = 0;
/** category for this type **/
virtual Metatype metatype(Copaque data) const noexcept = 0;
// nonconst methods
///@}
}; /*AType*/
/** Implementation IType_DRepr of AType for state DRepr
* should provide a specialization:
*
* template <>
* struct xo::facet::FacetImplementation<AType, DRepr> {
* using Impltype = IType_DRepr;
* };
*
* then IType_ImplType<DRepr> --> IType_DRepr
**/
template <typename DRepr>
using IType_ImplType = xo::facet::FacetImplType<AType, DRepr>;
} /*namespace scm*/
} /*namespace xo*/
/* AType.hpp */

View file

@ -0,0 +1,89 @@
/** @file IType_Any.hpp
*
* Generated automagically from ingredients:
* 1. code generator:
* [xo-facet/codegen/genfacet]
* arguments:
* --input [idl/Type.json5]
* 2. jinja2 template for abstract facet .hpp file:
* [iface_facet_any.hpp.j2]
* 3. idl for facet methods
* [idl/Type.json5]
**/
#pragma once
#include "AType.hpp"
#include <xo/facet/obj.hpp>
namespace xo { namespace scm { class IType_Any; } }
namespace xo {
namespace facet {
template <>
struct FacetImplementation<xo::scm::AType,
DVariantPlaceholder>
{
using ImplType = xo::scm::IType_Any;
};
}
}
namespace xo {
namespace scm {
/** @class IType_Any
* @brief AType implementation for empty variant instance
**/
class IType_Any : public AType {
public:
/** @defgroup scm-type-any-type-traits **/
///@{
/** integer identifying a type **/
using typeseq = xo::facet::typeseq;
using obj_AType = AType::obj_AType;
///@}
/** @defgroup scm-type-any-methods **/
///@{
const AType * iface() const { return std::launder(this); }
// from AType
// builtin methods
typeseq _typeseq() const noexcept override { return s_typeseq; }
[[noreturn]] void _drop(Opaque) const noexcept override { _fatal(); }
// const methods
[[noreturn]] Metatype metatype(Copaque) const noexcept override { _fatal(); }
// nonconst methods
///@}
private:
/** @defgraoup scm-type-any-private-methods **/
///@{
[[noreturn]] static void _fatal();
///@}
public:
/** @defgroup scm-type-any-member-vars **/
///@{
static typeseq s_typeseq;
static bool _valid;
///@}
};
} /*namespace scm */
} /*namespace xo */
/* IType_Any.hpp */

View file

@ -0,0 +1,84 @@
/** @file IType_Xfer.hpp
*
* Generated automagically from ingredients:
* 1. code generator:
* [xo-facet/codegen/genfacet]
* arguments:
* --input [idl/Type.json5]
* 2. jinja2 template for abstract facet .hpp file:
* [iface_facet_any.hpp.j2]
* 3. idl for facet methods
* [idl/Type.json5]
**/
#pragma once
#include <xo/type/Metatype.hpp>
namespace xo {
namespace scm {
/** @class IType_Xfer
**/
template <typename DRepr, typename IType_DRepr>
class IType_Xfer : public AType {
public:
/** @defgroup scm-type-xfer-type-traits **/
///@{
/** actual implementation (not generated; often delegates to DRepr) **/
using Impl = IType_DRepr;
/** integer identifying a type **/
using typeseq = AType::typeseq;
using obj_AType = AType::obj_AType;
///@}
/** @defgroup scm-type-xfer-methods **/
///@{
static const DRepr & _dcast(Copaque d) { return *(const DRepr *)d; }
static DRepr & _dcast(Opaque d) { return *(DRepr *)d; }
// from AType
// builtin methods
typeseq _typeseq() const noexcept override { return s_typeseq; }
void _drop(Opaque d) const noexcept override { _dcast(d).~DRepr(); }
// const methods
Metatype metatype(Copaque data) const noexcept override {
return I::metatype(_dcast(data));
}
// non-const methods
///@}
private:
using I = Impl;
public:
/** @defgroup scm-type-xfer-member-vars **/
///@{
/** typeseq for template parameter DRepr **/
static typeseq s_typeseq;
/** true iff satisfies facet implementation **/
static bool _valid;
///@}
};
template <typename DRepr, typename IType_DRepr>
xo::facet::typeseq
IType_Xfer<DRepr, IType_DRepr>::s_typeseq
= xo::facet::typeseq::id<DRepr>();
template <typename DRepr, typename IType_DRepr>
bool
IType_Xfer<DRepr, IType_DRepr>::_valid
= xo::facet::valid_facet_implementation<AType,
IType_Xfer>();
} /*namespace scm */
} /*namespace xo*/
/* end IType_Xfer.hpp */

View file

@ -0,0 +1,85 @@
/** @file RType.hpp
*
* Generated automagically from ingredients:
* 1. code generator:
* [xo-facet/codegen/genfacet]
* arguments:
* --input [idl/Type.json5]
* 2. jinja2 template for abstract facet .hpp file:
* [iface_facet_any.hpp.j2]
* 3. idl for facet methods
* [idl/Type.json5]
**/
#pragma once
#include "AType.hpp"
namespace xo {
namespace scm {
/** @class RType
**/
template <typename Object>
class RType : public Object {
private:
using O = Object;
public:
/** @defgroup scm-type-router-type-traits **/
///@{
using ObjectType = Object;
using DataPtr = Object::DataPtr;
using typeseq = xo::reflect::typeseq;
using obj_AType = AType::obj_AType;
///@}
/** @defgroup scm-type-router-ctors **/
///@{
RType() {}
RType(Object::DataPtr data) : Object{std::move(data)} {}
RType(const AType * iface, void * data)
requires std::is_same_v<typename Object::DataType, xo::facet::DVariantPlaceholder>
: Object(iface, data) {}
///@}
/** @defgroup scm-type-router-methods **/
///@{
// explicit injected content
// builtin methods
typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); }
void _drop() const noexcept { O::iface()->_drop(O::data()); }
// const methods
Metatype metatype() const noexcept {
return O::iface()->metatype(O::data());
}
// non-const methods (still const in router!)
///@}
/** @defgroup scm-type-member-vars **/
///@{
static bool _valid;
///@}
};
template <typename Object>
bool
RType<Object>::_valid = xo::facet::valid_object_router<Object>();
} /*namespace scm*/
} /*namespace xo*/
namespace xo { namespace facet {
template <typename Object>
struct RoutingFor<xo::scm::AType, Object> {
using RoutingType = xo::scm::RType<Object>;
};
} }
/* end RType.hpp */

View file

@ -0,0 +1,15 @@
/** @file type_register_facets.hpp
*
* @author Roland Conybeare, Jan 2026
**/
#pragma once
namespace xo {
namespace scm {
/** Register type (facet,impl) combinations with FacetRegistry **/
bool type_register_facets();
}
}
/* end type_register_facets.hpp */

View file

@ -0,0 +1,17 @@
/** @file type_register_types.hpp
*
* @author Roland Conybeare, Dec 2025
**/
#pragma once
#include <xo/alloc2/Collector.hpp>
namespace xo {
namespace scm {
/** Register type (facet,impl) combinations with FacetRegistry **/
bool type_register_types(obj<xo::mm::ACollector> gc);
}
}
/* end type_register_types.hpp */

25
src/type/CMakeLists.txt Normal file
View file

@ -0,0 +1,25 @@
# xo-type/src/type/CMakeLists.txt
set(SELF_LIB xo_type)
set(SELF_SRCS
init_type.cpp
type_register_facets.cpp
type_register_types.cpp
Metatype.cpp
DAtomicType.cpp
IType_DAtomicType.cpp
IGCObject_DAtomicType.cpp
)
xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS})
# ----------------------------------------------------------------
# input dependencies
#
# NOTE: dependency set here must be kept consistent with
# xo-type/cmake/xo_typeConfig.cmake.in
xo_dependency(${SELF_LIB} xo_alloc2)
xo_dependency(${SELF_LIB} xo_facet)
# end src/type/CMakeLists.txt

42
src/type/DAtomicType.cpp Normal file
View file

@ -0,0 +1,42 @@
/** @file DAtomicType.cpp
*
* @author Roland Conybeare, Mar 2026
**/
#include "AtomicType.hpp"
namespace xo {
namespace scm {
DAtomicType *
DAtomicType::_make(obj<AAllocator> mm, Metatype mtype)
{
void * mem = mm.alloc_for<DAtomicType>();
return new (mem) DAtomicType(mtype);
}
// ----- GCObject facet -----
std::size_t
DAtomicType::shallow_size() const noexcept
{
return sizeof(DAtomicType);
}
DAtomicType *
DAtomicType::shallow_copy(obj<AAllocator> mm) const noexcept
{
return mm.std_copy_for(this);
}
std::size_t
DAtomicType::forward_children(obj<ACollector>) noexcept
{
return this->shallow_size();
}
} /*namespace scm*/
} /*namespace xo*/
/* end DAtomicType.cpp */

View file

@ -0,0 +1,39 @@
/** @file IGCObject_DAtomicType.cpp
*
* Generated automagically from ingredients:
* 1. code generator:
* [xo-facet/codegen/genfacet]
* arguments:
* --input [idl/IGCObject_DAtomicType.json5]
* 2. jinja2 template for abstract facet .hpp file:
* [iface_facet_any.hpp.j2]
* 3. idl for facet methods
* [idl/IGCObject_DAtomicType.json5]
**/
#include "atomic/IGCObject_DAtomicType.hpp"
namespace xo {
namespace scm {
auto
IGCObject_DAtomicType::shallow_size(const DAtomicType & self) noexcept -> size_type
{
return self.shallow_size();
}
auto
IGCObject_DAtomicType::shallow_copy(const DAtomicType & self, obj<AAllocator> mm) noexcept -> Opaque
{
return self.shallow_copy(mm);
}
auto
IGCObject_DAtomicType::forward_children(DAtomicType & self, obj<ACollector> gc) noexcept -> size_type
{
return self.forward_children(gc);
}
} /*namespace scm*/
} /*namespace xo*/
/* end IGCObject_DAtomicType.cpp */

42
src/type/IType_Any.cpp Normal file
View file

@ -0,0 +1,42 @@
/** @file IType_Any.cpp
*
**/
#include "type/IType_Any.hpp"
#include <iostream>
#include <exception>
namespace xo {
namespace scm {
using xo::facet::DVariantPlaceholder;
using xo::facet::typeseq;
using xo::facet::valid_facet_implementation;
void
IType_Any::_fatal()
{
/* control here on uninitialized IAllocator_Any.
* Initialized instance will have specific implementation type
*/
std::cerr << "fatal"
<< ": attempt to call uninitialized"
<< " IType_Any method"
<< std::endl;
std::terminate();
}
typeseq
IType_Any::s_typeseq = typeseq::id<DVariantPlaceholder>();
bool
IType_Any::_valid
= valid_facet_implementation<AType, IType_Any>();
// nonconst methods
} /*namespace scm*/
} /*namespace xo*/
/* end IType_Any.cpp */

View file

@ -0,0 +1,28 @@
/** @file IType_DAtomicType.cpp
*
* Generated automagically from ingredients:
* 1. code generator:
* [xo-facet/codegen/genfacet]
* arguments:
* --input [idl/IType_DAtomicType.json5]
* 2. jinja2 template for abstract facet .hpp file:
* [iface_facet_any.hpp.j2]
* 3. idl for facet methods
* [idl/IType_DAtomicType.json5]
**/
#include "atomic/IType_DAtomicType.hpp"
namespace xo {
namespace scm {
auto
IType_DAtomicType::metatype(const DAtomicType & self) noexcept -> Metatype
{
return self.metatype();
}
} /*namespace scm*/
} /*namespace xo*/
/* end IType_DAtomicType.cpp */

32
src/type/Metatype.cpp Normal file
View file

@ -0,0 +1,32 @@
/** @file Metatype.cpp
*
* @author Roland Conybeare, Nar 2026
**/
#include "Metatype.hpp"
namespace xo {
namespace scm {
const char *
Metatype::_descr() const noexcept
{
switch (code_) {
case code::t_any: return "any";
case code::t_bool: return "bool";
case code::t_i64: return "i64";
case code::t_f64: return "f64";
case code::t_str: return "str";
case code::t_sum: return "sum";
case code::t_list: return "list";
case code::t_array: return "array";
case code::t_function: return "function";
case code::t_struct: return "struct";
case code::t_unit: return "unit";
}
}
} /*namespace scm*/
} /*namespace xo*/
/* end Metatype.cpp */

40
src/type/init_type.cpp Normal file
View file

@ -0,0 +1,40 @@
/** @file init_type.cpp
*
* @author Roland Conybeare, Jan 2026
**/
#include "init_type.hpp"
#include "type_register_facets.hpp"
#include "type_register_types.hpp"
#include <xo/alloc2/CollectorTypeRegistry.hpp>
#include <xo/alloc2/init_alloc2.hpp>
namespace xo {
using xo::scm::type_register_facets;
using xo::scm::type_register_types;
using xo::mm::CollectorTypeRegistry;
void
InitSubsys<S_type_tag>::init()
{
type_register_facets();
CollectorTypeRegistry::instance().register_types(&type_register_types);
}
InitEvidence
InitSubsys<S_type_tag>::require()
{
InitEvidence retval;
/* direct subsystem deps for xo-type/ */
retval ^= InitSubsys<S_alloc2_tag>::require();
/* xo-type/'s own initialization code */
retval ^= Subsystem::provide<S_type_tag>("type", &init);
return retval;
}
} /*namespace xo*/
/* end init_type.cpp */

View file

@ -0,0 +1,35 @@
/** @file type_register_facets.cpp
*
* @author Roland Conybeare, Feb 2026
**/
#include "type_register_facets.hpp"
#include <xo/type/AtomicType.hpp>
#include <xo/facet/FacetRegistry.hpp>
#include <xo/indentlog/scope.hpp>
namespace xo {
using xo::mm::AGCObject;
using xo::facet::FacetRegistry;
//using xo::facet::TypeRegistry;
using xo::reflect::typeseq;
namespace scm {
bool
type_register_facets()
{
scope log(XO_DEBUG(true));
FacetRegistry::register_impl<AGCObject, DAtomicType>();
log && log(xtag("DAtomicType.tseq", typeseq::id<DAtomicType>()));
return true;
}
} /*namespace scm*/
} /*namespace xo*/
/* end type_register_facets.cpp */

View file

@ -0,0 +1,34 @@
/** @file type_register_types.cpp
*
* @author Roland Conybeare, Dec 2025
**/
#include "type_register_types.hpp"
#include "AtomicType.hpp"
#include <xo/alloc2/Collector.hpp>
#include <xo/facet/FacetRegistry.hpp>
#include <xo/indentlog/scope.hpp>
namespace xo {
using xo::mm::ACollector;
using xo::mm::AGCObject;
using xo::facet::impl_for;
using xo::scope;
namespace scm {
bool
type_register_types(obj<ACollector> gc)
{
scope log(XO_DEBUG(true));
bool ok = true;
ok &= gc.install_type(impl_for<AGCObject, DAtomicType>());
return ok;
}
}
} /*namespace xo*/
/* end type_register_types.cpp */

16
utest/CMakeLists.txt Normal file
View file

@ -0,0 +1,16 @@
# built unittest xo-type/utest
set(UTEST_EXE utest.type)
set(UTEST_SRCS
type_utest_main.cpp
DAtomicType.test.cpp
# DString.test.cpp
# StringOps.test.cpp
# X1Collector.test.cpp
# Printable.test.cpp
)
xo_add_utest_executable(${UTEST_EXE} ${UTEST_SRCS})
xo_self_dependency(${UTEST_EXE} xo_type)
#xo_dependency(${UTEST_EXE} xo_alloc2)
xo_external_target_dependency(${UTEST_EXE} Catch2 Catch2::Catch2)

View file

@ -0,0 +1,40 @@
/** @file DAtomicType.test.cpp
*
* @author Roland Conybeare, Mar 2026
**/
#include "init_type.hpp"
#include "AtomicType.hpp"
#include <xo/alloc2/Allocator.hpp>
#include <xo/alloc2/Arena.hpp>
#include <xo/facet/obj.hpp>
#include <catch2/catch.hpp>
namespace xo {
using xo::scm::AType;
using xo::scm::DAtomicType;
using xo::scm::Metatype;
using xo::mm::AAllocator;
using xo::mm::DArena;
using xo::mm::ArenaConfig;
namespace ut {
static InitEvidence s_init = (InitSubsys<S_type_tag>::require());
TEST_CASE("DAtomicType-make", "[type][DAtomicType]")
{
ArenaConfig cfg { .name_ = "testarena",
.size_ = 4*1024 };
DArena arena = DArena::map(cfg);
auto alloc = obj<AAllocator,DArena>(&arena);
auto f64_type = obj<AType,DAtomicType>(DAtomicType::_make(alloc, Metatype::unit()));
REQUIRE(f64_type);
REQUIRE(f64_type.metatype().code() == Metatype::unit().code());
}
} /*namespace ut*/
} /*namespace xo*/
/* end DAtomicType.test.cpp */

24
utest/type_utest_main.cpp Normal file
View file

@ -0,0 +1,24 @@
/* file type_utest_main.cpp */
#include <xo/subsys/Subsystem.hpp>
#define CATCH_CONFIG_RUNNER
#include "catch2/catch.hpp"
int
main(int argc, char* argv[])
{
using xo::Subsystem;
// Your custom initialization code here
Subsystem::initialize_all();
// Run Catch2's test session
int result = Catch::Session().run(argc, argv);
// cleanup here, if any
return result;
}
/* end type_utest_main.cpp */