Compare commits
11 commits
764185eb85
...
f23dbe1986
| Author | SHA1 | Date | |
|---|---|---|---|
| f23dbe1986 | |||
| b80587fd1b | |||
| ee629b56b7 | |||
| 3d01ebf63c | |||
| f2244414aa | |||
| 2467405c25 | |||
| a5f1709bff | |||
| 8be0a076c7 | |||
| 80944ab956 | |||
| f452cd268d | |||
| 0ebb2afc15 |
13 changed files with 1135 additions and 302 deletions
|
|
@ -115,6 +115,26 @@ namespace meta {
|
|||
{ };
|
||||
|
||||
|
||||
/**
|
||||
* Metafunction: build an ID-Type based on the position in the list
|
||||
* @remark when the type is not in the list, TypeIdxID ≔ 0
|
||||
*/
|
||||
template<typename TY, typename TYPES, uint idx=1>
|
||||
struct TypeIdxID
|
||||
: std::integral_constant<uint, 0>
|
||||
{ };
|
||||
|
||||
template<typename TY, typename TYPES, uint idx>
|
||||
struct TypeIdxID<TY, Node<TY,TYPES>, idx> ///< @return 1-based position in case of match
|
||||
: std::integral_constant<uint, idx>
|
||||
{ };
|
||||
|
||||
template<typename X, typename TY, typename TYPES, uint idx>
|
||||
struct TypeIdxID<X, Node<TY,TYPES>, idx> ///< else recurse to check next element
|
||||
: TypeIdxID<X, TYPES, idx+1>
|
||||
{ };
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Build a list of const types from a given typelist.
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#define LIB_PAR_DISPOSITION_H
|
||||
|
||||
|
||||
#include "lib/par/spec.hpp"
|
||||
#include "lib/par/provision.hpp"
|
||||
#include "lib/par/param-type.hpp"
|
||||
|
||||
|
|
@ -33,6 +34,31 @@
|
|||
namespace lib {
|
||||
namespace par {
|
||||
|
||||
using ValStorage = ValBuffStorage<BASETYPE_MAX_SIZ>;
|
||||
|
||||
|
||||
/**
|
||||
* Implementation-Service: complete Parameter functionality.
|
||||
* Includes the ability to access / set a »value«, attach automation,
|
||||
* identify and convert underlying value data types and handle
|
||||
* trait- and identity tags and the specifics of the value scale.
|
||||
*/
|
||||
class Disposition
|
||||
: public Domain
|
||||
{
|
||||
IDRecord idr_;
|
||||
|
||||
public:
|
||||
template<typename X>
|
||||
X extract() const;
|
||||
|
||||
template<typename X>
|
||||
void setVal (X);
|
||||
|
||||
private:
|
||||
template<typename X>
|
||||
bool isBaseDomainMatch() const;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -40,12 +66,88 @@ namespace par {
|
|||
* with domain and scale, and a value provision. Can be generated through a builder
|
||||
* notation and stored within the Parameter object (as a container).
|
||||
*/
|
||||
class Disposition
|
||||
: public ParamType
|
||||
template<typename VAL, class IFA =Disposition> /////////////////////////////////////////////////////TICKET #1197 : the second template argument is quite confusing and became necessary due to the limitations of PolymorphicValue
|
||||
class ParamData
|
||||
: public TypedEntity<VAL, IFA>
|
||||
{
|
||||
VAL val_;
|
||||
Provision* src_;
|
||||
|
||||
/* === Provision Interface === */
|
||||
void retrieveInto (ValBuff&) const override;
|
||||
void setValFrom (ValBuff const&) override;
|
||||
|
||||
public:
|
||||
ParamData (VAL initVal)
|
||||
: val_{std::move (initVal)}
|
||||
, src_{nullptr}
|
||||
{ }
|
||||
};
|
||||
|
||||
template<typename X>
|
||||
using FullDomain = BaseDomain<X, Disposition>;
|
||||
|
||||
|
||||
|
||||
template<typename VAL, class IFA>
|
||||
void
|
||||
ParamData<VAL, IFA>::retrieveInto (ValBuff& target) const
|
||||
{
|
||||
asValue<VAL>(target) = val_;
|
||||
}
|
||||
|
||||
template<typename VAL, class IFA>
|
||||
void
|
||||
ParamData<VAL, IFA>::setValFrom (ValBuff const& newVal)
|
||||
{
|
||||
val_ = asValue<VAL>(newVal);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename X>
|
||||
X
|
||||
Disposition::extract() const
|
||||
{
|
||||
X result; // RVO
|
||||
|
||||
if (isBaseDomainMatch<X>())
|
||||
{ // short-circuit by direct force-cast
|
||||
retrieveInto (asValBuff (result));
|
||||
}
|
||||
else
|
||||
{ // run full type-conversion dispatch
|
||||
ValStorage valueBuffer;
|
||||
this->retrieveInto (valueBuffer);
|
||||
this->extractAs (result, valueBuffer);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
template<typename X>
|
||||
void
|
||||
Disposition::setVal (X changedVal)
|
||||
{
|
||||
if (isBaseDomainMatch<X>())
|
||||
{ // short-circuit by direct force-cast
|
||||
setValFrom (asValBuff (changedVal));
|
||||
}
|
||||
else
|
||||
{ // run full type-conversion dispatch
|
||||
ValStorage valueBuffer;
|
||||
this->conform (valueBuffer, changedVal);
|
||||
this->setValFrom (valueBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename X>
|
||||
bool
|
||||
Disposition::isBaseDomainMatch() const
|
||||
{
|
||||
return false; /////////////////////////OOO running into a dead end here? how can we possibly access a type tag marker without indirection??
|
||||
}
|
||||
|
||||
|
||||
}} // namespace lib::par
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@
|
|||
#define LIB_PAR_DOMAIN_H
|
||||
|
||||
|
||||
#include "lib/par/spec.hpp"
|
||||
#include "lib/meta/typelist.hpp"
|
||||
//#include "lib/meta/typelist-util.hpp"
|
||||
#include "lib/meta/generator.hpp"
|
||||
#include "lib/par/provision.hpp"
|
||||
#include "lib/meta/trait.hpp"
|
||||
|
|
@ -54,62 +54,31 @@ namespace par {
|
|||
using std::numeric_limits;
|
||||
|
||||
|
||||
/* ===== Type Handler Interface for generic parameter value access ===== */
|
||||
|
||||
template<typename X>
|
||||
constexpr inline ValBuff&
|
||||
asValBuff (X& something)
|
||||
{
|
||||
void* rawMem{& something};
|
||||
return * static_cast<ValBuff*> (rawMem);
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
constexpr inline ValBuff const&
|
||||
asValBuff (X const& something)
|
||||
{
|
||||
void const * rawMem{& something};
|
||||
return * static_cast<ValBuff const *> (rawMem);
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
constexpr inline X&
|
||||
asValue (ValBuff& storage)
|
||||
{
|
||||
void* rawMem{& storage};
|
||||
return * static_cast<X*> (rawMem);
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
constexpr inline X const&
|
||||
asValue (ValBuff const& storage)
|
||||
{
|
||||
void const * rawMem{& storage};
|
||||
return * static_cast<X const *> (rawMem);
|
||||
}
|
||||
|
||||
|
||||
template<typename X>
|
||||
class TypeHandler
|
||||
class HandlerBase
|
||||
: public Provision
|
||||
{
|
||||
public:
|
||||
virtual void extractAs (X& targetVal, ValBuff const& valBuff) =0;
|
||||
virtual void conform (ValBuff& targetBuff, X const& srcVal) =0;
|
||||
|
||||
void extractAs();
|
||||
void conform();
|
||||
};
|
||||
|
||||
// using lib::meta::typeseq;
|
||||
template<typename X, class PAR>
|
||||
class TypeHandler
|
||||
: public PAR
|
||||
{
|
||||
public:
|
||||
virtual void extractAs (X& targetVal, ValBuff const& valBuff) const =0;
|
||||
virtual void conform (ValBuff& targetBuff, X const& srcVal) =0;
|
||||
|
||||
using PAR::extractAs;
|
||||
using PAR::conform;
|
||||
};
|
||||
|
||||
|
||||
using BaseTypes = meta::Types<int
|
||||
,int64_t
|
||||
,uint
|
||||
,uint64_t
|
||||
,double
|
||||
,float
|
||||
,bool
|
||||
>;
|
||||
/** build a generic visitor interface for all types in list */
|
||||
using TypeHandlerInterface = meta::InstantiateForEach<BaseTypes::List, TypeHandler, Provision>;
|
||||
using TypeHandlerInterface = meta::InstantiateChained<BaseTypes::List, TypeHandler, HandlerBase>;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -129,185 +98,12 @@ namespace par {
|
|||
virtual ~Domain(); ///< this is an interface
|
||||
|
||||
virtual void applyLimit (ValBuff&) =0;
|
||||
virtual void transferTo (ValBuff const& source, Domain& targetDomain, ValBuff& target) =0;
|
||||
virtual void transferTo (ValBuff const& source, Domain& targetDomain, ValBuff& target) const =0;
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
|
||||
|
||||
// GCC > 13 warns at class definition when a new overload shadows an inherited virtual function.
|
||||
// While theoretically correct, in practice any call will be dispatched through the base interface,
|
||||
// which in turn is also generated by metaprogramming from a type list.
|
||||
// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109740
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Woverloaded-virtual\"")
|
||||
|
||||
|
||||
|
||||
template<typename V>
|
||||
struct DomainSetup
|
||||
{
|
||||
|
||||
template<typename X, class BAS>
|
||||
class TypeHandlerImpl
|
||||
: public BAS
|
||||
{
|
||||
void extractAs (X& targetVal, ValBuff const& valBuff) override;
|
||||
void conform (ValBuff& targetBuff, X const& srcVal) override;
|
||||
};
|
||||
|
||||
using TypeHandlerChain = meta::InstantiateChained<BaseTypes::List, TypeHandlerImpl, Domain>;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<typename V>
|
||||
class BaseDomain
|
||||
: public DomainSetup<V>::TypeHandlerChain
|
||||
{
|
||||
public:
|
||||
void applyLimit (ValBuff&) override;
|
||||
void transferTo (ValBuff const& source, Domain& targetDomain, ValBuff& target) override;
|
||||
};
|
||||
|
||||
|
||||
/* ===== type conversion details ===== */
|
||||
|
||||
/** Constraint: type \a SUB can not represent the full domain of type \a BAS
|
||||
* @todo implicitly also implements a limitation to »numeric« types,
|
||||
* due to the use of std::numeric_limits
|
||||
*/
|
||||
template<typename SUB, typename BAS>
|
||||
concept sub_domain = std::signed_integral<SUB> != std::signed_integral<BAS>
|
||||
or std::numeric_limits<SUB>::max() < std::numeric_limits<BAS>::max()
|
||||
or std::numeric_limits<SUB>::lowest() > std::numeric_limits<BAS>::lowest()
|
||||
;
|
||||
|
||||
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wsign-compare\"")
|
||||
// the following functions are specifically crafted to work around
|
||||
// the ambiguities caused by automatic signed-to-unsigned promotion;
|
||||
// furthermore, the automatic promotion allows to perform the comparison.
|
||||
|
||||
template<typename X, typename Y>
|
||||
inline constexpr bool
|
||||
isLower_safe (X const& x, Y const& y)
|
||||
{
|
||||
return isNeg(x) == isNeg(y)? x < y
|
||||
: isNeg(x);
|
||||
}
|
||||
|
||||
template<typename X, typename Y>
|
||||
inline constexpr bool
|
||||
isLarger_safe (X const& x, Y const& y)
|
||||
{
|
||||
return isNeg(x) == isNeg(y)? x > y
|
||||
: isNeg(y);
|
||||
}
|
||||
_Pragma("GCC diagnostic pop")
|
||||
|
||||
/** generic helper to conform into a common value domain
|
||||
* @tparam SUB the implied target value domain
|
||||
* @tparam BAS source data type
|
||||
* @return a value in source data type,
|
||||
* yet conformed into the target data range
|
||||
*/
|
||||
template<typename SUB, typename BAS>
|
||||
inline constexpr BAS
|
||||
preClamp (BAS const& value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/** special case: clamp the source value into the target value domain.
|
||||
* @remark tricky due to automatic conversions between signed/unsigned */
|
||||
template<typename SUB, typename BAS> requires (sub_domain<SUB,BAS>
|
||||
and not same_as<SUB,bool>)
|
||||
inline constexpr BAS
|
||||
preClamp (BAS const& rawVal)
|
||||
{
|
||||
static_assert (std::is_constructible_v<BAS,SUB const&>
|
||||
,"Value domains must overlap at least partially "
|
||||
"and values must be cross-constructible within overlap");
|
||||
|
||||
auto upperBound = numeric_limits<SUB>::max();
|
||||
auto lowerBound = numeric_limits<SUB>::lowest();
|
||||
|
||||
return isLarger_safe(rawVal, upperBound)? BAS(upperBound)
|
||||
: isLower_safe (rawVal, lowerBound)? BAS(lowerBound)
|
||||
: rawVal;
|
||||
}
|
||||
|
||||
/** special case: trigger a bool at the 0.5 level */
|
||||
template<same_as<bool> B, floating_point F>
|
||||
inline constexpr F
|
||||
preClamp (F const& rawVal)
|
||||
{
|
||||
return 0.5 < rawVal? F{1} : F{0};
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename V, typename X>
|
||||
inline void
|
||||
assignConverted (V& targetVal, X const& srcVal)
|
||||
{
|
||||
if constexpr (std::is_assignable_v<V&, X const&>)
|
||||
{
|
||||
targetVal = preClamp<V> (srcVal);
|
||||
}
|
||||
else
|
||||
if constexpr (std::is_constructible_v<V, X const&>)
|
||||
{
|
||||
targetVal.~U();
|
||||
new(&targetVal) V (preClamp<V> (srcVal));
|
||||
}
|
||||
else
|
||||
static_assert (!sizeof(X), "this type conversion is not supported");
|
||||
}
|
||||
|
||||
|
||||
template<typename V>
|
||||
template<typename X, class BAS>
|
||||
inline void
|
||||
DomainSetup<V>::TypeHandlerImpl<X,BAS>::extractAs (X& targetVal, ValBuff const& valBuff)
|
||||
{
|
||||
V const& srcVal = asValue<V> (valBuff);
|
||||
assignConverted (targetVal, srcVal);
|
||||
}
|
||||
|
||||
|
||||
template<typename V>
|
||||
template<typename X, class BAS>
|
||||
inline void
|
||||
DomainSetup<V>::TypeHandlerImpl<X,BAS>::conform (ValBuff& targetBuff, X const& srcVal)
|
||||
{
|
||||
V& targetVal = asValue<V> (targetBuff);
|
||||
assignConverted (targetVal, srcVal);
|
||||
}
|
||||
|
||||
|
||||
template<typename V>
|
||||
inline void
|
||||
BaseDomain<V>::applyLimit (ValBuff& valBuff)
|
||||
{
|
||||
V& val{asValue<V> (valBuff)};
|
||||
val = preClamp<V> (val);
|
||||
}
|
||||
|
||||
|
||||
template<typename V>
|
||||
inline void
|
||||
BaseDomain<V>::transferTo (ValBuff const& source, Domain& targetDomain, ValBuff& target)
|
||||
{
|
||||
TypeHandler<V>& typeHandler{targetDomain};
|
||||
typeHandler.conform (target, asValue<V> (source));
|
||||
targetDomain.applyLimit (target);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}} // namespace lib::par
|
||||
#endif /*LIB_PAR_DOMAIN_H*/
|
||||
|
|
|
|||
|
|
@ -14,8 +14,17 @@
|
|||
|
||||
/** @file param-type.hpp
|
||||
** Specification of the value domain and scale of a parameter.
|
||||
** A ParamType descriptor implicitly also encodes the concrete value type, the
|
||||
** allowed value range, clipping behaviour and specifics of the scale (discrete,
|
||||
** The implementation of parameters is built up in layers, starting from the generic
|
||||
** interfaces \ref Provision, which describes the fundamental capabilities of a
|
||||
** parameter as conceptualised here) and \ref Domain to support type conversions.
|
||||
**
|
||||
** All extensions beyond this point can be considered implementation-level services.
|
||||
** The BaseDomain layer provides the actual type conversion services, based on internal
|
||||
** knowledge of the concrete data type handled by this parameter.
|
||||
**
|
||||
** A \ref TypedEntity descriptor adds storage to capture type properties and allow
|
||||
** for an ID registration. In addition, the concrete value type is tagged, marking
|
||||
** the allowed value range, clipping behaviour and specifics of the scale (discrete,
|
||||
** stepping, continuous, logarithmic...).
|
||||
**
|
||||
** @todo WIP-WIP-WIP can be considered an initial draft and placeholder, as of 2026
|
||||
|
|
@ -27,22 +36,197 @@
|
|||
|
||||
|
||||
#include "lib/par/domain.hpp"
|
||||
#include "lib/meta/generator.hpp"
|
||||
|
||||
|
||||
namespace lib {
|
||||
namespace par {
|
||||
|
||||
|
||||
// GCC > 13 warns at class definition when a new overload shadows an inherited virtual function.
|
||||
// While theoretically correct, in practice any call will be dispatched through the base interface,
|
||||
// which in turn is also generated by metaprogramming from a type list.
|
||||
// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109740
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Woverloaded-virtual\"")
|
||||
|
||||
|
||||
template<typename VAL, class IFA>
|
||||
struct DomainSetup
|
||||
{
|
||||
|
||||
template<typename X, class PAR>
|
||||
class TypeHandlerImpl
|
||||
: public PAR
|
||||
{
|
||||
void extractAs (X& targetVal, ValBuff const& valBuff) const override;
|
||||
void conform (ValBuff& targetBuff, X const& srcVal) override;
|
||||
};
|
||||
|
||||
using TypeHandlerChain = meta::InstantiateChained<BaseTypes::List, TypeHandlerImpl, IFA>;
|
||||
};
|
||||
|
||||
|
||||
|
||||
template<typename VAL, class IFA>
|
||||
class BaseDomain
|
||||
: public DomainSetup<VAL, IFA>::TypeHandlerChain
|
||||
{
|
||||
public:
|
||||
void applyLimit (ValBuff&) override;
|
||||
void transferTo (ValBuff const& source, Domain& targetDomain, ValBuff& target) const override;
|
||||
};
|
||||
|
||||
|
||||
/* ===== type conversion details ===== */
|
||||
|
||||
/** Constraint: type \a SUB can not represent the full domain of type \a BAS
|
||||
* @todo implicitly also implements a limitation to »numeric« types,
|
||||
* due to the use of std::numeric_limits
|
||||
*/
|
||||
template<typename SUB, typename BAS>
|
||||
concept sub_domain = std::signed_integral<SUB> != std::signed_integral<BAS>
|
||||
or std::numeric_limits<SUB>::max() < std::numeric_limits<BAS>::max()
|
||||
or std::numeric_limits<SUB>::lowest() > std::numeric_limits<BAS>::lowest()
|
||||
;
|
||||
|
||||
|
||||
_Pragma("GCC diagnostic push") \
|
||||
_Pragma("GCC diagnostic ignored \"-Wsign-compare\"")
|
||||
// the following functions are specifically crafted to work around
|
||||
// the ambiguities caused by automatic signed-to-unsigned promotion;
|
||||
// furthermore, the automatic promotion allows to perform the comparison.
|
||||
|
||||
template<typename X, typename Y>
|
||||
inline constexpr bool
|
||||
isLower_safe (X const& x, Y const& y)
|
||||
{
|
||||
return isNeg(x) == isNeg(y)? x < y
|
||||
: isNeg(x);
|
||||
}
|
||||
|
||||
template<typename X, typename Y>
|
||||
inline constexpr bool
|
||||
isLarger_safe (X const& x, Y const& y)
|
||||
{
|
||||
return isNeg(x) == isNeg(y)? x > y
|
||||
: isNeg(y);
|
||||
}
|
||||
_Pragma("GCC diagnostic pop")
|
||||
|
||||
|
||||
/** generic helper to conform into a common value domain
|
||||
* @tparam SUB the implied target value domain
|
||||
* @tparam BAS source data type
|
||||
* @return a value in source data type,
|
||||
* yet conformed into the target data range
|
||||
*/
|
||||
template<typename SUB, typename BAS>
|
||||
inline constexpr BAS
|
||||
preClamp (BAS const& value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/** special case: clamp the source value into the target value domain.
|
||||
* @remark tricky due to automatic conversions between signed/unsigned */
|
||||
template<typename SUB, typename BAS> requires (sub_domain<SUB,BAS>
|
||||
and not same_as<SUB,bool>)
|
||||
inline constexpr BAS
|
||||
preClamp (BAS const& rawVal)
|
||||
{
|
||||
static_assert (std::is_constructible_v<BAS,SUB const&>
|
||||
,"Value domains must overlap at least partially "
|
||||
"and values must be cross-constructible within overlap");
|
||||
|
||||
auto upperBound = numeric_limits<SUB>::max();
|
||||
auto lowerBound = numeric_limits<SUB>::lowest();
|
||||
|
||||
return isLarger_safe(rawVal, upperBound)? BAS(upperBound)
|
||||
: isLower_safe (rawVal, lowerBound)? BAS(lowerBound)
|
||||
: rawVal;
|
||||
}
|
||||
|
||||
/** special case: trigger a bool at the 0.5 level */
|
||||
template<same_as<bool> B, floating_point F>
|
||||
inline constexpr F
|
||||
preClamp (F const& rawVal)
|
||||
{
|
||||
return 0.5 < rawVal? F{1} : F{0};
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename V, typename X>
|
||||
inline void
|
||||
assignConverted (V& targetVal, X const& srcVal)
|
||||
{
|
||||
if constexpr (std::is_assignable_v<V&, X const&>)
|
||||
{
|
||||
targetVal = preClamp<V> (srcVal);
|
||||
}
|
||||
else
|
||||
if constexpr (std::is_constructible_v<V, X const&>)
|
||||
{
|
||||
targetVal.~U();
|
||||
new(&targetVal) V (preClamp<V> (srcVal));
|
||||
}
|
||||
else
|
||||
static_assert (!sizeof(X), "this type conversion is not supported");
|
||||
}
|
||||
|
||||
|
||||
template<typename VAL, class IFA>
|
||||
template<typename X, class PAR>
|
||||
inline void
|
||||
DomainSetup<VAL,IFA>::TypeHandlerImpl<X,PAR>::extractAs (X& targetVal, ValBuff const& valBuff) const
|
||||
{
|
||||
VAL const& srcVal = asValue<VAL> (valBuff);
|
||||
assignConverted (targetVal, srcVal);
|
||||
}
|
||||
|
||||
|
||||
template<typename VAL, class IFA>
|
||||
template<typename X, class PAR>
|
||||
inline void
|
||||
DomainSetup<VAL,IFA>::TypeHandlerImpl<X,PAR>::conform (ValBuff& targetBuff, X const& srcVal)
|
||||
{
|
||||
VAL& targetVal = asValue<VAL> (targetBuff);
|
||||
assignConverted (targetVal, srcVal);
|
||||
}
|
||||
|
||||
|
||||
template<typename VAL, class IFA>
|
||||
inline void
|
||||
BaseDomain<VAL,IFA>::applyLimit (ValBuff& valBuff)
|
||||
{
|
||||
VAL& val{asValue<VAL> (valBuff)};
|
||||
val = preClamp<VAL> (val);
|
||||
}
|
||||
|
||||
|
||||
template<typename VAL, class IFA>
|
||||
inline void
|
||||
BaseDomain<VAL,IFA>::transferTo (ValBuff const& source, Domain& targetDomain, ValBuff& target) const
|
||||
{
|
||||
targetDomain.conform (target, asValue<VAL> (source));
|
||||
targetDomain.applyLimit (target);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Interface: represent a specific configuration of parameter value type,
|
||||
* Service-Interface: represent a specific configuration of parameter value type,
|
||||
* range and scale. Every ParamType descriptor is also a _prototype_ and has
|
||||
* an unique identity, ensured by registration, so that it acts as a type identifier.
|
||||
* @todo RLY? registration??
|
||||
* Furthermore, the interface exposes allowed conversion and conforming operations.
|
||||
*/
|
||||
class ParamType
|
||||
: public Domain
|
||||
template<typename VAL, class IFA>
|
||||
class TypedEntity
|
||||
: public BaseDomain<VAL,IFA>
|
||||
{
|
||||
public:
|
||||
};
|
||||
|
|
|
|||
|
|
@ -29,11 +29,25 @@
|
|||
#define LIB_PAR_PARAMETER_H
|
||||
|
||||
|
||||
#include "lib/par/disposition.hpp"
|
||||
#include "lib/polymorphic-value.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace lib {
|
||||
namespace par {
|
||||
|
||||
namespace {
|
||||
static constexpr size_t PAYLOAD_SIZ = sizeof(ParamData<double>) - sizeof(void*); ////////////////////////TICKET #1197 : this is a mess! PolymorphicValue adds the ADMIN_OVERHEAD (but our payload has already a VTable)
|
||||
using ParameterImplAPI = Disposition;
|
||||
using CopySupportMarker = polyvalue::CopySupport<ParameterImplAPI>;
|
||||
using ParamContainer = PolymorphicValue<ParameterImplAPI, PAYLOAD_SIZ, CopySupportMarker>;
|
||||
}
|
||||
|
||||
using util::unConst;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -41,12 +55,14 @@ namespace par {
|
|||
* The value can be fixed or supplied by an automation function.
|
||||
*/
|
||||
class Parameter
|
||||
: protected ParamContainer
|
||||
{
|
||||
public:
|
||||
template<typename VAL>
|
||||
class Builder;
|
||||
|
||||
template<typename VAL>
|
||||
VAL getVal();
|
||||
VAL getVal() const;
|
||||
|
||||
template<typename VAL>
|
||||
void setVal (VAL&&);
|
||||
|
|
@ -54,37 +70,59 @@ namespace par {
|
|||
/* === Builder API === */
|
||||
|
||||
template<typename VAL>
|
||||
static Builder forType();
|
||||
static Builder<VAL>
|
||||
forType() { return {}; }
|
||||
|
||||
template<typename VAL>
|
||||
static Builder<std::decay_t<VAL>>
|
||||
forValue (VAL&& initVal)
|
||||
{
|
||||
using PayloadType = std::decay_t<VAL>;
|
||||
return forType<PayloadType>()
|
||||
.withValue (std::forward<VAL> (initVal));
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
template<class IMP, typename...ARGS>
|
||||
Parameter (IMP* typeTag, ARGS&&... args)
|
||||
: PolymorphicValue (typeTag, std::forward<ARGS>(args)...)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
template<typename VAL> requires par_basetype<VAL>
|
||||
class Parameter::Builder
|
||||
{
|
||||
VAL initVal_{};
|
||||
|
||||
public:
|
||||
Parameter
|
||||
build()
|
||||
{
|
||||
UNIMPLEMENTED ("terminal builder operation: package a disposition into the Parameter");
|
||||
using ImplPackage = ParamData<VAL, CopySupportMarker>; //////////////////////////////////////////TICKET #1197 : remove the necessity to inject the CopySupportMarker
|
||||
ImplPackage* typeTag{nullptr};
|
||||
Parameter resParam{typeTag, std::move (initVal_)};
|
||||
return resParam;
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
Builder&&
|
||||
withValue (X&& initVal)
|
||||
{
|
||||
initVal_ = std::forward<X> (initVal);
|
||||
return std::move(this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename VAL>
|
||||
Parameter::Builder
|
||||
Parameter::forType()
|
||||
{
|
||||
UNIMPLEMENTED ("how to setup the base type configuration? do we need a type parameter in the Builder class?");
|
||||
}
|
||||
|
||||
|
||||
template<typename VAL>
|
||||
VAL
|
||||
Parameter::getVal()
|
||||
Parameter::getVal() const
|
||||
{
|
||||
UNIMPLEMENTED ("extract the »value«, possibly applying suitable type conversions");
|
||||
static_assert (isBaseType<VAL>, "only preconfigured parameter BaseTypes are supported");
|
||||
|
||||
return unConst(this)->getPayload().extract<VAL>();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -92,7 +130,9 @@ namespace par {
|
|||
void
|
||||
Parameter::setVal (VAL&& changedVal)
|
||||
{
|
||||
UNIMPLEMENTED ("apply suitable type conversions and clamping, then transfer the new value into the Provision interface");
|
||||
static_assert (isBaseType<VAL>, "only preconfigured parameter BaseTypes are supported");
|
||||
|
||||
getPayload().setVal (changedVal);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -33,16 +33,62 @@ namespace par {
|
|||
|
||||
using time::Time;
|
||||
|
||||
/** Marker for an opaque value buffer with
|
||||
* undisclosed size and content type */
|
||||
struct ValBuff { /*placeholder*/ };
|
||||
|
||||
|
||||
template<typename X>
|
||||
constexpr inline ValBuff&
|
||||
asValBuff (X& something)
|
||||
{
|
||||
void* rawMem{& something};
|
||||
return * static_cast<ValBuff*> (rawMem);
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
constexpr inline ValBuff const&
|
||||
asValBuff (X const& something)
|
||||
{
|
||||
void const * rawMem{& something};
|
||||
return * static_cast<ValBuff const *> (rawMem);
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
constexpr inline X&
|
||||
asValue (ValBuff& storage)
|
||||
{
|
||||
void* rawMem{& storage};
|
||||
return * static_cast<X*> (rawMem);
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
constexpr inline X const&
|
||||
asValue (ValBuff const& storage)
|
||||
{
|
||||
void const * rawMem{& storage};
|
||||
return * static_cast<X const *> (rawMem);
|
||||
}
|
||||
|
||||
|
||||
template<size_t bytes>
|
||||
struct ValBuffStorage
|
||||
: ValBuff
|
||||
{
|
||||
std::byte data[bytes];
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Interface: access to a parameter's value, to adjust or evaluate automation.
|
||||
* Conceptually, the value is decomposed into a _base value_ and possibly a
|
||||
* time-controlled adjustment (automation). The base value can be retrieved
|
||||
* and assigned, while the current time-based value is the result of evaluation.
|
||||
* Any parameter value is associated to a ParamType that defines the underlying
|
||||
* value domain and possibly a scale with range limits and metric constraints.
|
||||
* Any parameter value is implicitly associated with a Type that defines the
|
||||
* underlying [value domain](\ref Domain) and possibly a \ref Scale that
|
||||
* defines range limits and metric constraints.
|
||||
* @remark the value access and manipulation works _backwards_ from an implicit
|
||||
* value that is conceptually located _within_ this provision towards
|
||||
* an ValBuff for external access. The reason for this indirect
|
||||
|
|
|
|||
95
src/lib/par/spec.hpp
Normal file
95
src/lib/par/spec.hpp
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
SPEC.hpp - parameter trait specification
|
||||
|
||||
Copyright (C)
|
||||
2026 Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
**Lumiera** is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2 of the License, or (at your
|
||||
option) any later version. See the file COPYING for further details.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/** @file spec.hpp
|
||||
** Common definition and specification record for parameters.
|
||||
** While most functionality of parameters is indirected in some way, allowing
|
||||
** for future extension, some basic traits are marked as flag, so that frequently
|
||||
** used code-paths might take a shortcut. Notably the disposition interface, which
|
||||
** describes the full implementation service of a parameter container, explicitly
|
||||
** reserves one «slot» of storage for flags, type markers and an ID record.
|
||||
**
|
||||
** @todo WIP-WIP-WIP can be considered an initial draft and placeholder, as of 2026
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LIB_PAR_SPEC_H
|
||||
#define LIB_PAR_SPEC_H
|
||||
|
||||
|
||||
#include "lib/symbol.hpp"
|
||||
#include "lib/meta/typelist.hpp"
|
||||
#include "lib/meta/typelist-util.hpp"
|
||||
|
||||
|
||||
|
||||
namespace lib {
|
||||
namespace par {
|
||||
|
||||
/**
|
||||
* Fixed collection of elementary types supported in parameters
|
||||
*/
|
||||
using BaseTypes = meta::Types<int
|
||||
,int64_t
|
||||
,uint
|
||||
,uint64_t
|
||||
,double
|
||||
,float
|
||||
,bool
|
||||
>;
|
||||
|
||||
static constexpr uint BASETYPE_CNT = meta::count<BaseTypes::List>();
|
||||
static constexpr uint BASETYPE_MAX_SIZ = meta::maxSize<BaseTypes::List>();
|
||||
|
||||
template<typename T>
|
||||
static constexpr bool isBaseType = meta::isInList<T, BaseTypes::List>::value;
|
||||
|
||||
/** @note Only some fixed base data types are supported as Parameter value type. */
|
||||
template<typename T>
|
||||
concept par_basetype = isBaseType<T>;
|
||||
|
||||
template<typename T>
|
||||
using BaseTypeID = meta::TypeIdxID<T, BaseTypes::List>;
|
||||
|
||||
|
||||
|
||||
/* ===== setup of ID space ===== */
|
||||
|
||||
namespace {
|
||||
auto _bit_fit = [](uint bits){ return (1u << bits) - 1; };
|
||||
}
|
||||
|
||||
static constexpr uint _BASE_TYPE_BITS = 4;
|
||||
static constexpr uint _SCALES_BITS = 10;
|
||||
static constexpr uint _PARAM_ID_BITS = 18;
|
||||
|
||||
static constexpr uint MAX_BASETYPES = _bit_fit(_BASE_TYPE_BITS); ///< max number of parameter base types that can be configured
|
||||
static constexpr uint MAX_SCALES = _bit_fit(_SCALES_BITS); ///< max number of distinct scales that can be defined at runtime
|
||||
static constexpr uint MAX_PARAM_ID = _bit_fit(_PARAM_ID_BITS); ///< max number of distinct param identities that can be created
|
||||
|
||||
static_assert (BASETYPE_CNT <= MAX_BASETYPES);
|
||||
|
||||
|
||||
|
||||
struct IDRecord
|
||||
{
|
||||
uint baseTypeID :_BASE_TYPE_BITS = 0;
|
||||
uint scaleID :_SCALES_BITS = 0;
|
||||
uint paramIDID :_PARAM_ID_BITS = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}} // namespace lib::par
|
||||
#endif /*LIB_PAR_SPEC_H*/
|
||||
|
|
@ -516,7 +516,7 @@ namespace lib {
|
|||
static PolymorphicValue
|
||||
build (ARGS&&... args)
|
||||
{
|
||||
Adapter<IMP>* type_to_build_in_buffer(0);
|
||||
IMP* type_to_build_in_buffer{};
|
||||
return PolymorphicValue (type_to_build_in_buffer, std::forward<ARGS>(args)...);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ namespace util {
|
|||
* @todo 3/2024 seems we have solved this problem several times meanwhile /////////////////////////////////TICKET #1360 sort out floating-point rounding and precision
|
||||
*/
|
||||
inline constexpr bool
|
||||
almostEqual (double d1, double d2, unsigned int ulp =2) noexcept
|
||||
almostEqual (double d1, double d2, uint ulp =2) noexcept
|
||||
{
|
||||
using std::fabs;
|
||||
return fabs (d1-d2) < DBL_EPSILON * fabs (d1+d2) * ulp
|
||||
|
|
@ -224,6 +224,10 @@ namespace util {
|
|||
return logB;
|
||||
}
|
||||
|
||||
static_assert (-1 == ilog2(-5));
|
||||
static_assert ( 0 == ilog2( 1));
|
||||
static_assert ( 5 == ilog2(42));
|
||||
|
||||
|
||||
} // namespace util
|
||||
#endif /*UTIL_QUANT_H*/
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ TESTING "Library Test Suite: parameters" ./test-suite --group=param
|
|||
|
||||
|
||||
|
||||
PLANNED "Parameter Values" Parameter_test <<END
|
||||
TEST "Parameter Values" Parameter_test <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include "test/run.hpp"
|
||||
//#include "test/test-helper.hpp"
|
||||
#include "lib/par/domain.hpp"
|
||||
#include "lib/par/param-type.hpp"
|
||||
#include "test/diagnostic-output.hpp"////////////TODO
|
||||
|
||||
//#include <utility>
|
||||
|
|
@ -168,6 +169,9 @@ namespace test{
|
|||
|
||||
|
||||
|
||||
template<typename X>
|
||||
using FullDomain = BaseDomain<X, Domain>;
|
||||
|
||||
/** @test base function to access the contents of an opaque buffer
|
||||
* with known type, and convert into another target type.
|
||||
* - the base interface #Domain represents an opaque type
|
||||
|
|
@ -183,8 +187,10 @@ namespace test{
|
|||
void
|
||||
verify_valueAccess()
|
||||
{
|
||||
BaseDomain<int> domInt;
|
||||
SHOW_EXPR(sizeof(BaseDomain<int>)) ///////////////////////////////////////TODO this should be only one »slot«, but is actually quite large, due to using multiple inheritance in the Domain interface. /////OOO fix that!
|
||||
FullDomain<int> domInt;
|
||||
CHECK (sizeof(FullDomain<int>) <= sizeof(void*)); // only the VTable
|
||||
|
||||
// use the generic interface for access...
|
||||
Domain& dom{domInt};
|
||||
|
||||
int val = 1 + rani (1000);
|
||||
|
|
@ -193,21 +199,18 @@ SHOW_EXPR(sizeof(BaseDomain<int>)) ///////////////////////////////////////TODO t
|
|||
uint target1{0};
|
||||
CHECK (not target1);
|
||||
|
||||
TypeHandler<uint>& hu{dom};
|
||||
hu.extractAs (target1, src);
|
||||
dom.extractAs (target1, src);
|
||||
CHECK (target1 == uint(val));
|
||||
|
||||
float target2{0};
|
||||
|
||||
TypeHandler<float>& hf{dom};
|
||||
hf.extractAs (target2, src);
|
||||
dom.extractAs (target2, src);
|
||||
CHECK (target2 == float(val));
|
||||
|
||||
// value clamped to target domain...
|
||||
val = _MIN<int>;
|
||||
uint64_t target3{55};
|
||||
TypeHandler<uint64_t>& hu64{dom};
|
||||
hu64.extractAs (target3, src);
|
||||
dom.extractAs (target3, src);
|
||||
CHECK (target3 == _MIN<uint64_t>);
|
||||
}
|
||||
|
||||
|
|
@ -222,27 +225,24 @@ SHOW_EXPR(sizeof(BaseDomain<int>)) ///////////////////////////////////////TODO t
|
|||
void
|
||||
verify_valueSetting()
|
||||
{
|
||||
BaseDomain<int> domInt;
|
||||
FullDomain<int> domInt;
|
||||
Domain& dom{domInt};
|
||||
|
||||
int val_in_buff = 0;
|
||||
ValBuff& target = asValBuff (val_in_buff);
|
||||
|
||||
uint src1 = 1 + rani (1000);
|
||||
TypeHandler<uint>& hu{dom};
|
||||
hu.conform (target, src1);
|
||||
dom.conform (target, src1);
|
||||
CHECK (val_in_buff == int(src1));
|
||||
|
||||
double src2 = ranRange (1,100);
|
||||
CHECK (1 <= src2 and src2 < 100);
|
||||
TypeHandler<double>& hd{dom};
|
||||
hd.conform (target, src2);
|
||||
dom.conform (target, src2);
|
||||
CHECK (val_in_buff == int(floor (src2)));
|
||||
|
||||
// value clamped to target domain...
|
||||
auto mini = _MIN<int64_t>;
|
||||
TypeHandler<int64_t>& h64{dom};
|
||||
h64.conform (target, mini);
|
||||
dom.conform (target, mini);
|
||||
CHECK (val_in_buff == _MIN<int>);
|
||||
}
|
||||
|
||||
|
|
@ -263,9 +263,9 @@ SHOW_EXPR(sizeof(BaseDomain<int>)) ///////////////////////////////////////TODO t
|
|||
int64_t i64_val{0};
|
||||
bool boo{false};
|
||||
|
||||
BaseDomain<double> ddom;
|
||||
BaseDomain<int64_t> idom;
|
||||
BaseDomain<bool> bdom;
|
||||
FullDomain<double> ddom;
|
||||
FullDomain<int64_t> idom;
|
||||
FullDomain<bool> bdom;
|
||||
|
||||
Domain& d1{ddom};
|
||||
Domain& d3{bdom};
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
//#include "test/test-helper.hpp"
|
||||
#include "lib/par/parameter.hpp"
|
||||
//#include "lib/format-cout.hpp"
|
||||
#include "test/diagnostic-output.hpp"/////////////TODO
|
||||
|
||||
//#include <utility>
|
||||
//#include <string>
|
||||
|
|
@ -76,6 +77,9 @@ namespace test{
|
|||
void
|
||||
simpleUsage()
|
||||
{
|
||||
CHECK (sizeof(Parameter) <= 4 * sizeof(void*));
|
||||
CHECK (BASETYPE_MAX_SIZ <= sizeof(ValStorage));
|
||||
|
||||
Parameter par = Parameter::forType<int>().build();
|
||||
CHECK (0 == par.getVal<int>());
|
||||
|
||||
|
|
|
|||
|
|
@ -61468,6 +61468,20 @@
|
|||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1788380815777" ID="ID_339381268" MODIFIED="1788380998740" TEXT="Typlisten-Hilfsmittel">
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1788380823618" ID="ID_763137476" MODIFIED="1788380836976" TEXT="gehört längerfristig etwas konsolidiert...">
|
||||
<icon BUILTIN="hourglass"/>
|
||||
</node>
|
||||
<node CREATED="1788380842279" ID="ID_1993085663" MODIFIED="1788380927706" TEXT="Typlisten und Typ-Sequenzen sind nun voll ineinander überführbar">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Das Bindeglied steckt in typeseq-util.hpp ⟶ es wurde einfach möglich durch die Umstellung auf variadische Typ-Sequenzen (beim Übergang auf C++20)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1540682674455" ID="ID_1625152878" MODIFIED="1557498707236" TEXT="Typliste filtern">
|
||||
<node CREATED="1540682680286" ID="ID_1172485112" MODIFIED="1557498707236" TEXT="nach canConvert">
|
||||
<node CREATED="1540682731631" ID="ID_1059841081" MODIFIED="1557498707236" TEXT="die Typen, in die man umwandeln kann">
|
||||
|
|
@ -61491,6 +61505,39 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1788380932335" ID="ID_550975867" MODIFIED="1788381357392" TEXT="TypeIdxID">
|
||||
<linktarget COLOR="#80969f" DESTINATION="ID_550975867" ENDARROW="Default" ENDINCLINATION="-1482;411;" ID="Arrow_ID_1821706956" SOURCE="ID_659200917" STARTARROW="None" STARTINCLINATION="434;28;"/>
|
||||
<node CREATED="1788381017736" ID="ID_1220983692" MODIFIED="1788381171239" TEXT="die reine Suche gab es schon für Type-Sequenzen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
constexpr <font color="#000000" face="DejaVu Sans Mono"><b>indexOfType</b></font><<font color="#870505">T,TS...</font>>()
|
||||
</p>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p>
|
||||
bisher wenig verwendet, wenn aber, dann für einen Index-basierten Zugriff ⟹ es <b>muß</b> eine static-Assertion geben, daß der gesuchte Typ auch wirklich in der Liste ist (es wäre brandgefährlich, im sonst-Fall ein Sentinel zurückzugeben, z.B. -1)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1788381173379" ID="ID_611234338" MODIFIED="1788381193909" TEXT="konzipiere es damit explizit als Typ-ID">
|
||||
<node CREATED="1788381195458" ID="ID_1625105480" MODIFIED="1788381212466" TEXT="soll 0 sein für »alle anderen«"/>
|
||||
<node COLOR="#17155b" CREATED="1788381224205" ID="ID_1878301364" MODIFIED="1788381344411" TEXT="verdammt kniffelig ... letztlich aber geknackt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
der Trick war, den gefundenen Index in einem zusätzlichen non-type-Argument hochzuzählen, und bei Match von dort zu entnehmen. Warum? nur so kann man <i>einen ganz anderen Wert</i> liefern, wenn man über das Ende der Liste hinausläuft; die naive Implementierung mit Tail-Rekursion addiert ja den Index <i>auf dem Rückweg hoch</i> und erlaubt daher keinen alternativen Ausgang
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1775068804117" FOLDED="true" ID="ID_528287612" MODIFIED="1775585854666" TEXT="Laufzeit-idx Access">
|
||||
<linktarget COLOR="#2d4868" DESTINATION="ID_528287612" ENDARROW="Default" ENDINCLINATION="-1099;144;" ID="Arrow_ID_1760258574" SOURCE="ID_1844807854" STARTARROW="None" STARTINCLINATION="-935;121;"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
|
|
@ -64126,7 +64173,8 @@
|
|||
<linktarget COLOR="#313bd5" DESTINATION="ID_297232550" ENDARROW="Default" ENDINCLINATION="147;-4;" ID="Arrow_ID_604220325" SOURCE="ID_1658923821" STARTARROW="None" STARTINCLINATION="117;8;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1775751872730" ID="ID_106564309" MODIFIED="1775770628001" TEXT="damit den bestehenden PolymorphicValue modernisieren">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1775751872730" ID="ID_106564309" MODIFIED="1788302308822" TEXT="damit den bestehenden PolymorphicValue modernisieren">
|
||||
<linktarget COLOR="#fef1ad" DESTINATION="ID_106564309" ENDARROW="Default" ENDINCLINATION="377;18;" ID="Arrow_ID_1956727109" SOURCE="ID_1296566156" STARTARROW="None" STARTINCLINATION="297;11;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1775751886640" ID="ID_635074732" MODIFIED="1775770630422" TEXT="und auf dieser Basis die FunInline redefinieren">
|
||||
|
|
@ -64805,7 +64853,8 @@
|
|||
<node CREATED="1775752824541" ID="ID_1199118483" MODIFIED="1775752834819" TEXT="der Code ist ziemlich schwer zu verstehen"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1775752853151" ID="ID_87627416" MODIFIED="1775752859037" TEXT="Re-Implementierung">
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1775752853151" ID="ID_87627416" MODIFIED="1788301725468" TEXT="Re-Implementierung">
|
||||
<linktarget COLOR="#931557" DESTINATION="ID_87627416" ENDARROW="Default" ENDINCLINATION="-273;3165;" ID="Arrow_ID_867915966" SOURCE="ID_1451113864" STARTARROW="None" STARTINCLINATION="289;-1009;"/>
|
||||
<icon BUILTIN="hourglass"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1775752860084" ID="ID_1520505813" MODIFIED="1775769457487" TEXT="Idee: ein Instance-Manager-Interface schaffen">
|
||||
<linktarget COLOR="#feefb5" DESTINATION="ID_1520505813" ENDARROW="Default" ENDINCLINATION="22;-857;" ID="Arrow_ID_960733347" SOURCE="ID_297232550" STARTARROW="None" STARTINCLINATION="-127;7;"/>
|
||||
|
|
@ -64821,6 +64870,17 @@
|
|||
</html></richcontent>
|
||||
<node CREATED="1775752933506" ID="ID_868304108" MODIFIED="1775752972169" TEXT="wäre direkt implementierbar als Komponente, ohne Virtualisierung"/>
|
||||
<node CREATED="1775752903046" ID="ID_1216439634" MODIFIED="1775752913919" TEXT="man könnte den VirtualCopySupport direkt darauf aufsetzen"/>
|
||||
<node CREATED="1788302260005" ID="ID_1296566156" MODIFIED="1788302573075" TEXT="auch bei der Idee »FunInline« hatte ich PolymorphicValue in Erwägung gezogen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...war mir aber letztlich nicht schlüssig, in welche Richtung meine Abwägung geht; die C++-STDLIB verwendet ja <i>zwei Funktionspointer</i>, von denen einer auf einen generischen Instance-Manager zeigt. Meine eigenen »Freihand-Abwägungen« bezüglich generierter Assembly und Runtime-Overhead weisen aber immer wieder in die Richtung, daß eine VTable effizienter ist, als mehrere Funktionspointer, wobei im Fall von lediglich zwei Pointern vermutlich immer noch nahezu Äquivalenz besteht. Das Problem bei solchen Abwägungen im Kontext von LIbrary-Design ist, daß man die Frage eigentlich nicht empirisch entscheiden kann; Microbenchmarks sind immer nur Momentaufnahmen, und der globale Impact einer solchen Entscheidung ist extrem schwer zu fassen (und aufwendig zu untersuchen)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#fef1ad" DESTINATION="ID_106564309" ENDARROW="Default" ENDINCLINATION="377;18;" ID="Arrow_ID_1956727109" STARTARROW="None" STARTINCLINATION="297;11;"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1775769404408" ID="ID_862372565" LINK="https://issues.lumiera.org/ticket/1421" MODIFIED="1775769417192" TEXT="#1421 define Instance-Manager interface">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
|
|
@ -64828,6 +64888,13 @@
|
|||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1775769220570" ID="ID_572028635" LINK="https://issues.lumiera.org/ticket/1197" MODIFIED="1775769238759" TEXT="#1197 rationalise copy support in PolymorphicValue">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1788302637488" HGAP="32" ID="ID_335130787" LINK="#ID_1782676400" MODIFIED="1788302782855" TEXT="....und der generische Copy-Support sollte auf copy-and-swap aufbauen" VSHIFT="2">
|
||||
<font NAME="SansSerif" SIZE="11"/>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1788302603281" ID="ID_324413890" MODIFIED="1788302793158" TEXT="ebenso wichtig: Payload muß »in-place« konstruierbar sein">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -82935,7 +83002,7 @@
|
|||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1783092344401" ID="ID_723247866" MODIFIED="1783092356166" TEXT="ParamType">
|
||||
<node CREATED="1783092344401" ID="ID_723247866" MODIFIED="1788306366293" TEXT="Provision">
|
||||
<node CREATED="1783092477119" ID="ID_1734714581" MODIFIED="1783092481906" TEXT="Interfaface">
|
||||
<node CREATED="1783092482966" ID="ID_1196126403" MODIFIED="1783092486026" TEXT="virtuell"/>
|
||||
<node CREATED="1783092486716" ID="ID_1507254773" MODIFIED="1783092489572" TEXT="generisch">
|
||||
|
|
@ -82967,8 +83034,17 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1783101507062" ID="ID_1298955481" MODIFIED="1783101521840" TEXT="Header: lib/par/param-type.hpp|cpp">
|
||||
<node CREATED="1783101523306" ID="ID_1764325281" MODIFIED="1783172855177" TEXT="hier auch die Type-Registry"/>
|
||||
<node CREATED="1783101507062" ID="ID_1298955481" MODIFIED="1788306389082" TEXT="Header....">
|
||||
<node CREATED="1788306396605" ID="ID_1497186410" MODIFIED="1788306410252" TEXT="lib/par/provision.hpp">
|
||||
<node CREATED="1788306414146" HGAP="71" ID="ID_833702080" MODIFIED="1788306467320" TEXT="Buffer-Zugriffs-Mechanik" VSHIFT="2">
|
||||
<font NAME="SansSerif" SIZE="10"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1788306390020" ID="ID_1994320454" MODIFIED="1788306392775" TEXT="lib/par/param-type.hpp|cpp">
|
||||
<node CREATED="1783101523306" HGAP="29" ID="ID_1764325281" MODIFIED="1788306464746" TEXT="hier auch die Type-Registry" VSHIFT="2">
|
||||
<font NAME="SansSerif" SIZE="10"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1783097554556" ID="ID_1339731751" MODIFIED="1783097566222" TEXT="Domain">
|
||||
|
|
@ -82995,7 +83071,7 @@
|
|||
<node BACKGROUND_COLOR="#c8c0b6" CREATED="1784489444352" ID="ID_1412623970" MODIFIED="1784489521150" TEXT="doch! das funktioniert weiterhin">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1784489483382" ID="ID_617432070" MODIFIED="1787695360380">
|
||||
<node CREATED="1784489483382" ID="ID_617432070" MODIFIED="1788284693233">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
|
|
@ -83030,7 +83106,7 @@
|
|||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<linktarget COLOR="#ffe99c" DESTINATION="ID_617432070" ENDARROW="Default" ENDINCLINATION="236;9;" ID="Arrow_ID_1412212027" SOURCE="ID_711986937" STARTARROW="None" STARTINCLINATION="236;9;"/>
|
||||
<linktarget COLOR="#ffe99c" DESTINATION="ID_617432070" ENDARROW="Default" ENDINCLINATION="184;7;" ID="Arrow_ID_1412212027" SOURCE="ID_711986937" STARTARROW="None" STARTINCLINATION="162;6;"/>
|
||||
<linktarget COLOR="#fe8953" DESTINATION="ID_617432070" ENDARROW="Default" ENDINCLINATION="368;0;" ID="Arrow_ID_1535827259" SOURCE="ID_1219008003" STARTARROW="None" STARTINCLINATION="463;38;"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -83090,11 +83166,11 @@
|
|||
<node COLOR="#352c84" CREATED="1784491298401" ID="ID_427305032" MODIFIED="1784491298401" TEXT="Fazit {generiertes Multi-TypeHandler-OO-Interface}">
|
||||
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1784491360016" ID="ID_711986937" MODIFIED="1784491537887" TEXT="das Original-Baumuster von Alexandrescu ist immer noch die beste Lösung">
|
||||
<arrowlink COLOR="#ffe99c" DESTINATION="ID_617432070" ENDARROW="Default" ENDINCLINATION="236;9;" ID="Arrow_ID_1412212027" STARTARROW="None" STARTINCLINATION="236;9;"/>
|
||||
<node CREATED="1784491360016" ID="ID_711986937" MODIFIED="1788284693233" TEXT="das Original-Baumuster von Alexandrescu ist immer noch eine elegante Lösung">
|
||||
<arrowlink COLOR="#ffe99c" DESTINATION="ID_617432070" ENDARROW="Default" ENDINCLINATION="184;7;" ID="Arrow_ID_1412212027" STARTARROW="None" STARTINCLINATION="162;6;"/>
|
||||
</node>
|
||||
<node CREATED="1784491373675" ID="ID_1952132123" MODIFIED="1784491392120" TEXT="die Implementierung per Chain braucht keine Sichtbarkeit der anderen Overloads"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1784491392987" ID="ID_1626670078" MODIFIED="1784491428279" TEXT="auf Ambiguitäten in den Typ-Signaturen achten">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1784491392987" ID="ID_1626670078" MODIFIED="1788284654454" TEXT="auf Ambiguitäten in den Typ-Signaturen achten">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
|
|
@ -83103,6 +83179,7 @@
|
|||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<linktarget COLOR="#474ebe" DESTINATION="ID_1626670078" ENDARROW="Default" ENDINCLINATION="317;19;" ID="Arrow_ID_1833189754" SOURCE="ID_35862304" STARTARROW="None" STARTINCLINATION="396;16;"/>
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -83117,7 +83194,7 @@
|
|||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1788209315295" ID="ID_279904556" MODIFIED="1788210268056" TEXT="VTables blähen sich auf">
|
||||
<node COLOR="#435e98" CREATED="1788209315295" ID="ID_279904556" MODIFIED="1788284583155" TEXT="VTables blähen sich auf">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node CREATED="1788209326125" ID="ID_1531181426" MODIFIED="1788209343878" TEXT="Mix-in ⟹ schließt jedes Sub-Objekt komplett mit ein">
|
||||
<node CREATED="1788210282924" ID="ID_1520344652" MODIFIED="1788210493326" TEXT="zwar gibt C++ keinerlei Garantien zum Daten-Layout (außer für PODs)">
|
||||
|
|
@ -83164,10 +83241,23 @@
|
|||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1788211053578" ID="ID_1121107125" MODIFIED="1788214912904" TEXT="Also ⟹ muß doch umstellen auf eine lineare Kette — auch für die Interfaces">
|
||||
<linktarget COLOR="#f91755" DESTINATION="ID_1121107125" ENDARROW="Default" ENDINCLINATION="-1456;53;" ID="Arrow_ID_1757832686" SOURCE="ID_1738529643" STARTARROW="None" STARTINCLINATION="-304;11;"/>
|
||||
<node COLOR="#435e98" CREATED="1788211053578" ID="ID_1121107125" MODIFIED="1788284625243" TEXT="Also ⟹ muß doch umstellen auf eine lineare Kette — auch für die Interfaces">
|
||||
<linktarget COLOR="#a81651" DESTINATION="ID_1121107125" ENDARROW="Default" ENDINCLINATION="-1456;53;" ID="Arrow_ID_1757832686" SOURCE="ID_1738529643" STARTARROW="None" STARTINCLINATION="-297;13;"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node COLOR="#0c5669" CREATED="1788284754476" ID="ID_653345776" MODIFIED="1788284851663" TEXT="nun Assert im Test auf Größe des Basis-Interfaces">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...was nicht komplett durch den C++ - Standard gedeckt ist, jedoch aufgrund der Alignment-Contstraints und der Pflicht zur zero-overhead-Implementierung praktisch immer gegeben sein dürfte
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1788284591681" ID="ID_35862304" MODIFIED="1788284660301" TEXT="Fazit: etwas kniffligere Definition — aber weniger Ambituitäts-Probleme">
|
||||
<arrowlink COLOR="#474ebe" DESTINATION="ID_1626670078" ENDARROW="Default" ENDINCLINATION="317;19;" ID="Arrow_ID_1833189754" STARTARROW="None" STARTINCLINATION="396;16;"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -83950,7 +84040,7 @@
|
|||
<node CREATED="1788013034593" ID="ID_1225110265" MODIFIED="1788013038934" TEXT="eine Provision"/>
|
||||
<node CREATED="1788014082405" ID="ID_100431217" MODIFIED="1788014088031" TEXT="das ParamType-Interace"/>
|
||||
<node CREATED="1788014092867" ID="ID_1527036015" MODIFIED="1788017590529" TEXT="polyvalue::CopySupport - Marker">
|
||||
<node CREATED="1788017597647" ID="ID_1451113864" LINK="https://issues.lumiera.org/ticket/1197" MODIFIED="1788020032021" TEXT="stelle fest: PolymorphicValue ist schon recht verwirrend implementiert">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1788017597647" ID="ID_1451113864" LINK="https://issues.lumiera.org/ticket/1197" MODIFIED="1788301852253" TEXT="stelle fest: PolymorphicValue ist schon recht verwirrend implementiert">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
|
|
@ -83979,6 +84069,17 @@
|
|||
</ul>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#931557" DESTINATION="ID_87627416" ENDARROW="Default" ENDINCLINATION="-273;3165;" ID="Arrow_ID_867915966" STARTARROW="None" STARTINCLINATION="289;-1009;"/>
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#af020b" CREATED="1788301729827" ID="ID_18695637" MODIFIED="1788386325808" TEXT="erscheint zunehmend dringend...">
|
||||
<linktarget COLOR="#ff2137" DESTINATION="ID_18695637" ENDARROW="Default" ENDINCLINATION="1165;103;" ID="Arrow_ID_1244208579" SOURCE="ID_1978220833" STARTARROW="None" STARTINCLINATION="349;18;"/>
|
||||
<linktarget COLOR="#ff2137" DESTINATION="ID_18695637" ENDARROW="Default" ENDINCLINATION="1165;103;" ID="Arrow_ID_635472113" SOURCE="ID_1100385220" STARTARROW="None" STARTINCLINATION="373;14;"/>
|
||||
<font NAME="SansSerif" SIZE="11"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1788301751355" ID="ID_1968045723" MODIFIED="1788301772221" TEXT="in diesem (oder dem nächsten) VerticalSlice angehen">
|
||||
<font NAME="SansSerif" SIZE="11"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1788017707090" ID="ID_308578833" MODIFIED="1788018098862" TEXT="man muß nur ein Marker-Interface implementieren (um beim Kopieren zu kooperieren)">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
|
|
@ -84080,7 +84181,20 @@
|
|||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1788020869700" ID="ID_57699637" MODIFIED="1788020888892" TEXT="klar ist: wenn es einen »Buffer« gibt, dann residiert er hier, in der Provision"/>
|
||||
<node COLOR="#5b280f" CREATED="1788020869700" ID="ID_57699637" MODIFIED="1788380239674" TEXT="klar ist: wenn es einen »Buffer« gibt, dann residiert er hier, in der Provision">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1788380241393" ID="ID_258414787" MODIFIED="1788380272992" TEXT="Nein! definitiv nicht ⟶ das bricht die Abstraktion (»Datenquelle«)"/>
|
||||
<node CREATED="1788380280763" ID="ID_1135171473" MODIFIED="1788380317432" TEXT="der »Buffer« gehört in einen (opaquen) Implementierungs-Typ">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
ich will mich ja <i>grade nicht darauf festlegen</i>, daß es einen »Buffer« gibt
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1788021229355" ID="ID_1822130411" MODIFIED="1788021252164" TEXT="Provision& könnte eine Dekorator-Kette bilden">
|
||||
<node CREATED="1788022402071" ID="ID_37196039" MODIFIED="1788022413073" TEXT="damit könnte auch das »Setzen« delegiert werden"/>
|
||||
<node CREATED="1788022413763" ID="ID_241754503" MODIFIED="1788022585515" TEXT="aber unklar: wie wird der Typ ausgedrückt?"/>
|
||||
|
|
@ -84166,6 +84280,11 @@
|
|||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1788403986153" ID="ID_1976191283" MODIFIED="1788404065349" TEXT="»Typ« heißt nun ⟼ TypedEntity<VAL>">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1788404020598" ID="ID_1755481124" MODIFIED="1788404034549" TEXT="das bedeutet: es ist nun ein Implementierungs-Service"/>
|
||||
<node CREATED="1788404035161" ID="ID_470583685" MODIFIED="1788404044976" TEXT="und wird auf den Parameter-Basis-Typ getemplated"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1788125003779" ID="ID_1750350767" MODIFIED="1788125413347" TEXT="(dynamische) Provision">
|
||||
<node CREATED="1788125418166" ID="ID_1175365111" MODIFIED="1788125431416" TEXT="erfordert weiteren »Slot« für ein Delegate"/>
|
||||
|
|
@ -84335,7 +84454,7 @@
|
|||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#f91755" DESTINATION="ID_1121107125" ENDARROW="Default" ENDINCLINATION="-1456;53;" ID="Arrow_ID_1757832686" STARTARROW="None" STARTINCLINATION="-304;11;"/>
|
||||
<arrowlink COLOR="#a81651" DESTINATION="ID_1121107125" ENDARROW="Default" ENDINCLINATION="-1456;53;" ID="Arrow_ID_1757832686" STARTARROW="None" STARTINCLINATION="-297;13;"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1788207092440" ID="ID_1489003663" MODIFIED="1788214784231" TEXT="Typ und BaseDomain werden zum Problem">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
|
|
@ -84354,8 +84473,16 @@
|
|||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1788207233069" ID="ID_403725711" MODIFIED="1788207254569" TEXT="aber die konkrete Scale muß darauf aufbauen (da sie Werte beschränkt)"/>
|
||||
<node CREATED="1788215170120" ID="ID_1317810371" MODIFIED="1788215194280" TEXT="Typ muß konkret sein, schließt BaseDomain ein und verweist auf Scale"/>
|
||||
<node CREATED="1788207233069" ID="ID_403725711" MODIFIED="1788207254569" TEXT="aber die konkrete Scale muß darauf aufbauen (da sie Werte beschränkt)">
|
||||
<node CREATED="1788277709450" HGAP="60" ID="ID_1575437557" MODIFIED="1788277762386" TEXT="„aufbauen“ heißt nicht zwangsläufig auch „erweitern“" VSHIFT="1">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1788215170120" ID="ID_1317810371" MODIFIED="1788215194280" TEXT="Typ muß konkret sein, schließt BaseDomain ein und verweist auf Scale">
|
||||
<node CREATED="1788279901620" HGAP="78" ID="ID_1647252878" MODIFIED="1788279934225" TEXT="umbenennen in ⟼ TypedEntity" VSHIFT="1">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1788215427662" ID="ID_214321685" MODIFIED="1788217785702" TEXT="Das Povision-Interface muß anders angeordnet werden">
|
||||
<linktarget COLOR="#ff001d" DESTINATION="ID_214321685" ENDARROW="Default" ENDINCLINATION="4;-14;" ID="Arrow_ID_1991058182" SOURCE="ID_1569730697" STARTARROW="None" STARTINCLINATION="-120;4;"/>
|
||||
|
|
@ -84371,7 +84498,16 @@
|
|||
</html></richcontent>
|
||||
<node CREATED="1788215575560" ID="ID_690071422" MODIFIED="1788215606429" TEXT="das ist das front-End"/>
|
||||
<node CREATED="1788215613679" ID="ID_200801579" MODIFIED="1788215624951" TEXT="somit wird hier auch eine Interface-Kette eingemischt"/>
|
||||
<node CREATED="1788215708763" ID="ID_907924223" MODIFIED="1788215727096" TEXT="oder man würde Zugang zu einer Provision bieten"/>
|
||||
<node CREATED="1788215708763" ID="ID_907924223" MODIFIED="1788277831015" TEXT="oder man würde Zugang zu einer Provision bieten">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
bedeutet, es gibt eine Methode um eine Provision& zu bekommen, welche konsequenterweise dann über das Implementierungs-Interface erreichbar sein muß (da wir uns auf eine einfache Vererbungskette einschränken müssen)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1788215737795" ID="ID_516807030" MODIFIED="1788215749277" TEXT="Provision wird damit ein eigenständiges Interface">
|
||||
<node CREATED="1788215750841" ID="ID_374789197" MODIFIED="1788215911279" TEXT="sie ist nur implizit getypt">
|
||||
|
|
@ -84402,12 +84538,12 @@
|
|||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1788221594093" ID="ID_579519208" MODIFIED="1788221708229" TEXT="es muß aber per default als NOP implementiert sein">
|
||||
<node CREATED="1788221594093" ID="ID_579519208" MODIFIED="1788279294776" TEXT="es muß aber per default als NOP implementiert sein">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...sonst wird es schwierig mit dem Zusammenstellen der Interface-Kette; tatsächlich lassen sich alle für dieses Interface vorgesehenen Operationen »leer« Implementieren — es passiert dann einfach gar nichts, keine Zuweisung, keine Verbindung
|
||||
...sonst wird es schwierig mit dem Zusammenstellen der Interface-Kette; tatsächlich lassen sich alle für dieses Interface vorgesehenen Operationen »leer« Implementieren — es passiert dann einfach gar nichts, keine Zuweisung, keine Verbindung — was inhaltlich-logisch sogar korrekt ist, ein NICHTS-Parameter...
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
|
|
@ -84420,6 +84556,352 @@
|
|||
<node CREATED="1788222535392" ID="ID_1282201343" MODIFIED="1788222543419" TEXT="Disposition ist immer noch ein Interface"/>
|
||||
<node CREATED="1788222544142" ID="ID_1947215779" MODIFIED="1788222568288" TEXT="es wird per PolymorphicValue auf das Parameter-Objekt exponiert"/>
|
||||
<node CREATED="1788222571539" ID="ID_1256386409" MODIFIED="1788222603029" TEXT="die ganze konkrete Implementierung setzt darauf auf (und bleibt damit opaque, und variierbar)"/>
|
||||
<node BACKGROUND_COLOR="#c8bed8" COLOR="#3e3976" CREATED="1788293527789" ID="ID_1979935695" MODIFIED="1788296915688" TEXT="Konsequenz ⟹ muß dieses Interface generisch zusammenstellen">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1788293568866" ID="ID_131380857" MODIFIED="1788380416055" TEXT="es muß noch unterhalb der getypten Implementierung liegen"/>
|
||||
<node CREATED="1788380418977" ID="ID_626646433" MODIFIED="1788380435831" TEXT="es muß bereits einen ID-Record bieten">
|
||||
<node CREATED="1788380437998" ID="ID_1881580962" MODIFIED="1788380488048" TEXT="sonst ist kein »short-circuit« möglich">
|
||||
<arrowlink COLOR="#7a6a8b" DESTINATION="ID_1468282295" ENDARROW="Default" ENDINCLINATION="116;-139;" ID="Arrow_ID_582693889" STARTARROW="None" STARTINCLINATION="220;17;"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1788293586698" ID="ID_1746668987" MODIFIED="1788293628728" TEXT="Inhaltlich gehört es aber näher zum ParamData-Record"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1788279465992" ID="ID_511934631" MODIFIED="1788307762955" TEXT="Insgesamt entsteht hier eine Konkretisierungs-Kette">
|
||||
<linktarget COLOR="#4d65b9" DESTINATION="ID_511934631" ENDARROW="Default" ENDINCLINATION="-379;20;" ID="Arrow_ID_927557846" SOURCE="ID_1002785268" STARTARROW="None" STARTINCLINATION="119;14;"/>
|
||||
<icon BUILTIN="forward"/>
|
||||
<node CREATED="1788279482831" ID="ID_1252818882" MODIFIED="1788279536466" TEXT="wir gehen vom Kontrakt zum Service">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
es handelt sich dabei durchgehend um Abstraktionen, wobei sich jedoch der Charakter der Abstraktion ändert von einer Zusicherung zu etwas, auf dem wir konkret aufbauen können
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1788279539424" ID="ID_1639736337" MODIFIED="1788279543780" TEXT="Bedeutung der Stufen">
|
||||
<node CREATED="1788279549319" ID="ID_120197629" MODIFIED="1788279575207" TEXT="Provision: die Grundidee eines Parameters wie hier konzeptionalisiert"/>
|
||||
<node CREATED="1788279579772" ID="ID_1387667429" MODIFIED="1788279619787" TEXT="Domain: Zusicherung einer Typ-konformen Handhabung"/>
|
||||
<node CREATED="1788280039452" ID="ID_1355845527" MODIFIED="1788295973732" TEXT="Disposition: der vollständige Parameter-Implementierungs-Service"/>
|
||||
<node CREATED="1788279649921" ID="ID_829245549" MODIFIED="1788279664995" TEXT="BaseDomain: Festlegung der Eigenschaften der Datenbasis"/>
|
||||
<node CREATED="1788279667230" ID="ID_1645392786" MODIFIED="1788279840724" TEXT="TypedEntity: Konformität und Darstelluns-Fähigkeiten"/>
|
||||
<node CREATED="1788295927324" ID="ID_53887849" MODIFIED="1788295946230" TEXT="ParamData: der komplette Implementierungs-Record"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1788296967307" ID="ID_1067952271" MODIFIED="1788296982864" TEXT="damit ist für jeden Belang eine Ebene festgelegt">
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1788296987347" ID="ID_1409086602" MODIFIED="1788297005246" TEXT="kann nun die Implementierung konstruieren">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#435e98" CREATED="1788307857528" ID="ID_412964688" MODIFIED="1788313299843" TEXT="Value-Init ⟶ direkt vom Builder in den Konstruktor"/>
|
||||
<node CREATED="1788307874399" ID="ID_195138202" MODIFIED="1788307912949" TEXT="Get mit Typ-Konversion ⟶ generisches front-End auf dem Disposition-Interface">
|
||||
<node CREATED="1788307916543" ID="ID_877977052" MODIFIED="1788307932499" TEXT="so muß es sein — dafür haben wir ein Interface"/>
|
||||
<node CREATED="1788307933286" ID="ID_67518693" MODIFIED="1788307948939" TEXT="die Implementierung baut dann auf den Basis-Interfaces auf">
|
||||
<node CREATED="1788366990200" ID="ID_1939303972" MODIFIED="1788367012596" TEXT="schön wärs...">
|
||||
<icon BUILTIN="smiley-angry"/>
|
||||
</node>
|
||||
<node CREATED="1788366994118" ID="ID_143088929" MODIFIED="1788367004585" TEXT="dann läuft aber alles per Indirektion">
|
||||
<icon BUILTIN="smily_bad"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1788308332698" ID="ID_1468282295" MODIFIED="1788380480854" TEXT="Problem: brauche hier die BaseDomain-ID ohne Indirektion">
|
||||
<linktarget COLOR="#7a6a8b" DESTINATION="ID_1468282295" ENDARROW="Default" ENDINCLINATION="116;-139;" ID="Arrow_ID_582693889" SOURCE="ID_1881580962" STARTARROW="None" STARTINCLINATION="220;17;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1788362693945" ID="ID_1951653761" MODIFIED="1788362711453" TEXT="sonst »relativiert« sich der Direkt-Zugriff">
|
||||
<node CREATED="1788366366118" ID="ID_295761416" MODIFIED="1788366874928" TEXT="tatsächlich brauche ich höchstens eine Indirektion">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...denn hier habe ich ja (per Template-Parameter) schon einen Typ in der Hand, muß also nur noch den zugehörigen TypeHandler aufrufen (eine Indirektion)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1788366386901" ID="ID_303065066" MODIFIED="1788366439089" TEXT="der double-Dispatch wäre gar nicht notwendig hier">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...der deckt nur den (theoretischen) Fall ab, daß wir eine Zuweisung zwischen <i>zwei Parametern</i> machen (für die beide der Datentyp opaque ist).
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1788366876053" ID="ID_871895427" MODIFIED="1788366988849" TEXT="und eine Indirektion um dann per force-Cast zuzugreifen wäre Unsinn">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
zumal ich dann auch noch per force-downcast auf den Buffer zugreifen müßte
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="smiley-oh"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fed199" COLOR="#b90040" CREATED="1788309764989" ID="ID_137382885" MODIFIED="1788380092658" TEXT="Alarm: das Design geht hier nicht auf">
|
||||
<arrowlink COLOR="#fe2680" DESTINATION="ID_1551239755" ENDARROW="Default" ENDINCLINATION="191;-241;" ID="Arrow_ID_1230826257" STARTARROW="None" STARTINCLINATION="-740;0;"/>
|
||||
<linktarget COLOR="#b25193" DESTINATION="ID_137382885" ENDARROW="Default" ENDINCLINATION="-395;29;" ID="Arrow_ID_1892316604" SOURCE="ID_1271224230" STARTARROW="None" STARTINCLINATION="2071;0;"/>
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node CREATED="1788309801877" ID="ID_1982340657" MODIFIED="1788309820758" TEXT="auf der Interface-Ebene fehlen mir relevante Informationen"/>
|
||||
<node CREATED="1788309821442" ID="ID_1283728464" MODIFIED="1788309832720" TEXT="aber per Voraussetzung will ich keine Indirektion"/>
|
||||
<node CREATED="1788309836170" ID="ID_1386925847" MODIFIED="1788309890528" TEXT="und das Implementation-Layout sollte komplett frei konfigurierbar bleiben">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
auch im Hinblick darauf, daß ich später mal (möglichst mit dem gleichen generischen Code) auch komplexe Parameter-Typen handhaben möchte, wie Vektoren, Farb-Tripel und ganze Masken-Parametersätze...
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1788380554839" ID="ID_1101549379" MODIFIED="1788380577746" TEXT="Kompromiß: ziehe einen ID-Record bereits in die Disposition">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#c2b6c8" COLOR="#5b280f" CREATED="1788382780349" FOLDED="true" ID="ID_552546860" MODIFIED="1788397901695" TEXT="PolymorphicValue nicht optimal definiert">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1788301325125" ID="ID_1978220833" MODIFIED="1788386325808" TEXT="das mit dem CopySupport ist ein echtes Problem ">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Der Umstand, daß man da so ein Marker-Template inmischen muß, und dann die Fallunterscheidung, wann der PolymorphicValue-Container tatsächlich die schlanke lineare Vererbungskette nutzen kann, und wo der Copy-Adapter aufgesetzt wird....
|
||||
</p>
|
||||
<p>
|
||||
Ich hab das Zeug gebaut, und schon ein paar mal verwendet, aber <i>ich blick' da einfach nicht mehr durch</i> — jedes mal muß man sich wieder durch die ganzen Templates durchfressen (und das für etwas, was es eigentlich mit modernem C++ gar nicht mehr bräuchte)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#ff2137" DESTINATION="ID_18695637" ENDARROW="Default" ENDINCLINATION="1165;103;" ID="Arrow_ID_1244208579" STARTARROW="None" STARTINCLINATION="349;18;"/>
|
||||
<icon BUILTIN="smiley-angry"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1788383059641" ID="ID_1688642617" MODIFIED="1788386316028" TEXT="das Marker-Template muß wirklich in der Kette liegen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...ich hatte es zwar definiert und im Container-Typ angegeben — aber dann im konkreten API-Aufbau doch nicht eingeschleift (weil es da thematisch ja auch nicht hingehört, Grrrr)
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
<node CREATED="1788384797381" ID="ID_1232714334" MODIFIED="1788386029574" TEXT="stimmt garnicht ⟶ es wählt die optimale Variante">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1788384925999" ID="ID_906034232" MODIFIED="1788384956844" TEXT="aber es schlägt den "admin overhead" blindlings oben drauf"/>
|
||||
<node CREATED="1788384957654" ID="ID_799415187" MODIFIED="1788384990688" TEXT="aber wir verwenden einen sizeof ⟶ da ist die VTable bereits mit eingerechnet"/>
|
||||
<node CREATED="1788384992694" ID="ID_1687522773" MODIFIED="1788385063843" TEXT="also ist auch das Konzept »admin-overhead« in sich verworren (und überflüssig)">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
insofern dieses ganze clevere seitwärige Attachment überflüssig ist;  die einzige zwingende Voraussetzung ist, daß wir eine VTable haben
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" COLOR="#435e98" CREATED="1788386034754" ID="ID_1268627911" MODIFIED="1788386341107" TEXT="Lösung">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1788386039641" ID="ID_477009340" MODIFIED="1788386053499" TEXT="zweites Template-Argument in ParamData">
|
||||
<node CREATED="1788386057747" ID="ID_904631655" MODIFIED="1788386082344" TEXT="damit kann dann der Parameter (Container) hier das CopySupport-API injizieren"/>
|
||||
<node CREATED="1788386085851" ID="ID_1295285894" MODIFIED="1788386098957" TEXT="und wir halten die Komplexität nur an einer stelle"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1788386101665" ID="ID_93545182" MODIFIED="1788386217575" TEXT="muß die PAYLOAD_SIZE so definieren, daß die VTable-size abgezogen wird">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
weil PolymorphicValue da blindlings seinen ADMIN_OVERHEAD draufschlägt. Das ist ein sekundäres Problem im API-Design — wenn das Marker-API und der »workaround« mit dem Mix-in nicht mehr gebraucht werden, dann fällt auch diese ganze Verwirrung hier weg (die mich jetzt viele Stunden gekostet hat)
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1788386354314" ID="ID_1688624687" MODIFIED="1788386399854" TEXT="jetzt paßts: sizeof(Parameter) ≡ 4 «slot»">
|
||||
<font NAME="SansSerif" SIZE="11"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1788313220539" ID="ID_1678152846" MODIFIED="1788313251138" TEXT="Set mit Typ-Konversion ⟶ spiegelblidlich auf dem Disposition-Inteface"/>
|
||||
<node COLOR="#435e98" CREATED="1788313267301" ID="ID_697595338" MODIFIED="1788313294222" TEXT="Provision: Zugriff auf den Value-Buffer ⟶ cast und Assignment"/>
|
||||
<node CREATED="1788404121292" ID="ID_630136540" MODIFIED="1788404194186">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
<font color="#8c505c" face="DejaVu Sans Mono" size="9pt"><b>ValStorage</b></font>  : ein konkreter ValBuff mit ausreichender Storage-size
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="forward"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1788404196803" ID="ID_569414817" MODIFIED="1788404269415" TEXT="baue statische Type-Spec auf">
|
||||
<arrowlink COLOR="#578fd2" DESTINATION="ID_1609007571" ENDARROW="Default" ENDINCLINATION="53;-180;" ID="Arrow_ID_486335926" STARTARROW="None" STARTINCLINATION="-29;106;"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1788404287935" ID="ID_959512138" MODIFIED="1788404297298" TEXT="Basis-Typ-ID wird generisch erzeugt"/>
|
||||
<node CREATED="1788404298134" ID="ID_770813391" MODIFIED="1788404312059" TEXT="Storage-Buffer-Size wird automatisch begrenzt"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1788367103969" ID="ID_1551239755" MODIFIED="1788369873156" TEXT="innere Widersprüche werden deutlich">
|
||||
<linktarget COLOR="#fe2680" DESTINATION="ID_1551239755" ENDARROW="Default" ENDINCLINATION="191;-241;" ID="Arrow_ID_1230826257" SOURCE="ID_137382885" STARTARROW="None" STARTINCLINATION="-740;0;"/>
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node CREATED="1788367171639" ID="ID_632634612" MODIFIED="1788367181733" TEXT="ich will zugleich zwei Extreme">
|
||||
<node CREATED="1788367184127" ID="ID_1812755681" MODIFIED="1788367214110" TEXT="ich will einen einfachen Datenwert (⟹Effizienz)"/>
|
||||
<node CREATED="1788367215173" ID="ID_1024391215" MODIFIED="1788367223797" TEXT="aber getypt soll der auch sein...."/>
|
||||
<node CREATED="1788367226489" ID="ID_334299039" MODIFIED="1788367596873" TEXT="und außerdem möchte ich mich JETZT nicht festlegen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...zumal ich einen weiteren gewaltigen Zielkonflikt schon »riechen« kann: die Ansprüche komplexer Datentypen sind mit einem <i>leichtgewichtigen Standardfall</i> schwer vereinbar.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1788367600886" ID="ID_661068668" MODIFIED="1788369878699" TEXT="vermutlich steckt da eine tiefere Problemlage dahinter....">
|
||||
<linktarget COLOR="#b781a4" DESTINATION="ID_661068668" ENDARROW="Default" ENDINCLINATION="128;148;" ID="Arrow_ID_1562138790" SOURCE="ID_134775037" STARTARROW="None" STARTINCLINATION="-493;26;"/>
|
||||
<node CREATED="1788367626408" ID="ID_729798008" MODIFIED="1788367646292" TEXT="denn eigentlich ist mir das ganze »Paramter«-Thema im Moment zu viel"/>
|
||||
<node CREATED="1788367647365" ID="ID_1045440705" MODIFIED="1788367666198">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
ich <b>muß</b> es aber anfassen
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<node CREATED="1788367668144" ID="ID_361160202" MODIFIED="1788367953743" TEXT="weil sich hier eine ganze weitere Dimension im Konzept auftut">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Ich habe gesagt: alles was sich vorher regeln läßt, wird in einer Art Compiler <i>optimal konfiguriert</i>. Und alles Übrige sucht mich jetzt als »Parameter« (oder gar Konfiguration und Regelwerk) heim.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1788367686902" ID="ID_1051533158" MODIFIED="1788367849769" TEXT="weil es ganz gefährlich mit dem Thema Instanz-Managmenet verknüpft ist">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
....an den Parameter wird deutlich, daß möglicherweise meine »Lösung« mit den Segmenten (die ohnehin mehr eine Ausrede ist) so ohne Weiteres gar nicht tragfähig sein könnte — und wenn sich das realisieren sollte, dann stehe ich unter Handlungszwang (heißt, ich kann die Architektur nicht länger so offen halten, wie ich es gerne hätte, um den weiterreichenden Ideen die notwendige Luft zu verschaffen)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1788367954838" ID="ID_542541550" MODIFIED="1788368220121" TEXT="weil ich diesen Pflock einschlagen muß (sonst werden die Pragmatiker das verpfuschen)">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Das Thema »Automation« ist eines der wichtigsten Themen, die bestehende Applikationen immer wieder versäumen. Für mich ist die Lösung so offensichtlich klar, daß ich es immer in die Zukunft verschoben habe. Nun läuft mir aber die Zeit davon, dieses Projekt hat keine endlose Zukunft (wenn es sie je gehabt hätte....). Ich brauche also <i>für alle wirklich wichtigen Themen</i> eine <b>Architektur-Lösung</b>  — also eine geprägte Struktur, die man ohne Zerstörung nicht übergehen kann.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#ccb59b" COLOR="#6e2a38" CREATED="1788368252238" ID="ID_1087603902" MODIFIED="1788368268125" TEXT="rational betrachtet: die Offenheit des Design ist derzeit das Wichtigste">
|
||||
<font ITALIC="true" NAME="SansSerif" SIZE="14"/>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
<node CREATED="1788368277962" ID="ID_422312977" MODIFIED="1788368313545" TEXT="⟹ ich könnte höchstens einen Ansatzpunkt für die Effizienz aufzeigen">
|
||||
<node CREATED="1788368321899" ID="ID_1218702512" MODIFIED="1788368357857" TEXT="dazu müßte die Flag-Storage bereits in der Disposition direkt zugänglich sein">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1788368361587" ID="ID_1908291843" MODIFIED="1788369980901" TEXT="also ohne Indirektion — aber nutzbar für Subklassen"/>
|
||||
<node CREATED="1788368368524" ID="ID_1488167235" MODIFIED="1788368381846" TEXT="ich müßte mich zwingend auf ein Flag-Datenwort festlegen"/>
|
||||
<node CREATED="1788368414264" ID="ID_318537304" MODIFIED="1788369253534" TEXT="das ist jedoch die einzige denkbare Alternative zur VTable">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
Hier mache ich ein ganz grundsätzliches Argument...
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
Parameter sollen universell sein ⟹ also müssen sie laufzeit-dynamisch flexibel gemacht werden
|
||||
</li>
|
||||
<li>
|
||||
eine Konfiguration zur Laufzeit erfordert stets eine Storage (auch die VTable)
|
||||
</li>
|
||||
<li>
|
||||
wenn ich unter der Schwelle eines Funktionspointer-Dispatches bleiben möchte, kann ich nur in von Vornherein festgelegte Code-Alternativen verzweigen, per Flag (oder Compile-Time-Branch)
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
<i>Theoretisch</i> ließen sich beide Indirektionsmechanismen über eine Dispatch-Tabelle verbinden; das wäre aber eine <i>durchaus fragwürdige</i> Storage-Optimierung (die ganz sicher unter das Verdikt »premature« fällt, sofern nicht anders aufgezeigt)
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1788369259126" ID="ID_773542973" MODIFIED="1788369325763" TEXT="Einschätzung: ein zweiter »Slot« ist praktisch immer vertretbar...">
|
||||
<node CREATED="1788369328598" ID="ID_757945751" MODIFIED="1788369847883" TEXT="dann habe ich eben vier »Slots« — wtf">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
unter unsäglichen Schmerzen könnte ich daraus drei »Slots« machen ... und was bringt mir das? Wenn ich ultimative Effizienz brauche, sollte ich kein universelles Konstrukt wie einen Parameter verwenden. Siehe die Activity-Language im Scheduler, wo ich durch geeignete Speicher-Anordnung die durchaus massiv vorhandene Indirektion auf aktzeptable Cache-Kohärenz gebracht habe.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1788369351058" ID="ID_134775037" MODIFIED="1788369878698" TEXT="im Moment leide ich wirklich am »Phantomschmerz«">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
also echt jetzt! warum beiße ich mich an der Hinsicht dermaßen fest? alle anderen Hinsichten, die ich durchdacht (und bereits gelöst) habe, sind viel wichtiger (z.B. die Automation). Irgendwie versuche ich, hier einen Sieg vor mir selber zu erringen, wobei es doch im Moment gar nichts zu gewinnen gibt.
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#b781a4" DESTINATION="ID_661068668" ENDARROW="Default" ENDINCLINATION="128;148;" ID="Arrow_ID_1562138790" STARTARROW="None" STARTINCLINATION="-493;26;"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1788380520115" ID="ID_1609007571" MODIFIED="1788404265183" TEXT="führe also eine generische Spec mit einem ID-Record ein">
|
||||
<linktarget COLOR="#578fd2" DESTINATION="ID_1609007571" ENDARROW="Default" ENDINCLINATION="53;-180;" ID="Arrow_ID_486335926" SOURCE="ID_569414817" STARTARROW="None" STARTINCLINATION="-29;106;"/>
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1788380609599" ID="ID_768311001" MODIFIED="1788380631272" TEXT="und die zugehörige Storage kommt in die Disposition"/>
|
||||
<node CREATED="1788380657233" ID="ID_659200917" MODIFIED="1788381357392" TEXT="Neben-Thema: brauche nun eine Basis-Typ-ID">
|
||||
<arrowlink COLOR="#80969f" DESTINATION="ID_550975867" ENDARROW="Default" ENDINCLINATION="-1482;411;" ID="Arrow_ID_1821706956" STARTARROW="None" STARTINCLINATION="434;28;"/>
|
||||
<node CREATED="1788381363706" HGAP="31" ID="ID_1985934952" MODIFIED="1788381457346" TEXT="die kann unmittelbar statisch und eindeutig zugewiesen werden" VSHIFT="6">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
zunächst dachte ich noch, ich müßte eine statische Registrierungs-Tabelle aufbauen, ggfs. mit einem Class-Lock. Da ich mich nun aber darauf festgelegt habe, die Basis-Typen statisch festzulegen, in einer Typsequenz, wandert das alles in die Metaprogramming-Ecke
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1788403805224" ID="ID_35022947" MODIFIED="1788403822452" TEXT="generisches Schema um die Bits im ID-Record zu belegen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1788134884746" ID="ID_195532610" MODIFIED="1788134888546" TEXT="Builder-Notation">
|
||||
|
|
@ -84440,6 +84922,55 @@
|
|||
</node>
|
||||
<node CREATED="1788196981983" ID="ID_832309415" MODIFIED="1788197050345" TEXT="erst dort kann über den konkreten Typ-Aufbau entschieden werden">
|
||||
<linktarget COLOR="#4a3c9d" DESTINATION="ID_832309415" ENDARROW="Default" ENDINCLINATION="-1088;45;" ID="Arrow_ID_331072636" SOURCE="ID_97985230" STARTARROW="None" STARTINCLINATION="-455;17;"/>
|
||||
<node CREATED="1788299705092" ID="ID_1154522601" MODIFIED="1788299716551" TEXT="den Basis-Typ müssen wir sofort in einen Template-Parameter nehmen"/>
|
||||
<node CREATED="1788299717240" ID="ID_114328645" MODIFIED="1788299730333" TEXT="aber der Rest (vor allem die Scale) muß noch offen bleiben"/>
|
||||
</node>
|
||||
<node CREATED="1788300649206" ID="ID_932127060" MODIFIED="1788304361422" TEXT="sollte Resultat möglichst in-place konstruieren">
|
||||
<icon BUILTIN="yes"/>
|
||||
<node CREATED="1788301071029" ID="ID_1356800089" MODIFIED="1788301322838" TEXT="dem steht die bestehende Implementierung von PolymorphicValue im Wege">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
....diese erscheint heutzutage in mehrfacher Hinsicht als <i>unbeholfen</i>  — wobei allerdings die Wurzeln noch in die Zeit vor C++11 zurückreichen. Im Besonderen gibt es keinen direkt nutzbaren Konstruktor, und auch keine effizienten move-Assignments (copy-and-swap-Idiom). Demzufolge würde bereits eine direkte per-Value-Initialisierung der Basisklasse sofort einen Aufruf des virtuellen-Copy-APIs nach sich ziehen....
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node CREATED="1788301325125" ID="ID_1100385220" MODIFIED="1788301843036" TEXT="PolymorphicValue muß definitiv demnächst umfasend modernisiert werden">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...da ich dieses Konstrukt zunehmend für bedeutsam halte, und in viel größerem Umfang zu verwenden gedenke — es könnte sogar das bisherige ref-count-basiderte Memory-Management im high-level-Model ablösen....
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<arrowlink COLOR="#ff2137" DESTINATION="ID_18695637" ENDARROW="Default" ENDINCLINATION="1165;103;" ID="Arrow_ID_635472113" STARTARROW="None" STARTINCLINATION="373;14;"/>
|
||||
</node>
|
||||
<node CREATED="1788303471915" ID="ID_1786592729" MODIFIED="1788303488329" TEXT="muß dann wohl direkt den protected-Base-ctor verwenden">
|
||||
<node CREATED="1788303498632" ID="ID_1722801672" MODIFIED="1788303511627" TEXT="das ist definitiv möglich (und vorgesehen)...."/>
|
||||
<node CREATED="1788303512343" ID="ID_1972587310" MODIFIED="1788303683341" TEXT="verwendet trickreiches Argument-Matching">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
....der proctcted-ctor bekommt ein marker-Tag, das definiert ist als IMP* — dadurch wird der Typ IMP kommuniziert und in einen TypeSelector<IMP> verwandelt ... der dann allerdings erneut indirekt an den eigentlichen Arbeits-ctor weitergetgeben wird. Oh (Herr)mann!
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1788304299541" ID="ID_1086678671" MODIFIED="1788304357788" TEXT="Builder::build() verläßt sich dann auf die RVO">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
damit <i>sollte laut Standard</i> der initiale Parameter-Value tatsächlich in-place konstruiert werden, ohne Aufruf des virtuellen copy-support
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -84448,30 +84979,41 @@
|
|||
</node>
|
||||
<node CREATED="1788203329439" ID="ID_1991597342" MODIFIED="1788203340179" TEXT="Parameter-Basisfunktionen">
|
||||
<node CREATED="1788203369397" ID="ID_1275080112" MODIFIED="1788203381813" TEXT="treibe den Struktur-Aufbau">
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1788203394319" ID="ID_1002785268" MODIFIED="1788203455329" TEXT="Disposition festlegen">
|
||||
<node COLOR="#435e98" CREATED="1788203394319" ID="ID_1002785268" MODIFIED="1788307769571" TEXT="Disposition festlegen">
|
||||
<arrowlink COLOR="#4d65b9" DESTINATION="ID_511934631" ENDARROW="Default" ENDINCLINATION="-379;20;" ID="Arrow_ID_927557846" STARTARROW="None" STARTINCLINATION="119;14;"/>
|
||||
<icon BUILTIN="full-1"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1788203400185" ID="ID_900611719" MODIFIED="1788203458783" TEXT="Builder-Notation schaffen">
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1788203400185" ID="ID_900611719" MODIFIED="1788307794257" TEXT="Builder-Notation schaffen">
|
||||
<icon BUILTIN="full-2"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1788203422590" ID="ID_1249325546" MODIFIED="1788203462519" TEXT="Valure-Konversionen einbinden">
|
||||
<icon BUILTIN="full-3"/>
|
||||
<node COLOR="#338800" CREATED="1788313016806" ID="ID_1966722816" MODIFIED="1788403892705" TEXT="generisch per Indirektion">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1788313027713" ID="ID_1271224230" MODIFIED="1788313367997" TEXT="short-circuit bei direkt passendem Typ">
|
||||
<arrowlink COLOR="#b25193" DESTINATION="ID_137382885" ENDARROW="Default" ENDINCLINATION="-395;29;" ID="Arrow_ID_1892316604" STARTARROW="None" STARTINCLINATION="2071;0;"/>
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1788203353588" ID="ID_810940322" MODIFIED="1788203359142" TEXT="entwicklen per Parameter_test">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1788203485528" ID="ID_1524876130" MODIFIED="1788203551838" TEXT="simpleUsage">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1788203491453" ID="ID_1148834637" MODIFIED="1788203559585" TEXT="einfachen unlimitierten int-Parameter erzeugen">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<node COLOR="#338800" CREATED="1788203485528" ID="ID_1524876130" MODIFIED="1788313089197" TEXT="simpleUsage">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1788203491453" ID="ID_1148834637" MODIFIED="1788313002273" TEXT="einfachen unlimitierten int-Parameter erzeugen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1788203508251" ID="ID_1482426242" MODIFIED="1788203559586" TEXT="diesem einen (typisierten) Wert zuweisen">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<node COLOR="#338800" CREATED="1788203508251" ID="ID_1482426242" MODIFIED="1788313007743" TEXT="diesem einen (typisierten) Wert zuweisen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1788203517810" ID="ID_473781313" MODIFIED="1788203559587" TEXT="den Wert in verschiedene Typen extrahieren">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
<node COLOR="#338800" CREATED="1788203517810" ID="ID_473781313" MODIFIED="1788313011048" TEXT="den Wert in verschiedene Typen extrahieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#174956" COLOR="#8dfd49" CREATED="1788313090668" ID="ID_684424843" MODIFIED="1788313179645" STYLE="bubble" TEXT="erster einfachster Testfall GRÜN">
|
||||
<edge COLOR="#61fe5b" STYLE="bezier" WIDTH="thin"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -185803,12 +186345,12 @@ std::cout << tmpl.render({"what", "World"}) << s
|
|||
</node>
|
||||
</node>
|
||||
<node CREATED="1686439783608" ID="ID_25677654" MODIFIED="1686439786528" TEXT="Concepts">
|
||||
<node CREATED="1686438949795" ID="ID_197491932" LINK="https://stackoverflow.com/a/68238680" MODIFIED="1686439911618" TEXT="Concepts für Templates">
|
||||
<node CREATED="1686438949795" ID="ID_197491932" LINK="https://stackoverflow.com/a/68238680" MODIFIED="1686438949795" TEXT="Concepts für Templates">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
<p>
|
||||
...also für template templtate parameter;
|
||||
...also für template template parameter;
|
||||
</p>
|
||||
<p>
|
||||
für diese muß man allerdings stets die umständlichere <i>requires</i>-Syntax verwenden
|
||||
|
|
|
|||
Loading…
Reference in a new issue