• My non-genric barrier

    From Bonita Montero@3:633/10 to All on Thu Jan 15 18:12:20 2026

    // Header

    #pragma once
    #include <mutex>
    #include <condition_variable>
    #include <functional>

    struct xbarrier
    {
    struct arrival_token
    {
    arrival_token() noexcept = default;
    arrival_token( const arrival_token &tk ) noexcept;
    arrival_token &operator =( const arrival_token &tk ) noexcept;
    operator unsigned() const noexcept;
    private:
    friend struct xbarrier;
    arrival_token( unsigned id ) noexcept;
    int id = -1;
    };
    template<typename Complete>
    xbarrier( unsigned initial, Complete &&complete );
    xbarrier( const xbarrier & ) = delete;
    xbarrier &operator =( const xbarrier & ) = delete;
    template<bool Wait = true, bool Drop = false>
    arrival_token arrive( arrival_token tk, unsigned count = 1 );
    private:
    std::mutex m_mtx;
    std::condition_variable m_cv;
    unsigned m_initial, m_ctr, m_gen;
    std::function<void ()> m_complete;
    };

    template<typename Complete>
    xbarrier::xbarrier( unsigned initial, Complete &&complete ) :
    m_initial( initial ),
    m_ctr( initial ),
    m_gen( 0 ),
    m_complete( std::forward<Complete>( complete ) )
    {
    }

    inline xbarrier::arrival_token::arrival_token( const arrival_token &tk ) noexcept :
    id( tk.id )
    {
    }

    inline xbarrier::arrival_token &xbarrier::arrival_token::operator =(
    const arrival_token &tk ) noexcept
    {
    id = tk.id;
    return *this;
    }

    inline xbarrier::arrival_token::operator unsigned() const noexcept
    {
    return id;
    }

    inline xbarrier::arrival_token::arrival_token( unsigned id ) noexcept :
    id( id )
    {
    }

    // Cpp

    #pragma once
    #include "xbarrier.h"

    using namespace std;

    template<bool Wait, bool Drop>
    auto xbarrier::arrive( arrival_token tk, unsigned count ) -> arrival_token
    {
    if( !count )
    return tk;
    unique_lock lock( m_mtx );
    if constexpr( Drop )
    if( m_initial )
    --m_initial;
    else
    return tk;
    m_ctr = m_ctr >= count ? m_ctr - count : 0;
    unsigned id = m_ctr, gen = m_gen;
    if( !m_ctr )
    {
    m_ctr = 0;
    ++m_gen;
    }
    m_ctr = m_ctr ? m_ctr : m_initial;
    if( m_ctr == m_initial )
    m_cv.notify_all();
    else
    if constexpr( Wait )
    m_cv.wait( lock, [&] { return gen != m_gen; } );
    if( tk.id < 0 )
    tk.id = id;
    if( !tk.id )
    m_complete();
    return tk;
    }

    template auto xbarrier::arrive<false, false>( arrival_token, unsigned )
    arrival_token;
    template auto xbarrier::arrive<true, false>( arrival_token, unsigned )
    arrival_token;
    template auto xbarrier::arrive<false, true>( arrival_token, unsigned )
    arrival_token;
    template auto xbarrier::arrive<true, true>( arrival_token, unsigned ) -> arrival_token;

    That's pure beauty !

    --- PyGate Linux v1.5.2
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)