123 lines
4.8 KiB
C++
123 lines
4.8 KiB
C++
/** @file facet_implementation.hpp
|
|
*
|
|
* @author Roland Conybeare, Dec 2025
|
|
**/
|
|
|
|
#pragma once
|
|
|
|
#include "xo/facet/facet.hpp"
|
|
#include <concepts>
|
|
#include <type_traits>
|
|
|
|
namespace xo {
|
|
namespace facet {
|
|
// ----- facet implementation -----
|
|
|
|
// An implementation provides behavior (i.e. code, not data)
|
|
// for a particular abstract facet, specialized for a specific data type
|
|
|
|
/** For example ISpecific = IComplex_DPolarCoords
|
|
**/
|
|
template <typename AFacet, typename ISpecific>
|
|
concept implements_facet = requires {
|
|
std::is_base_of_v<AFacet, ISpecific>;
|
|
std::is_default_constructible_v<ISpecific>;
|
|
std::is_standard_layout_v<ISpecific>;
|
|
/** require no additional state **/
|
|
sizeof(ISpecific) == sizeof(AFacet);
|
|
};
|
|
|
|
/** Use: when defining datatype recovery for a typed facet implementation:
|
|
*
|
|
* template <typename Repr>
|
|
* struct AMyFacet_Impl : public AMyFacet {
|
|
* static void _something(Repr *);
|
|
* static int _andalso(Repr *, double somearg);
|
|
*
|
|
* virtual void something(void * data) const final override {
|
|
* _something((Repr *)data);
|
|
* }
|
|
*
|
|
* virtual int andalso(void * data, double somearg) const final override {
|
|
* _andalso((Repr *)data, somearg);
|
|
* }
|
|
*
|
|
* static bool _valid;
|
|
* };
|
|
*
|
|
* template <typename Repr>
|
|
* bool AMyFacet_Impl<Repr>::_valid
|
|
* = valid_facet_implementation<AMyFacet, AMyFacet_Specific>();
|
|
**/
|
|
template <typename AFacet, typename ISpecific>
|
|
consteval bool valid_facet_implementation()
|
|
requires (valid_abstract_facet<AFacet>())
|
|
{
|
|
static_assert(std::is_base_of_v<AFacet, ISpecific>,
|
|
"Facet implementation must inherit FacetRttiShim<AFacet>");
|
|
static_assert(std::is_default_constructible_v<ISpecific>,
|
|
"Facet implementation must be default-constructible");
|
|
static_assert(sizeof(ISpecific) == sizeof(AFacet),
|
|
"Facet implementation may not introduce state");
|
|
static_assert(!std::has_virtual_destructor_v<ISpecific>,
|
|
"Facet implementation does not benefit from virtual dtor (since has no data)");
|
|
static_assert(std::is_trivially_destructible_v<ISpecific>,
|
|
"Facet implementation expected to have trivial dtor (since has no data)");
|
|
|
|
// don't need this test, it's covered by sizeof check
|
|
//static_assert(std::is_pointer_interconvertible_base_of_v<AFacet, ISpecific>,
|
|
// "Interface implementation must directly inherit interface (no base offset)");
|
|
|
|
return true;
|
|
};
|
|
|
|
/** Compile-time facet implementation lookup
|
|
*
|
|
* @c FacetImplementation<AMyFacet, DSomeRepr>::ImplType
|
|
* gives the type that implements @c AMyFacet with state @c DSomeRepr
|
|
*
|
|
* template<DRepr>
|
|
* struct FacetImplementation<AMyFacet, DRepr> {
|
|
* using ImplType = IMyFacet_Impl<DRepr>;
|
|
* };
|
|
*
|
|
* template<>
|
|
* struct FacetImplementation<AMyFacet, DVariantPlaceholder> {
|
|
* using ImplType = IMyFacet_Any;
|
|
* };
|
|
*
|
|
**/
|
|
template <typename AFacet, typename DRepr>
|
|
struct FacetImplementation {
|
|
static_assert(false && "expect specialization <AFacet,DRepr> which should provide ImplType trait");
|
|
};
|
|
|
|
/** Retrieve facet implementation for a (facet, datatype) pair **/
|
|
template <typename AFacet, typename DRepr>
|
|
using FacetImplType = FacetImplementation<AFacet, DRepr>::ImplType;
|
|
|
|
/** Data type for facet implementation that supports runtime polymorphism.
|
|
* Implementation will stub all methods, since they will never be invoked.
|
|
*
|
|
* template <>
|
|
* struct IMyFacet_Any : public AMyFacet {
|
|
* virtual void something(void * data) const final override { assert(false); }
|
|
* virtual int andalso(void * data) const final override { assert(false); return 0; }
|
|
*
|
|
* static bool _valid;
|
|
* }
|
|
*
|
|
* template <>
|
|
* bool IMyFacet_Any::_valid
|
|
* = valid_facet_implementation<AMyFacet, IMyFacet_Any>();
|
|
**/
|
|
struct DVariantPlaceholder {};
|
|
|
|
/** PLAN:
|
|
* expect also will need runtime version of FacetImplementation.
|
|
**/
|
|
|
|
} /*namespace facet*/
|
|
} /*namespace xo*/
|
|
|
|
/* end facet_implementation.hpp */
|