Upgrade: switch to C++23 (see #1245)
The Lumiera »Reference Platform« is now upgraded to Debian/Buster, which provides GCC-14 and Clang-20. Thus the compiler support for C++20 language features seems solid enough, and C++23, while still in ''experimental stage'' can be seen as a complement and addendum. This changeset * upgrades the compile switches for the build system * provides all the necessary adjustments to keep the code base compilable Notable changes: * λ-capture by value now requires explicit qualification how to handle `this` * comparison operators are now handled transparently by the core language, largely obsoleting boost::operators. This change incurs several changes to implicit handling rules and causes lots of ambiguities — which typically pinpoint some long standing design issues, especially related to MObjects and the ''time entities''. Most tweaks done here can be ''considered preliminary'' * unfortunately the upgraded standard ''fails'' to handle **tuple-like** entities in a satisfactory way — rather an ''exposition-only'' concept is introduced, which applies solely to some containers from the STL, thereby breaking some very crucial code in the render entities, which was built upon the notion of ''tuple-like'' entities and the ''tuple protocol''. The solution is to abandon the STL in this respect and **provide an alternative implementation** of the `apply` function and related elements.
This commit is contained in:
parent
d888891d84
commit
afa7ca2e4d
44 changed files with 1165 additions and 104 deletions
|
|
@ -65,7 +65,7 @@ def defineBuildEnvironment():
|
|||
env.Replace( CPPPATH =["#src"] # used to find includes, "#" means always absolute to build-root
|
||||
, CPPDEFINES=['LUMIERA_VERSION='+VERSION ] # note: it's a list to append further defines
|
||||
, CCFLAGS='-Wall -Wextra -Wformat-security'
|
||||
, CXXFLAGS='-std=gnu++17 -Wno-enum-compare'
|
||||
, CXXFLAGS='-std=gnu++23 -Wno-enum-compare'
|
||||
, CFLAGS='-std=gnu99'
|
||||
)
|
||||
env.Append(LINKFLAGS='-Wl,--no-undefined') # require every dependency is given on link, in the right order
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ namespace stage {
|
|||
|
||||
facade.reset ( // trigger loading of the GuiStarterPlugin...
|
||||
new GuiRunner (
|
||||
[=] (string* problemMessage)
|
||||
[=,this] (string* problemMessage)
|
||||
{ // will be invoked when the UI thread exits
|
||||
closeGuiModule();
|
||||
termNotification(problemMessage);
|
||||
|
|
|
|||
|
|
@ -121,8 +121,8 @@ namespace lib {
|
|||
~AllocationCluster () noexcept;
|
||||
|
||||
/** hard wired size of storage extents */
|
||||
static size_t constexpr EXTENT_SIZ = 256;
|
||||
static size_t constexpr max_size();
|
||||
static constexpr size_t EXTENT_SIZ = 256;
|
||||
static constexpr size_t max_size();
|
||||
|
||||
|
||||
/* === diagnostics === */
|
||||
|
|
|
|||
|
|
@ -293,17 +293,17 @@ namespace lib {
|
|||
|
||||
template<class FUN>
|
||||
explicit
|
||||
Local (FUN&& buildInstance)
|
||||
Local (FUN&& _buildInstance)
|
||||
{
|
||||
__assert_compatible<MOC>();
|
||||
__assert_compatible<typename SubclassFactoryType<FUN>::Subclass>();
|
||||
|
||||
temporarilyInstallAlternateFactory (origInstance_, origFactory_
|
||||
,[=]()
|
||||
{
|
||||
mock_.reset (buildInstance());
|
||||
return mock_.get();
|
||||
});
|
||||
,[this, buildInstance=forward<FUN> (_buildInstance)]
|
||||
{
|
||||
mock_.reset (buildInstance());
|
||||
return mock_.get();
|
||||
});
|
||||
}
|
||||
~Local()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#define LIB_META_TUPLE_CLOSURE_H
|
||||
|
||||
#include "lib/meta/function-closure.hpp"
|
||||
#include "lib/meta/tuple-helper.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
#include <utility>
|
||||
|
|
@ -140,7 +141,7 @@ namespace meta{
|
|||
auto
|
||||
operator() (RemainingParams remPar) const
|
||||
{
|
||||
return std::apply (unConst(this)->partialClosure_, remPar);
|
||||
return apply (unConst(this)->partialClosure_, remPar);
|
||||
};
|
||||
|
||||
CLO partialClosure_;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <functional>
|
||||
|
||||
|
||||
namespace util { // forward declaration
|
||||
|
|
@ -78,6 +79,56 @@ namespace meta {
|
|||
using disable_if_Tuple = lib::meta::disable_if<lib::meta::is_Tuple<std::remove_reference_t<TUP>>>;
|
||||
|
||||
|
||||
|
||||
namespace { // apply to tuple-like : helpers...
|
||||
|
||||
/** @internal invocation helper similar to C++17 — but preferring a custom `get` impl */
|
||||
template<typename FUN, typename TUP, size_t...Idx>
|
||||
constexpr decltype(auto)
|
||||
__unpack_and_apply (FUN&& f, TUP&& tup, std::index_sequence<Idx...>)
|
||||
{ // ▽▽▽ ADL
|
||||
using std::get;
|
||||
return std::invoke (std::forward<FUN> (f)
|
||||
,get<Idx> (std::forward<TUP>(tup))...
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/** @internal invoke a metafunction with \a FUN and all element types from \a TUP */
|
||||
template<template<typename...> class META, class FUN, class TUP>
|
||||
struct _InvokeMetafunTup
|
||||
{
|
||||
using Tupl = std::decay_t<TUP>;
|
||||
using Elms = typename ElmTypes<Tupl>::Seq;
|
||||
using Args = typename Prepend<FUN, Elms>::Seq;
|
||||
using Type = typename RebindVariadic<META, Args>::Type;
|
||||
};
|
||||
|
||||
template<class FUN, class TUP>
|
||||
inline constexpr bool can_nothrow_invoke_tup = _InvokeMetafunTup<std::is_nothrow_invocable,FUN,TUP>::Type::value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replacement for `std::apply` — yet applicable to _tuple-like custom types_.
|
||||
* For unclear reasons, the standard chooses to reject such custom types, and
|
||||
* only allows a fixed set of explicitly defined facilities from the Stdlib
|
||||
* (tuple, pair, array, and some ranges stuff).
|
||||
* @todo 6/2025 as a first step, this replicates the implementation from C++17;
|
||||
* the second step would be to constrain this to a concept `tuple_like`
|
||||
*/
|
||||
template<class FUN, class TUP>
|
||||
constexpr decltype(auto)
|
||||
apply (FUN&& f, TUP&& tup) noexcept (can_nothrow_invoke_tup<FUN,TUP> )
|
||||
{
|
||||
using Indices = std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<TUP>>>;
|
||||
|
||||
return __unpack_and_apply (std::forward<FUN> (f)
|
||||
,std::forward<TUP> (tup)
|
||||
,Indices{}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tuple iteration: perform some arbitrary operation on each element of a tuple.
|
||||
* @note the given functor must be generic, since each position of the tuple
|
||||
|
|
@ -87,7 +138,7 @@ namespace meta {
|
|||
* then employ a fold expression with the comma operator.
|
||||
*/
|
||||
template<class TUP, class FUN, typename = enable_if_Tuple<TUP>>
|
||||
void
|
||||
constexpr void
|
||||
forEach (TUP&& tuple, FUN fun)
|
||||
{
|
||||
std::apply ([&fun](auto&&... elms)
|
||||
|
|
@ -112,7 +163,7 @@ namespace meta {
|
|||
* is used, which is guaranteed to evaluate from left to right.
|
||||
*/
|
||||
template<class TUP, class FUN, typename = enable_if_Tuple<TUP>>
|
||||
auto
|
||||
constexpr auto
|
||||
mapEach (TUP&& tuple, FUN fun)
|
||||
{
|
||||
return std::apply ([&fun](auto&&... elms)
|
||||
|
|
|
|||
|
|
@ -31,6 +31,13 @@
|
|||
** the corresponding operators on the pointee and by allowing to specify a base class smart-ptr
|
||||
** as template parameter.
|
||||
**
|
||||
** @deprecated 2025 : smells like an overly zealous design, while fundamental traits of the
|
||||
** involved entities remain nebulous. Who is the »entity«? The pointer or the pointee?
|
||||
** Why do we even want to delegate relational operators, while we do not even know that
|
||||
** the target supports them? And why to we need an virtual equality? If these objects have
|
||||
** reference semantics, then a base class should compare the identity. And there should not
|
||||
** be any ordering on such elements. So the whole motivation of rolling a specialised
|
||||
** shard-ptr seems moot. /////////////////////////////////////////////////////TICKET #501 : clarify Placement and MObject identity
|
||||
** @see asset.hpp
|
||||
** @see custom-shared-ptr-test.cpp
|
||||
** @see orderingofassetstest.cpp
|
||||
|
|
@ -94,11 +101,11 @@ namespace lib {
|
|||
|
||||
|
||||
private: /* === friend operators injected into enclosing namespace for ADL === */
|
||||
//////////////////TICKET #932 Clang is unable to fill in the default template argument. Resolved in newer versions of Clang. Temporary workaround: add second parameter B
|
||||
///////////////////TICKET #932 Clang is unable to fill in the default template argument. Resolved in newer versions of Clang. Temporary workaround: add second parameter B
|
||||
template<typename _O_,typename B>
|
||||
friend inline bool
|
||||
operator== (P const& p, P<_O_, B> const& q) { return (p and q)? (*p == *q) : (!p and !q); }
|
||||
|
||||
///////////////////////TICKET #501 : clarify Placement and MObject identity
|
||||
template<typename _O_,typename B>
|
||||
friend inline bool
|
||||
operator!= (P const& p, P<_O_, B> const& q) { return (p and q)? (*p != *q) : !(!p and !q); }
|
||||
|
|
|
|||
|
|
@ -234,8 +234,8 @@ namespace lib {
|
|||
return Tar{floor (val)};
|
||||
}
|
||||
} //----headroom to accommodate low probabilities
|
||||
static size_t constexpr QUANTISER = 1 << 4 + util::ilog2 (Tar::maxVal()-Tar::minVal());
|
||||
static double constexpr CAP_EPSILON = 1/(2.0 * QUANTISER);
|
||||
static constexpr size_t QUANTISER = 1 << 4 + util::ilog2 (Tar::maxVal()-Tar::minVal());
|
||||
static constexpr double CAP_EPSILON = 1/(2.0 * QUANTISER);
|
||||
|
||||
|
||||
/** @internal draw from source of randomness */
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ namespace lib {
|
|||
* elements of type \a TY in memory _with proper alignment_.
|
||||
*/
|
||||
template<typename TY>
|
||||
size_t inline constexpr
|
||||
inline constexpr size_t
|
||||
reqSiz()
|
||||
{
|
||||
size_t quant = alignof(TY);
|
||||
|
|
@ -159,7 +159,7 @@ namespace lib {
|
|||
}
|
||||
|
||||
/** determine size of a reserve buffer to place with proper alignment */
|
||||
size_t inline constexpr
|
||||
inline constexpr size_t
|
||||
alignRes (size_t alignment)
|
||||
{
|
||||
return positiveDiff (alignment, alignof(void*));
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ namespace lib {
|
|||
Symbol& operator= (Symbol &&) = default;
|
||||
|
||||
explicit operator bool() const { return not empty(); }
|
||||
bool empty() const { return *this == BOTTOM or *this == EMPTY; }
|
||||
bool empty() const { return *this == BOTTOM.c() or *this == EMPTY.c(); }
|
||||
|
||||
size_t
|
||||
length() const
|
||||
|
|
|
|||
|
|
@ -285,7 +285,7 @@ namespace time {
|
|||
Duration
|
||||
FrameRate::duration() const
|
||||
{
|
||||
if (0 == *this)
|
||||
if (HALTED > *this)
|
||||
throw error::Logic ("Impossible to quantise to an zero spaced frame grid"
|
||||
, error::LUMIERA_ERROR_BOTTOM_VALUE);
|
||||
|
||||
|
|
|
|||
|
|
@ -451,28 +451,28 @@ namespace time {
|
|||
int
|
||||
HmsTC::getSecs() const
|
||||
{ /////////////////////////////////////////////////////////////////////////////////////////////////TICKET #750 we do not want numeric accessors her — rather we want Digxel members
|
||||
return (raw_time_64(tpoint_) / TIME_SCALE_sec) % 60;
|
||||
return (_raw (tpoint_) / TIME_SCALE_sec) % 60;
|
||||
}
|
||||
|
||||
/** @deprecated 5/25 : no numeric computations in this class! use Digxel instead! */
|
||||
int
|
||||
HmsTC::getMins() const
|
||||
{
|
||||
return (raw_time_64(tpoint_) / TIME_SCALE_sec / 60) % 60;
|
||||
return (_raw (tpoint_) / TIME_SCALE_sec / 60) % 60;
|
||||
}
|
||||
|
||||
/** @deprecated 5/25 : no numeric computations in this class! use Digxel instead! */
|
||||
int
|
||||
HmsTC::getHours() const
|
||||
{
|
||||
return raw_time_64(tpoint_) / TIME_SCALE_sec / 60 / 60;
|
||||
return _raw (tpoint_) / TIME_SCALE_sec / 60 / 60;
|
||||
}
|
||||
|
||||
/** @deprecated 5/25 : no numeric computations in this class! use Digxel instead! */
|
||||
double
|
||||
HmsTC::getMillis() const
|
||||
{
|
||||
return (raw_time_64(tpoint_) / TIME_SCALE_ms) % 1000;
|
||||
return (_raw (tpoint_) / TIME_SCALE_ms) % 1000;
|
||||
}
|
||||
|
||||
/** */
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ namespace time {
|
|||
static TimeValue buildRaw_(raw_time_64);
|
||||
|
||||
/** @internal diagnostics */
|
||||
operator std::string () const;
|
||||
explicit operator std::string() const;
|
||||
|
||||
/** @return is in-domain, not a boundary value */
|
||||
bool isRegular() const;
|
||||
|
|
@ -265,8 +265,6 @@ namespace time {
|
|||
return *this;
|
||||
}
|
||||
|
||||
/// Support mixing with plain 64bit int arithmetics
|
||||
operator raw_time_64() const { return t_; }
|
||||
/// Support for micro-tick precise time arithmetics
|
||||
operator FSecs() const { return FSecs{t_, TimeValue::SCALE}; }
|
||||
|
||||
|
|
@ -342,7 +340,7 @@ namespace time {
|
|||
);
|
||||
|
||||
/** @internal diagnostics */
|
||||
operator std::string () const;
|
||||
explicit operator std::string() const;
|
||||
|
||||
/** convenience start for time calculations */
|
||||
TimeVar operator+ (TimeValue const& tval) const { return TimeVar(*this) + tval; }
|
||||
|
|
@ -405,7 +403,7 @@ namespace time {
|
|||
Offset stretchedByFloatFactor (double) const;
|
||||
|
||||
/** @internal diagnostics, indicating ∆ */
|
||||
operator std::string () const;
|
||||
explicit operator std::string() const;
|
||||
|
||||
// Supporting sign flip
|
||||
Offset operator- () const;
|
||||
|
|
@ -522,7 +520,7 @@ namespace time {
|
|||
|
||||
|
||||
/** @internal diagnostics */
|
||||
operator std::string () const;
|
||||
explicit operator std::string() const;
|
||||
|
||||
/// Supporting backwards use as offset
|
||||
Offset operator- () const;
|
||||
|
|
@ -651,7 +649,7 @@ namespace time {
|
|||
void accept (Mutation const&);
|
||||
|
||||
/** @internal diagnostics */
|
||||
operator std::string () const;
|
||||
explicit operator std::string() const;
|
||||
|
||||
/// Supporting extended total order, based on start and interval length
|
||||
friend bool operator== (TimeSpan const& t1, TimeSpan const& t2) { return t1.t_==t2.t_ && t1.dur_==t2.dur_; }
|
||||
|
|
@ -689,7 +687,10 @@ namespace time {
|
|||
/** duration of one frame */
|
||||
Duration duration() const;
|
||||
|
||||
operator std::string() const;
|
||||
/** derive total ordering from base class */
|
||||
std::strong_ordering operator<=>(FrameRate const&) const = default;
|
||||
|
||||
explicit operator std::string() const;
|
||||
};
|
||||
|
||||
/** convenient conversion to duration in fractional seconds */
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
namespace util {
|
||||
|
||||
template<typename N>
|
||||
inline bool constexpr
|
||||
inline constexpr bool
|
||||
isPow2 (N n)
|
||||
{
|
||||
return n > 0 and !(n & (n-1));
|
||||
|
|
|
|||
|
|
@ -40,9 +40,9 @@ namespace std {// forward declarations to avoid pervasive includes
|
|||
class set;
|
||||
|
||||
template<typename IT, typename V>
|
||||
IT find (IT, IT, V const&);
|
||||
constexpr IT find (IT, IT, V const&);
|
||||
template<typename IT, typename V>
|
||||
IT remove (IT, IT, V const&);
|
||||
constexpr IT remove (IT, IT, V const&);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -57,21 +57,21 @@ namespace util {
|
|||
|
||||
|
||||
template <class NUM>
|
||||
inline int constexpr
|
||||
inline constexpr int
|
||||
sgn (NUM n)
|
||||
{
|
||||
return (n==0)? 0 :((n<0)? -1:+1 );
|
||||
}
|
||||
|
||||
template <class N1, class N2>
|
||||
inline N1 constexpr
|
||||
inline constexpr N1
|
||||
min (N1 n1, N2 n2)
|
||||
{
|
||||
return n2 < n1? N1(n2) : n1;
|
||||
}
|
||||
|
||||
template <class N1, class N2>
|
||||
inline N1 constexpr
|
||||
inline constexpr N1
|
||||
max (N1 n1, N2 n2)
|
||||
{
|
||||
return n1 < n2? N1(n2) : n1;
|
||||
|
|
@ -79,7 +79,7 @@ namespace util {
|
|||
|
||||
/** cut a numeric value to be >=0 */
|
||||
template <typename NUM>
|
||||
inline NUM constexpr
|
||||
inline constexpr NUM
|
||||
noneg (NUM val)
|
||||
{
|
||||
return (0<val? val : 0);
|
||||
|
|
@ -87,7 +87,7 @@ namespace util {
|
|||
|
||||
/** force a numeric to be within bounds, inclusively */
|
||||
template <typename NUM, typename NB>
|
||||
inline NUM constexpr
|
||||
inline constexpr NUM
|
||||
limited (NB lowerBound, NUM val, NB upperBound)
|
||||
{
|
||||
return min ( max (val, lowerBound)
|
||||
|
|
@ -95,7 +95,7 @@ namespace util {
|
|||
}
|
||||
|
||||
template <typename NUM, typename NB>
|
||||
inline bool constexpr
|
||||
inline constexpr bool
|
||||
isLimited (NB lowerBound, NUM val, NB upperBound)
|
||||
{
|
||||
return lowerBound <= val
|
||||
|
|
@ -103,7 +103,7 @@ namespace util {
|
|||
}
|
||||
|
||||
template <typename UN, typename N2>
|
||||
inline UN constexpr
|
||||
inline constexpr UN
|
||||
positiveDiff (N2 newVal, UN refVal)
|
||||
{
|
||||
return UN(newVal) > refVal? UN(newVal) - refVal
|
||||
|
|
|
|||
|
|
@ -113,8 +113,8 @@ namespace ctrl {
|
|||
: queue_{}
|
||||
, dispatcher_{}
|
||||
{
|
||||
dispatcher_.connect(
|
||||
[=]() {try {
|
||||
dispatcher_.connect([=,this]
|
||||
{try {
|
||||
queue_.invoke();
|
||||
}
|
||||
catch (std::exception& problem)
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ namespace stage {
|
|||
void
|
||||
NotificationService::dispatchMsg (ID uiElement, lib::diff::GenNode&& uiMessage)
|
||||
{
|
||||
dispatch_->event ([=]()
|
||||
dispatch_->event ([=,this]
|
||||
{
|
||||
ctrl::BusTerm::mark (uiElement, uiMessage);
|
||||
});
|
||||
|
|
@ -136,7 +136,7 @@ namespace stage {
|
|||
void
|
||||
NotificationService::mutate (ID uiElement, MutationMessage&& diff)
|
||||
{
|
||||
dispatch_->event ([=]()
|
||||
dispatch_->event ([=,this]
|
||||
{ // apply and consume diff message stored within closure
|
||||
this->change (uiElement, move(unConst(diff)));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ namespace widget {
|
|||
ms_seconds_ebox.set_can_focus(true);
|
||||
|
||||
|
||||
auto connect_motion_event = [=](Gtk::EventBox& guiElm, Field fieldID)
|
||||
auto connect_motion_event = [=,this](Gtk::EventBox& guiElm, Field fieldID)
|
||||
{
|
||||
auto handlerSlot = bind (mem_fun(this, &TimeCode::field_motion_notify_event), fieldID);
|
||||
guiElm.signal_motion_notify_event().connect (handlerSlot);
|
||||
|
|
@ -249,7 +249,7 @@ namespace widget {
|
|||
connect_motion_event (ms_seconds_ebox, MS_Seconds);
|
||||
|
||||
|
||||
auto connect_button_press = [=](Gtk::EventBox& guiElm, Field fieldID)
|
||||
auto connect_button_press = [=,this](Gtk::EventBox& guiElm, Field fieldID)
|
||||
{
|
||||
auto handlerSlot = bind (mem_fun(this, &TimeCode::field_button_press_event), fieldID);
|
||||
guiElm.signal_button_press_event().connect (handlerSlot);
|
||||
|
|
@ -267,7 +267,7 @@ namespace widget {
|
|||
connect_button_press (ms_seconds_ebox, MS_Seconds);
|
||||
|
||||
|
||||
auto connect_button_release = [=](Gtk::EventBox& guiElm, Field fieldID)
|
||||
auto connect_button_release = [=,this](Gtk::EventBox& guiElm, Field fieldID)
|
||||
{
|
||||
auto handlerSlot = bind (mem_fun(this, &TimeCode::field_button_release_event), fieldID);
|
||||
guiElm.signal_button_release_event().connect (handlerSlot);
|
||||
|
|
@ -285,7 +285,7 @@ namespace widget {
|
|||
connect_button_release (ms_seconds_ebox, MS_Seconds);
|
||||
|
||||
|
||||
auto connect_scroll_event = [=](Gtk::EventBox& guiElm, Field fieldID)
|
||||
auto connect_scroll_event = [=,this](Gtk::EventBox& guiElm, Field fieldID)
|
||||
{
|
||||
auto handlerSlot = bind (mem_fun(this, &TimeCode::field_button_scroll_event), fieldID);
|
||||
guiElm.signal_scroll_event().connect (handlerSlot);
|
||||
|
|
@ -303,7 +303,7 @@ namespace widget {
|
|||
connect_scroll_event (ms_seconds_ebox, MS_Seconds);
|
||||
|
||||
|
||||
auto connect_key_press = [=](Gtk::EventBox& guiElm, Field fieldID)
|
||||
auto connect_key_press = [=,this](Gtk::EventBox& guiElm, Field fieldID)
|
||||
{
|
||||
auto handlerSlot = bind (mem_fun(this, &TimeCode::field_key_press_event), fieldID);
|
||||
guiElm.signal_key_press_event().connect (handlerSlot);
|
||||
|
|
@ -321,7 +321,7 @@ namespace widget {
|
|||
connect_key_press (ms_seconds_ebox, MS_Seconds);
|
||||
|
||||
|
||||
auto connect_key_release = [=](Gtk::EventBox& guiElm, Field fieldID)
|
||||
auto connect_key_release = [=,this](Gtk::EventBox& guiElm, Field fieldID)
|
||||
{
|
||||
auto handlerSlot = bind (mem_fun(this, &TimeCode::field_key_release_event), fieldID);
|
||||
guiElm.signal_key_release_event().connect (handlerSlot);
|
||||
|
|
@ -339,7 +339,7 @@ namespace widget {
|
|||
connect_key_release (ms_seconds_ebox, MS_Seconds);
|
||||
|
||||
|
||||
auto connect_focus_gain = [=](Gtk::EventBox& guiElm, Field fieldID)
|
||||
auto connect_focus_gain = [=,this](Gtk::EventBox& guiElm, Field fieldID)
|
||||
{
|
||||
auto handlerSlot = bind (mem_fun(this, &TimeCode::field_focus_gain_event), fieldID);
|
||||
guiElm.signal_focus_in_event().connect (handlerSlot);
|
||||
|
|
@ -357,7 +357,7 @@ namespace widget {
|
|||
connect_focus_gain (ms_seconds_ebox, MS_Seconds);
|
||||
|
||||
|
||||
auto connect_focus_loss = [=](Gtk::EventBox& guiElm, Field fieldID)
|
||||
auto connect_focus_loss = [=,this](Gtk::EventBox& guiElm, Field fieldID)
|
||||
{
|
||||
auto handlerSlot = bind (mem_fun(this, &TimeCode::field_focus_loss_event), fieldID);
|
||||
guiElm.signal_focus_out_event().connect (handlerSlot);
|
||||
|
|
@ -1108,7 +1108,7 @@ namespace widget {
|
|||
if (frames != 0 && frames * drag_accum < (_raw(current_time())))
|
||||
{
|
||||
// minus because up is negative in computer-land
|
||||
pos = TimeValue (floor (pos - drag_accum * frames));
|
||||
pos = TimeValue (floor (_raw(pos) - drag_accum * frames));
|
||||
set (pos, false);
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ namespace workspace {
|
|||
bool
|
||||
DockArea::hasPanel (const int description_index)
|
||||
{
|
||||
return util::has_any (panels_, [=](panel::Panel* panel)
|
||||
return util::has_any (panels_, [&](panel::Panel* panel)
|
||||
{
|
||||
return getPanelType(panel) == description_index;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ namespace workspace {
|
|||
bool
|
||||
PanelManager::hasPanel (const int description_index)
|
||||
{
|
||||
return util::has_any (panels_, [=](panel::Panel* panel)
|
||||
return util::has_any (panels_, [&](panel::Panel* panel)
|
||||
{
|
||||
return getPanelType(panel) == description_index;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ namespace control {
|
|||
|
||||
runningLoop_ =
|
||||
make_unique<DispatcherLoop>(
|
||||
[=](string* problemIndicator)
|
||||
[=,this](string* problemIndicator)
|
||||
{ // when the Session thread ends....
|
||||
SteamDispatcher::endRunningLoopState();
|
||||
termNotification (problemIndicator);
|
||||
|
|
|
|||
|
|
@ -307,6 +307,8 @@ namespace engine {
|
|||
{
|
||||
builder.emplaceParamDataBlock (&block(), turnoutSys);
|
||||
}
|
||||
///////////////OOO
|
||||
Feed()= default;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@
|
|||
#include "lib/p.hpp"
|
||||
#include "lib/time/timevalue.hpp"
|
||||
|
||||
#include <boost/operators.hpp>
|
||||
#include <string>
|
||||
|
||||
|
||||
|
|
@ -69,8 +68,7 @@ namespace mobject {
|
|||
*/
|
||||
class MObject
|
||||
: public Buildable,
|
||||
util::NonCopyable,
|
||||
boost::equality_comparable< MObject >
|
||||
util::NonCopyable
|
||||
{
|
||||
protected:
|
||||
typedef lib::time::Duration Duration;
|
||||
|
|
@ -97,12 +95,21 @@ namespace mobject {
|
|||
/** MObject self-test (usable for asserting) */
|
||||
virtual bool isValid() const =0;
|
||||
|
||||
virtual Duration& getLength() =0; ////////////////////TICKET #448
|
||||
|
||||
virtual bool operator== (const MObject& oo) const =0; ///< needed for handling by lumiera::P
|
||||
virtual Duration& getLength() =0; ///////////////////////////TICKET #448
|
||||
|
||||
/** needed for handling by lumiera::P
|
||||
* @deprecated 2025 this seems not well motivated. lumiera::P was created
|
||||
* to support comparisons, and now we do not know how to implement them,
|
||||
* and thus we make the operation virtual. Are MObjects conceived as
|
||||
* having value semantics? For reference semantics, comparing the
|
||||
* »identity« should be sufficient
|
||||
* @note 2025 changed to a predicate to cope with C++20 reversed operators.
|
||||
*/
|
||||
virtual bool isEquivalentTo (const MObject& oo) const =0; ////////////////////////////////////////TICKET #501 : clarify Placement and MObject identity
|
||||
|
||||
friend bool operator== (MObject const& o1, MObject const& o2) { return o1.isEquivalentTo(o2); }
|
||||
|
||||
protected:
|
||||
|
||||
virtual string initShortID() const =0;
|
||||
|
||||
};
|
||||
|
|
|
|||
|
|
@ -31,9 +31,10 @@ namespace session {
|
|||
/** default/fallback implementation of equality
|
||||
* using literal object identity (same address).
|
||||
* Required to enable handling by lumiera::P
|
||||
* @deprecated 2025, see comment in MObject ////////////////////////////////////////////////////////////TICKET #501 : clarify Placement and MObject identity
|
||||
*/
|
||||
bool
|
||||
AbstractMO::operator== (const MObject& oo) const
|
||||
AbstractMO::isEquivalentTo (const MObject& oo) const
|
||||
{
|
||||
return (this == &oo);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ namespace session {
|
|||
return length_;
|
||||
}
|
||||
|
||||
bool operator== (const MObject& oo) const;
|
||||
bool isEquivalentTo (const MObject& oo) const override;
|
||||
|
||||
protected:
|
||||
void
|
||||
|
|
|
|||
|
|
@ -94,9 +94,9 @@ namespace play {
|
|||
{
|
||||
shutdown_initiated_ = true;
|
||||
launchDetached ("Output shutdown supervisor"
|
||||
,[=]{
|
||||
bringDown (completedSignal);
|
||||
});
|
||||
,[=,this]{
|
||||
bringDown (completedSignal);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ namespace gear {
|
|||
class EngineEvent
|
||||
{
|
||||
protected:
|
||||
static size_t constexpr RAW_SIZ = 3;
|
||||
static constexpr size_t RAW_SIZ = 3;
|
||||
using Storage = std::array<int64_t, RAW_SIZ>;
|
||||
|
||||
template<class DAT>
|
||||
|
|
|
|||
|
|
@ -82,9 +82,7 @@ namespace gear {
|
|||
using lib::time::FSecs;
|
||||
using lib::time::Time;
|
||||
using std::atomic;
|
||||
using std::memory_order::memory_order_relaxed;
|
||||
using std::memory_order::memory_order_acquire;
|
||||
using std::memory_order::memory_order_release;
|
||||
using std::memory_order;
|
||||
using std::chrono_literals::operator ""us;
|
||||
using std::chrono::microseconds;
|
||||
|
||||
|
|
@ -129,8 +127,8 @@ namespace gear {
|
|||
{
|
||||
ThreadID expect_noThread; // expect no one else to be in...
|
||||
return groomingToken_.compare_exchange_strong (expect_noThread, thisThread()
|
||||
,memory_order_acquire // success also constitutes an acquire barrier
|
||||
,memory_order_relaxed // failure has no synchronisation ramifications
|
||||
,memory_order::acquire // success also constitutes an acquire barrier
|
||||
,memory_order::relaxed // failure has no synchronisation ramifications
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -145,7 +143,7 @@ namespace gear {
|
|||
{ // expect that this thread actually holds the Grooming-Token
|
||||
REQUIRE (groomingToken_.load(memory_order_relaxed) == thisThread());
|
||||
const ThreadID noThreadHoldsIt;
|
||||
groomingToken_.store (noThreadHoldsIt, memory_order_release);
|
||||
groomingToken_.store (noThreadHoldsIt, memory_order::release);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ namespace gear {
|
|||
work::performRandomisedSpin (size_t stepping, size_t randFact)
|
||||
{
|
||||
size_t degree = CONTEND_SOFT_FACTOR * (1+randFact) * stepping;
|
||||
for (volatile size_t i=0; i<degree; ++i) {/*SPIN*/}
|
||||
for (volatile size_t i=0; i<degree; ) { i=i+1; /*SPIN*/}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ namespace test{
|
|||
for (uint i=0; i<cnt; ++i)
|
||||
{
|
||||
uint increment = rand_.i(MAX_RAND_INCMT);
|
||||
queue.feed ([=]() { countConsumerCall(increment); });
|
||||
queue.feed ([=,this]{ countConsumerCall(increment); });
|
||||
producerSum += increment;
|
||||
usleep (delay);
|
||||
queue.invoke(); // NOTE: dequeue one functor added during our sleep
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ namespace test{
|
|||
quant (int testPoint)
|
||||
{
|
||||
TimeVar quantised = this->gridLocal(TimeValue(testPoint));
|
||||
return int(quantised);
|
||||
return _raw(quantised);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ namespace test{
|
|||
CHECK (!(var < ref) );
|
||||
CHECK ( (var > ref) );
|
||||
|
||||
raw_time_64 rat(var);
|
||||
raw_time_64 rat = _raw(var);
|
||||
CHECK (!(rat == ref) );
|
||||
CHECK ( (rat != ref) );
|
||||
CHECK ( (rat >= ref) );
|
||||
|
|
|
|||
|
|
@ -62,9 +62,9 @@ namespace test{
|
|||
{
|
||||
TimeValue parsed = FMT::parse (timeSpec_, *grid_);
|
||||
CHECK (parsed == expected, "parsing '%s' resulted in %s instead of %s"
|
||||
, cStr(timeSpec_)
|
||||
, cStr(Time(parsed))
|
||||
, cStr(Time(expected)));
|
||||
, timeSpec_.c_str()
|
||||
, string{Time(parsed)}.c_str()
|
||||
, string{Time(expected)}.c_str());
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ namespace test{
|
|||
CHECK (var < Time::MAX);
|
||||
CHECK (var > Time::MIN);
|
||||
|
||||
raw_time_64 raw (var);
|
||||
raw_time_64 raw = _raw(var);
|
||||
CHECK (raw == org);
|
||||
CHECK (raw > org - two);
|
||||
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ namespace test {
|
|||
|
||||
AssetManager& aMang = AssetManager::instance();
|
||||
CHECK (aMang.getAsset (mm1->getID()) == mm2); // record of mm1 was replaced by mm2
|
||||
CHECK (aMang.getAsset (mm2->getID()) == mm2);
|
||||
CHECK (aMang.getAsset (mm2->getID()) == mm2); ////////////////////////TICKET #501 : clarify Placement and MObject identity
|
||||
|
||||
CHECK (aMang.known (mm1->getID()));
|
||||
CHECK (aMang.known (mm2->getID()));
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ namespace test {
|
|||
return element_;
|
||||
}
|
||||
|
||||
operator string() const { return element_; }
|
||||
operator string() const { return util::toString(element_); }
|
||||
|
||||
|
||||
friend bool
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ namespace test {
|
|||
{
|
||||
Placement<Clip>& pC = getPlacement<Clip>();
|
||||
cout << "Clip on media : "<< pC->getMedia() <<"\n";
|
||||
CHECK (pC->operator==(c));
|
||||
CHECK (pC->isEquivalentTo(c));
|
||||
log_ = string (pC);
|
||||
}
|
||||
void treat (AbstractMO&)
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@
|
|||
|
||||
#include "lib/p.hpp"
|
||||
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
|
||||
|
||||
namespace lib {
|
||||
|
|
@ -37,15 +35,13 @@ namespace test{
|
|||
|
||||
|
||||
struct X
|
||||
: boost::totally_ordered<X>
|
||||
{
|
||||
long x_;
|
||||
|
||||
X(long x=0) : x_(x) {}
|
||||
explicit X(long x=0) : x_(x) {}
|
||||
operator long () { return x_; }
|
||||
|
||||
bool operator< (const X& ox) const { return x_ < ox.x_; }
|
||||
bool operator== (const X& ox) const { return x_ == ox.x_; }
|
||||
std::strong_ordering operator<=>(X const&) const = default;
|
||||
|
||||
virtual ~X() {} // using RTTI
|
||||
};
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <string>
|
||||
|
||||
|
||||
using lumiera::error::Fatal;
|
||||
using lib::transformIterator;
|
||||
using lib::iter_stl::snapshot;
|
||||
using lib::iter_stl::eachElm;
|
||||
|
|
@ -53,6 +54,12 @@ namespace test {
|
|||
operator string() const { return "hey Joe!"; }
|
||||
};
|
||||
|
||||
class Bomb
|
||||
{
|
||||
public:
|
||||
operator string() const { throw Fatal{"mistake"}; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
class AutoCounter
|
||||
|
|
@ -110,7 +117,7 @@ namespace test {
|
|||
CHECK (toString (chatterer) == "hey Joe!"_expect);
|
||||
|
||||
CHECK (toString (&chatterer) == "↗hey Joe!"_expect); // pointer indicated
|
||||
CHECK (toString (nullptr) == "↯"_expect); // runtime exception, caught
|
||||
CHECK (toString (Bomb{}) == "↯"_expect); // runtime exception, caught
|
||||
|
||||
CHECK (toString (true) == "true"_expect); // special handling for bool
|
||||
CHECK (toString (2+2 == 5) == "false"_expect);
|
||||
|
|
|
|||
|
|
@ -660,7 +660,7 @@ namespace test {
|
|||
*/
|
||||
SessionThread(function<void(DiffSource*)> notifyGUI)
|
||||
: ThreadJoinable{"BusTerm_test: asynchronous diff mutation"
|
||||
, [=]
|
||||
, [this,notifyGUI]
|
||||
{
|
||||
uint cnt = randGen_.i(MAX_RAND_BORGS);
|
||||
for (uint i=0; i<cnt; ++i)
|
||||
|
|
@ -719,8 +719,9 @@ namespace test {
|
|||
usleep (100);
|
||||
uiDispatcher.invoke();
|
||||
}
|
||||
session.join();
|
||||
auto ok = session.join();
|
||||
//------end-multithreaded-mutation---
|
||||
CHECK (ok);
|
||||
|
||||
// on rare occasions we (consumer thread)
|
||||
// prematurely empty the queue...
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ namespace test{
|
|||
commandHandler_ = newHandler;
|
||||
else
|
||||
commandHandler_ =
|
||||
[=](GenNode const& cmd)
|
||||
[this](GenNode const& cmd)
|
||||
{
|
||||
log_.warn(_Fmt("NOT handling command-message %s in test-mode") % cmd);
|
||||
};
|
||||
|
|
@ -226,7 +226,7 @@ namespace test{
|
|||
stateMarkHandler_ = newHandler;
|
||||
else
|
||||
stateMarkHandler_ =
|
||||
[=](ID subject, GenNode const& mark)
|
||||
[this](ID subject, GenNode const& mark)
|
||||
{
|
||||
log_.warn(_Fmt("NOT handling state-mark %s passed from %s in test-mode")
|
||||
% mark % subject);
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ namespace test {
|
|||
bool showRes = true; ///< print result data
|
||||
bool showRef = true; ///< calculate single threaded reference time
|
||||
|
||||
static uint constexpr REPETITIONS{20};
|
||||
static constexpr uint REPETITIONS{20};
|
||||
|
||||
BlockFlowAlloc bFlow{};
|
||||
EngineObserver watch{};
|
||||
|
|
|
|||
|
|
@ -1394,7 +1394,7 @@ namespace test {
|
|||
for ( ; 0 < round; --round)
|
||||
lib::hash::combine (scree,scree);
|
||||
sink = scree;
|
||||
sink++;
|
||||
sink = sink + 1;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1408,7 +1408,7 @@ namespace test {
|
|||
for (size_t i=0; i<memBlock.size()-1; ++i)
|
||||
memBlock[i+1] += memBlock[i];
|
||||
sink = *memBlock.back();
|
||||
sink++;
|
||||
sink = sink + 1;
|
||||
}
|
||||
|
||||
double
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue