Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #120136 > unrolled thread

My deque-replaement

Started byBonita Montero <Bonita.Montero@gmail.com>
First post2024-09-20 15:18 +0200
Last post2024-09-23 09:04 +0800
Articles 20 on this page of 45 — 8 participants

Back to article view | Back to comp.lang.c++


Contents

  My deque-replaement Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-20 15:18 +0200
    Re: My deque-replaement Muttley@dastardlyhq.com - 2024-09-20 14:10 +0000
      Re: My deque-replaement Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-20 16:18 +0200
        Re: My deque-replaement Muttley@dastardlyhq.com - 2024-09-20 15:08 +0000
          Re: My deque-replaement Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-20 17:12 +0200
            Re: My deque-replaement Muttley@dastardlyhq.com - 2024-09-20 15:57 +0000
              Re: My deque-replaement Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-20 18:03 +0200
                Re: My deque-replaement Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-20 18:09 +0200
                Re: My deque-replaement Muttley@dastardlyhq.com - 2024-09-21 09:40 +0000
                  Re: My deque-replaement Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-21 12:54 +0200
                  Re: My deque-replaement Chris Ahlstrom <OFeem1987@teleworm.us> - 2024-09-21 08:18 -0400
                    Re: My deque-replaement Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-21 14:25 +0200
                      Re: My deque-replaement Muttley@dastardlyhq.com - 2024-09-21 15:59 +0000
                        Re: My deque-replaement Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-21 18:12 +0200
                          Re: My deque-replaement Muttley@dastardlyhq.com - 2024-09-22 07:58 +0000
                            Re: My deque-replaement Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-22 10:48 +0200
                              Re: My deque-replaement Muttley@dastardlyhq.com - 2024-09-22 09:01 +0000
                                Re: My deque-replaement Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-22 11:49 +0200
                                  Re: My deque-replaement Muttley@dastardlyhq.com - 2024-09-22 15:13 +0000
                                    Re: My deque-replaement Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-22 17:28 +0200
                            Re: My deque-replaement Chris Ahlstrom <OFeem1987@teleworm.us> - 2024-09-22 06:49 -0400
                              Re: My deque-replaement Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-22 13:00 +0200
                                Re: My deque-replaement Muttley@dastardlyhq.com - 2024-09-22 15:19 +0000
                                  Re: My deque-replaement Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-22 17:30 +0200
                              Re: My deque-replaement Muttley@dastardlyhq.com - 2024-09-22 15:16 +0000
                                Re: My deque-replaement Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-22 17:31 +0200
                                  Re: My deque-replaement Muttley@dastardlyhq.com - 2024-09-23 07:35 +0000
                                    Re: My deque-replaement Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-23 09:36 +0200
                                      Re: My deque-replaement Muttley@dastardlyhq.com - 2024-09-23 09:31 +0000
                                        Re: My deque-replaement Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-23 11:47 +0200
                                        Re: My deque-replaement Michael S <already5chosen@yahoo.com> - 2024-09-23 13:42 +0300
                                          Re: My deque-replaement David Brown <david.brown@hesbynett.no> - 2024-09-23 14:09 +0200
                                            Re: My deque-replaement Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-23 19:00 +0200
                    Re: My deque-replaement jseigh <jseigh_es00@xemaps.com> - 2024-09-21 13:03 -0400
                      Re: My deque-replaement Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-21 19:13 +0200
                        Re: My deque-replaement jseigh <jseigh_es00@xemaps.com> - 2024-09-21 15:29 -0400
                          Re: My deque-replaement Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-22 08:23 +0200
                            Re: My deque-replaement jseigh <jseigh_es00@xemaps.com> - 2024-09-22 08:10 -0400
                              Re: My deque-replaement Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-22 15:03 +0200
                                Re: My deque-replaement "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-22 11:37 -0700
                      Re: My deque-replaement "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2024-09-21 13:59 -0700
                        Re: My deque-replaement jseigh <jseigh_es00@xemaps.com> - 2024-09-21 18:31 -0400
    Re: My deque-replaement wij <wyniijj5@gmail.com> - 2024-09-22 07:58 +0800
      Re: My deque-replaement Bonita Montero <Bonita.Montero@gmail.com> - 2024-09-22 09:51 +0200
        Re: My deque-replaement wij <wyniijj5@gmail.com> - 2024-09-23 09:04 +0800

Page 1 of 3  [1] 2 3  Next page →


#120136 — My deque-replaement

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-09-20 15:18 +0200
SubjectMy deque-replaement
Message-ID<vcjsmr$14bod$1@raubtier-asyl.eternal-september.org>
Just a ring-buffer with functional access:

#pragma once
#include <utility>
#include <cassert>
#include <memory>
#include <span>
#include "invoke_on_destruct.h"
#include "nui.h"

#if defined(__llvm__)
	#pragma clang diagnostic push
	#pragma clang diagnostic ignored "-Wparentheses"
	#pragma clang diagnostic ignored "-Wunqualified-std-cast-call"
#endif

template<typename T, typename Alloc = std::allocator<T>>
struct ring_deque
{
	ring_deque( ptrdiff_t capacity = 0, Alloc const &alloc = Alloc() );
	~ring_deque();
	ring_deque( ring_deque<T, Alloc> const &other );
	ring_deque( ring_deque<T, Alloc> &&other ) noexcept;
	ring_deque<T, Alloc> &operator =( ring_deque<T, Alloc> const &other );
	ring_deque<T, Alloc> &operator =( ring_deque<T, Alloc> &&other ) noexcept;
	template<bool Forward, typename Consumer>
	void scan( Consumer consumer )
		requires requires( T &value ) { { consumer( value ) }; };
	template<bool Forward, typename Consumer>
	void scan( Consumer consumer ) const
		requires requires( T const &value ) { { consumer( value ) }; };
	T &front() noexcept;
	T const &front() const noexcept;
	T &back() noexcept;
	T const &back() const noexcept;
	template<bool Forward, typename Consumer>
	size_t consume( Consumer consumer )
		requires requires( T &value ) { { consumer( value ) } -> 
std::same_as<int>; };
	template<bool Back, typename ... Args>
	T &emplace( Args &&... args )
		requires std::is_constructible_v<T, Args ...>;
	void pop_back() noexcept;
	void pop_front() noexcept;
	void pop_n( ptrdiff_t n ) noexcept;
	void shrink_to_fit();
	bool empty() const noexcept;
	size_t size() const noexcept;
	size_t capacity() const noexcept;
	void clear();
	T &operator []( ptrdiff_t i ) noexcept;
	T const &operator []( ptrdiff_t i ) const noexcept;
	void reserve( ptrdiff_t capacity );
private:
	using span_t = std::span<T>;
	span_t allocRing( size_t capacity );
	void freeRing( span_t sp );
	template<bool Forward, typename Consumer>
	void scanInternal( Consumer consumer );
	template<bool Forward, typename Consumer>
	void scanInternal( span_t::iterator &it, Consumer consumer );
	void grow();
	void reCap( ptrdiff_t capacity );
	static size_t normCap( ptrdiff_t capacity );
	using alloc_t = Alloc;
	NO_UNIQUE_ADDRESS alloc_t m_alloc;
	span_t m_ring;
	span_t::iterator m_front, m_back;
	size_t m_n;
};

template<typename T, typename Alloc>
ring_deque<T, Alloc>::ring_deque( ptrdiff_t capacity, Alloc const &alloc ) :
	m_alloc( alloc ),
	m_ring( allocRing( normCap( capacity ) ) ),
	m_front( m_ring.begin() ),
	m_back( m_ring.begin() ),
	m_n( 0 )
{
}

template<typename T, typename Alloc>
ring_deque<T, Alloc>::~ring_deque()
{
	consume<true>( [&]( T & ) -> int { return 1; } );
	freeRing( m_ring );
}

template<typename T, typename Alloc>
ring_deque<T, Alloc>::ring_deque( ring_deque<T, Alloc> const &other ) :
	ring_deque( other.m_n, other.m_alloc )
{
	invoke_on_destruct reset( [&] { this->~ring_deque(); } );
	other.scanInternal<true>( [&]( T const &value ) { emplace_back( value 
); return true; } );
	reset.disable();
}

template<typename T, typename Alloc>
ring_deque<T, Alloc>::ring_deque( ring_deque<T, Alloc> &&other ) noexcept :
	m_alloc( other.m_alloc ),
	m_ring( other.m_ring ),
	m_front( other.m_front ),
	m_back( other.m_back ),
	m_n( other.m_n )
{
	other.m_ring = span_t();
	other.m_n = 0;
#if !defined(NDEBUG)
	other.m_front = span_t().begin();
	other.m_back = span_t().begin();
#endif
}

template<typename T, typename Alloc>
ring_deque<T, Alloc> &ring_deque<T, Alloc>::operator =( ring_deque<T, 
Alloc> const &other )
{
	clear();
	reserve( other.size() );
	other.scanInternal<true>( [&]( T const &value ) { emplace_back( value 
); return true; } );
	return *this;
}

template<typename T, typename Alloc>
ring_deque<T, Alloc> &ring_deque<T, Alloc>::operator =( ring_deque<T, 
Alloc> &&other ) noexcept
{
	freeRing( m_ring );
	m_alloc = other.m_alloc;
	m_ring = other.m_ring;
	m_front = other.m_front;
	m_back = other.m_back;
	m_n = other.m_n;
	other.m_ring = span_t();
	other.m_n = 0;
#if !defined(NDEBUG)
	other.m_front = span_t().begin();
	other.m_back = span_t().begin();
#endif
	return *this;
}

template<typename T, typename Alloc>
template<bool Forward, typename Consumer>
inline void ring_deque<T, Alloc>::scan( Consumer consumer )
	requires requires( T &value ) { { consumer( value ) }; }
{
	using namespace std;
	scanInternal<Forward>( [&]( T &value )
		{
			bool ret = true;
			if constexpr( requires() { { consumer( value ) } -> 
convertible_to<bool>; } )
				ret = consumer( value );
			else
				consumer( value );
			return ret;
		} );
}

template<typename T, typename Alloc>
template<bool Forward, typename Consumer>
inline void ring_deque<T, Alloc>::scan( Consumer consumer ) const
	requires requires( T const &value ) { { consumer( value ) }; }
{
	const_cast<ring_deque<T, Alloc> *>(this)->scan<Forward>( [&]( T &value 
) { return consumer( value ); } );
}

template<typename T, typename Alloc>
inline T &ring_deque<T, Alloc>::front() noexcept
{
	assert(m_n);
	return *m_front;
}

template<typename T, typename Alloc>
inline T const &ring_deque<T, Alloc>::front() const noexcept
{
	assert(m_n);
	return *m_front;
}

template<typename T, typename Alloc>
inline T &ring_deque<T, Alloc>::back() noexcept
{
	assert(m_n);
	return m_back[-1];
}

template<typename T, typename Alloc>
inline T const &ring_deque<T, Alloc>::back() const noexcept
{
	assert(m_n);
	return m_back[-1];
}

template<typename T, typename Alloc>
template<bool Forward, typename Consumer>
inline size_t ring_deque<T, Alloc>::consume( Consumer consumer )
	requires requires( T &value ) { { consumer( value ) } -> 
std::same_as<int>; }
{
	size_t nInitial = m_n;
	typename span_t::iterator it = Forward ? m_front : m_back;
	invoke_on_destruct adjust( [&] { (Forward ? m_front : m_back) = it; } );
	scanInternal<Forward>( it, [&]( T &value ) -> bool
		{
			int cont = consumer( value );
			if( cont >= 0 ) [[likely]]
			{
				value.~T();
				--m_n;
			}
			return cont > 0;
		} );
	return nInitial - m_n;
}

template<typename T, typename Alloc>
template<bool Back, typename ... Args>
T &ring_deque<T, Alloc>::emplace( Args &&... args )
	requires std::is_constructible_v<T, Args ...>
{
	using namespace std;
	assert(m_ring.size() >= m_n);
	if( m_n == m_ring.size() ) [[unlikely]]
		grow();
	auto next = Back ? m_back : m_front;
	if( next == (Back ? m_ring.end() : m_ring.begin()) ) [[unlikely]]
		next = Back ? m_ring.begin() : m_ring.end();
	next -= !Back;
	new( (void *)&*next ) T( forward<Args>( args ) ... );
	next += Back;
	(Back ? m_back : m_front) = next;
	++m_n;
	return *(Back ? m_back - 1 : m_front);
}

template<typename T, typename Alloc>
inline void ring_deque<T, Alloc>::pop_back() noexcept
{
	assert(m_n);
	(*--m_back).~T();
	if( m_back == m_ring.begin() ) [[unlikely]]
		m_back = m_ring.end();
	--m_n;
}

template<typename T, typename Alloc>
inline void ring_deque<T, Alloc>::pop_front() noexcept
{
	assert(m_n);
	(*m_front++).~T();
	if( m_front == m_ring.end() ) [[unlikely]]
		m_front = m_ring.begin();
	--m_n;
}

template<typename T, typename Alloc>
void ring_deque<T, Alloc>::pop_n( ptrdiff_t n ) noexcept
{
	if( n > 0 )
	{
		assert(m_n >= (size_t)n);
		size_t dest = m_n - n;
		consume<true>( [&]( T &value ) -> int { return --m_n != dest; } );
	}
	else if( n < 0 )
	{
		assert(m_n >= (size_t)-n);
		size_t dest = m_n - -n;
		consume<false>( [&]( T &value ) -> int { return --m_n != dest; } );
	}
}

template<typename T, typename Alloc>
inline void ring_deque<T, Alloc>::shrink_to_fit()
{
	reCap( m_n );
}

template<typename T, typename Alloc>
inline bool ring_deque<T, Alloc>::empty() const noexcept
{
	return !size();
}

template<typename T, typename Alloc>
inline size_t ring_deque<T, Alloc>::size() const noexcept
{
	return m_n;
}

template<typename T, typename Alloc>
inline size_t ring_deque<T, Alloc>::capacity() const noexcept
{
	return m_ring.size();
}

template<typename T, typename Alloc>
inline void ring_deque<T, Alloc>::clear()
{
	pop_n( m_n );
}

template<typename T, typename Alloc>
T &ring_deque<T, Alloc>::operator []( ptrdiff_t i ) noexcept
{
	using namespace std;
	if( i >= 0 )
	{
		assert((size_t)i < m_n);
		ptrdiff_t headRun = m_ring.end() - m_front;
		if( i < headRun )
			return m_front[i];
		else
			return m_ring.begin()[i - headRun];
	}
	else
	{
		assert((size_t)-i <= m_n);
		ptrdiff_t tailRun = m_ring.begin() - m_back;
		if( i >= tailRun )
			return m_back[i];
		else
			return m_ring.end()[i - tailRun];
	}
}

template<typename T, typename Alloc>
inline T const &ring_deque<T, Alloc>::operator []( ptrdiff_t i ) const 
noexcept
{
	return (*const_cast<ring_deque<T, Alloc> *>(this))[i];
}

template<typename T, typename Alloc>
inline void ring_deque<T, Alloc>::reserve( ptrdiff_t capacity )
{
	reCap( capacity );
}

template<typename T, typename Alloc>
template<bool Forward, typename Consumer>
inline void ring_deque<T, Alloc>::scanInternal( Consumer consumer )
{
	typename span_t::iterator it;
	scanInternal<Forward>( it, consumer );
}

template<typename T, typename Alloc>
template<bool Forward, typename Consumer>
inline void ring_deque<T, Alloc>::scanInternal( span_t::iterator &it, 
Consumer consumer )
{
	using namespace std;
	it = Forward ? m_front : m_back;
	for( size_t n = m_n; n; --n )
	{
		if( !consumer( it[-(ptrdiff_t)!Forward] ) ) [[unlikely]]
			break;
		it = it + (Forward - !Forward);
		if( it == (Forward ? m_ring.end() : m_ring.begin()) ) [[unlikely]]
			it = Forward ? m_ring.begin() : m_ring.end();
	}
}

template<typename T, typename Alloc>
inline void ring_deque<T, Alloc>::grow()
{
	size_t nBefore = m_ring.size();
	reCap( 2 * nBefore + (size_t)!nBefore );
}

template<typename T, typename Alloc>
void ring_deque<T, Alloc>::reCap( ptrdiff_t capacity )
{
	using namespace std;
	size_t n = normCap( capacity );;
	if( n <= m_n )
		return;
	span_t ring( allocRing( n ) );
	size_t nElements = m_n;
	invoke_on_destruct finalize( [&]
		{
			m_n = nElements;
			freeRing( ring );
		} );
	auto it = ring.begin();
	invoke_on_destruct moveBack( [&]
		{
			while( it != ring.begin() )
			{
				if constexpr( is_move_constructible_v<T> )
					emplace<false>( move( *--it ) );
				(*it).~T();
			}
		} );
	if constexpr( is_move_constructible_v<T> )
		consume<true>( [&]( T &value )
			{
				new( (void *)&*it ) T( move( value ) );
				++it;
				return 1;
			} );
	else
		scan<true>( [&]( T &value )
			{
				new( (void *)&*it ) T( move( value ) );
				++it;
				return true;
			} );
	moveBack.disable();
	swap( m_ring, ring );
	m_front = m_ring.begin();
	m_back = it;
}

template<typename T, typename Alloc>
inline size_t ring_deque<T, Alloc>::normCap( ptrdiff_t capacity )
{
	if( capacity < 0 ) [[unlikely]]
		capacity = (size_t)-capacity / sizeof(T);
	return capacity;
}

template<typename T, typename Alloc>
typename ring_deque<T, Alloc>::span_t ring_deque<T, Alloc>::allocRing( 
size_t capacity )
{
	using namespace std;
	if( !capacity )
		return span_t();
#if !defined(__cpp_lib_allocate_at_least) && defined(_MSC_VER)
	allocation_result<T *, size_t> ar( m_alloc.allocate_at_least( capacity ) );
	return span_t( ar.ptr, ar.count );
#else
	return span_t( m_alloc.allocate( capacity ), capacity );
#endif
}

template<typename T, typename Alloc>
inline void ring_deque<T, Alloc>::freeRing( span_t sp )
{
	if( to_address( sp.begin() ) )
		m_alloc.deallocate( sp.data(), sp.size() );
}

#if defined(__llvm__)
	#pragma clang diagnostic pop
#endif

[toc] | [next] | [standalone]


#120137

FromMuttley@dastardlyhq.com
Date2024-09-20 14:10 +0000
Message-ID<vcjvo6$14rak$1@dont-email.me>
In reply to#120136
On Fri, 20 Sep 2024 15:18:22 +0200
Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>Just a ring-buffer with functional access:

A ring buffer can be written about 10 lines of code give or take. You seem to
revel in making simple things complicated. One day post us your version of
Hello World so we can have a laugh.

[toc] | [prev] | [next] | [standalone]


#120139

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-09-20 16:18 +0200
Message-ID<vck06s$14sue$1@raubtier-asyl.eternal-september.org>
In reply to#120137
Am 20.09.2024 um 16:10 schrieb Muttley@dastardlyhq.com:

> A ring buffer can be written about 10 lines of code ...

A deque is also much more complex than you think it is necessary.

[toc] | [prev] | [next] | [standalone]


#120140

FromMuttley@dastardlyhq.com
Date2024-09-20 15:08 +0000
Message-ID<vck34v$15c1u$1@dont-email.me>
In reply to#120139
On Fri, 20 Sep 2024 16:18:07 +0200
Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>Am 20.09.2024 um 16:10 schrieb Muttley@dastardlyhq.com:
>
>> A ring buffer can be written about 10 lines of code ...
>
>A deque is also much more complex than you think it is necessary.

A deque is not needed for a ring buffer. Using one demonstrates you don't
actually know what a ring buffer is. Hint: its an array with 2 pointers/indexes.
Done.

[toc] | [prev] | [next] | [standalone]


#120141

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-09-20 17:12 +0200
Message-ID<vck3ch$15cdi$1@raubtier-asyl.eternal-september.org>
In reply to#120140
Am 20.09.2024 um 17:08 schrieb Muttley@dastardlyhq.com:

> A deque is not needed for a ring buffer. 

Both usually serve the same purpose. A deque has iterators and therefore
the source of the MSVC-implementation is about 1.800 LOCs. If I'd write
such an implementation and I would post it here you'd say that all this
isn't necessary.

> Using one demonstrates you don't actually know what a ring buffer is.

You are overburdened with my code and you didn't read it.
I implemented a very convenient to use ring-buffer.

[toc] | [prev] | [next] | [standalone]


#120142

FromMuttley@dastardlyhq.com
Date2024-09-20 15:57 +0000
Message-ID<vck61a$15pgl$1@dont-email.me>
In reply to#120141
On Fri, 20 Sep 2024 17:12:20 +0200
Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>Am 20.09.2024 um 17:08 schrieb Muttley@dastardlyhq.com:
>
>> A deque is not needed for a ring buffer. 
>
>Both usually serve the same purpose. A deque has iterators and therefore

No, they don't. A deque can have an unbounded (except by memory) number of
items whereas a ring buffer is by design a fixed size.

>> Using one demonstrates you don't actually know what a ring buffer is.
>
>You are overburdened with my code and you didn't read it.
>I implemented a very convenient to use ring-buffer.

A ring buffer doesn't require 420 lines of code. People like yourself are
responsible for the absurd amount of bloat in modern code and ridiculously
powerful CPUs being required just to run office style applications and web
pages.

[toc] | [prev] | [next] | [standalone]


#120143

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-09-20 18:03 +0200
Message-ID<vck6bv$15plf$1@raubtier-asyl.eternal-september.org>
In reply to#120142
Am 20.09.2024 um 17:57 schrieb Muttley@dastardlyhq.com:

> No, they don't. A deque can have an unbounded (except by memory)
> number of items whereas a ring buffer is by design a fixed size.

A ring-buffer can be growing, my implementation also does grow.
The Boost ringbuffer also can grow.

> A ring buffer doesn't require 420 lines of code.

The code is rather small since I use a lot of functional programming
callbacks which re-uses existing code - with maximum performance.
For the one who uses my code it's extremely convenient.

	ring_deque<string> rds;
	...
	rds.consume<true>( [&]( string &str )
		{
			cout << str << endl;
		} );

> People like yourself are responsible for the absurd amount of bloat
> in modern code and ridiculously powerful CPUs being required just
> to run office style applications and web pages.

The "bloat" results in very few code of who uses this "bloat".
You're simply overburdened. Have a look at the standard library
code, it's much more complex for things which might look trivial
to you.

[toc] | [prev] | [next] | [standalone]


#120144

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-09-20 18:09 +0200
Message-ID<vck6nj$15seu$1@raubtier-asyl.eternal-september.org>
In reply to#120143
Am 20.09.2024 um 18:03 schrieb Bonita Montero:

> A ring-buffer can be growing, my implementation also does grow.
> The Boost ringbuffer also can grow.

The current Boost circular_buffer is 272kB, scattered in multiple
files. That's not bloat !

[toc] | [prev] | [next] | [standalone]


#120145

FromMuttley@dastardlyhq.com
Date2024-09-21 09:40 +0000
Message-ID<vcm4an$1i7jt$1@dont-email.me>
In reply to#120143
On Fri, 20 Sep 2024 18:03:14 +0200
Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>Am 20.09.2024 um 17:57 schrieb Muttley@dastardlyhq.com:
>
>> No, they don't. A deque can have an unbounded (except by memory)
>> number of items whereas a ring buffer is by design a fixed size.
>
>A ring-buffer can be growing, my implementation also does grow.

A ringbuffer that can grow is not a ring buffer, its a deque as you figured 
out.

>The Boost ringbuffer also can grow.

Boost has a lot to answer for in many areas.

>> People like yourself are responsible for the absurd amount of bloat
>> in modern code and ridiculously powerful CPUs being required just
>> to run office style applications and web pages.
>
>The "bloat" results in very few code of who uses this "bloat".
>You're simply overburdened. Have a look at the standard library

Am I? I think it might be you who can't think clearly enough to write a 
clean simple algorithm for a simple data structure.

>code, it's much more complex for things which might look trivial
>to you.

Ring buffers are trivial.

[toc] | [prev] | [next] | [standalone]


#120146

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-09-21 12:54 +0200
Message-ID<vcm8kj$1ir5m$1@raubtier-asyl.eternal-september.org>
In reply to#120145
Am 21.09.2024 um 11:40 schrieb Muttley@dastardlyhq.com:
> On Fri, 20 Sep 2024 18:03:14 +0200
> Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>> Am 20.09.2024 um 17:57 schrieb Muttley@dastardlyhq.com:
>>
>>> No, they don't. A deque can have an unbounded (except by memory)
>>> number of items whereas a ring buffer is by design a fixed size.
>>
>> A ring-buffer can be growing, my implementation also does grow.
> 
> A ringbuffer that can grow is not a ring buffer, its a deque as you figured
> out.

It's unspecified whether a ring-buffer can grow. All deque<>-implemen-
tations are ring-buffers since the chunk-list is implemented as a ring.

>> The Boost ringbuffer also can grow.
> 
> Boost has a lot to answer for in many areas.

Boost is for sure too complex for you.

>>> People like yourself are responsible for the absurd amount of bloat
>>> in modern code and ridiculously powerful CPUs being required just
>>> to run office style applications and web pages.
>>
>> The "bloat" results in very few code of who uses this "bloat".
>> You're simply overburdened. Have a look at the standard library
> 
> Am I? I think it might be you who can't think clearly enough to write a
> clean simple algorithm for a simple data structure.

But it's for sure not that convenient to use.

>> code, it's much more complex for things which might look trivial
>> to you.
> 
> Ring buffers are trivial.

Not if they're comfortable to use.

[toc] | [prev] | [next] | [standalone]


#120147

FromChris Ahlstrom <OFeem1987@teleworm.us>
Date2024-09-21 08:18 -0400
Message-ID<vcmdjh$1jed0$1@dont-email.me>
In reply to#120145
Muttley@dastardlyhq.com wrote this copyrighted missive and expects royalties:

> On Fri, 20 Sep 2024 18:03:14 +0200
> Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>>Am 20.09.2024 um 17:57 schrieb Muttley@dastardlyhq.com:
>>
>>> No, they don't. A deque can have an unbounded (except by memory)
>>> number of items whereas a ring buffer is by design a fixed size.
>>
>>A ring-buffer can be growing, my implementation also does grow.
>
> A ringbuffer that can grow is not a ring buffer, its a deque as you figured 
> out.
>
>>The Boost ringbuffer also can grow.
>
> Boost has a lot to answer for in many areas.
>
>>> People like yourself are responsible for the absurd amount of bloat
>>> in modern code and ridiculously powerful CPUs being required just
>>> to run office style applications and web pages.
>>
>>The "bloat" results in very few code of who uses this "bloat".
>>You're simply overburdened. Have a look at the standard library
>
> Am I? I think it might be you who can't think clearly enough to write a 
> clean simple algorithm for a simple data structure.
>
>>code, it's much more complex for things which might look trivial
>>to you.
>
> Ring buffers are trivial.

Depends what you want. The ringbuffer.c module in the jack2 project is 420
lines including comments and #ifdefs. It also provides optional locking, and
some convenience functions.

I wrote a ringbuffer template class that is "similar" in size and scope.
Probably could refine it further.

Apropos of nothing:

    https://mathworld.wolfram.com/Trivial.html

    According to the Nobel Prize-winning physicist Richard Feynman (Feynman
    1997), mathematicians designate any theorem as "trivial" once a proof has
    been obtained--no matter how difficult the theorem was to prove in the
    first place. There are therefore exactly two types of true mathematical
    propositions: trivial ones, and those which have not yet been proven.

-- 
Have at you!

[toc] | [prev] | [next] | [standalone]


#120148

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-09-21 14:25 +0200
Message-ID<vcmdv9$1jjfn$1@raubtier-asyl.eternal-september.org>
In reply to#120147
Am 21.09.2024 um 14:18 schrieb Chris Ahlstrom:

> I wrote a ringbuffer template class that is "similar" in size and scope.
> Probably could refine it further.

He thinks he could write that in 10 lines without noticing the requirements.

[toc] | [prev] | [next] | [standalone]


#120149

FromMuttley@dastardlyhq.com
Date2024-09-21 15:59 +0000
Message-ID<vcmqht$1ld5i$1@dont-email.me>
In reply to#120148
On Sat, 21 Sep 2024 14:25:18 +0200
Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>Am 21.09.2024 um 14:18 schrieb Chris Ahlstrom:
>
>> I wrote a ringbuffer template class that is "similar" in size and scope.
>> Probably could refine it further.
>
>He thinks he could write that in 10 lines without noticing the requirements.

I implented the sound output buffer for a virtual synth as a ring buffer.
As you can imagine time constraints were on the order of milliseconds as the
buffer itself only contained 1/20th of a second of PCM data.

Normally the read and write pointers kept more or less in lock step depending
on how the threads were running but not always, and you absolutely cannot have 
the sound stop so if the read pointer had to go around again so be it, you
might hear a small click but usually not.

It didn't require 420 lines to implement because if it had it would have been
so slow the sound would have been glitching all over the place.

Unlike you sitting in your ivory academic tower I have real world experience
of these things.

[toc] | [prev] | [next] | [standalone]


#120150

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-09-21 18:12 +0200
Message-ID<vcmr90$1lfqi$1@raubtier-asyl.eternal-september.org>
In reply to#120149
Am 21.09.2024 um 17:59 schrieb Muttley@dastardlyhq.com:

> I implented the sound output buffer for a virtual synth as a ring buffer.

That's a ring for _trivial_ C++ types, that's much easier. I can handle
complex C++ types with a vector<>-like emplace( )and I move them when
the ring is resized; that's much more effort.

> It didn't require 420 lines to implement because if it had it would have been
> so slow the sound would have been glitching all over the place.

Your requirements are simply totally different since you don't need to
handle resizes and complex types.

> Unlike you sitting in your ivory academic tower I have real world experience
> of these things.

I wrote my little class for a real purpose.

And you need a dozen postings to understand what the static and variable
initialization parameters for a semaphore are good for.

[toc] | [prev] | [next] | [standalone]


#120161

FromMuttley@dastardlyhq.com
Date2024-09-22 07:58 +0000
Message-ID<vcoimb$24pda$1@dont-email.me>
In reply to#120150
On Sat, 21 Sep 2024 18:12:21 +0200
Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>Am 21.09.2024 um 17:59 schrieb Muttley@dastardlyhq.com:
>
>> I implented the sound output buffer for a virtual synth as a ring buffer.
>
>That's a ring for _trivial_ C++ types, that's much easier. I can handle

Watch those goalposts move.

>complex C++ types with a vector<>-like emplace( )and I move them when
>the ring is resized; that's much more effort.

For complex types any sane person would just use an STL container as the 
basis of a ring buffer instead of reinventing the wheel like you've done. And 
probably made it square in the process.

>And you need a dozen postings to understand what the static and variable
>initialization parameters for a semaphore are good for.

And you required a number of posts using loads of gibberish to attempt to 
explain yet you still failed. Meanwhile someone else managed it in 2 lines.

[toc] | [prev] | [next] | [standalone]


#120164

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-09-22 10:48 +0200
Message-ID<vcolk2$257gb$2@raubtier-asyl.eternal-september.org>
In reply to#120161
Am 22.09.2024 um 09:58 schrieb Muttley@dastardlyhq.com:

> For complex types any sane person would just use an STL container as the
> basis of a ring buffer instead of reinventing the wheel like you've done.

And the STL-container is a magnitude more complex. I developed
this little alternative because I needed a qeue for MSVC which
is as efficient as libstdc++'s or libc++'s deque.

> And you required a number of posts using loads of gibberish to attempt to
> explain yet you still failed. Meanwhile someone else managed it in 2 lines.

My code simply works and it it maximally efficient and convenient to use.

[toc] | [prev] | [next] | [standalone]


#120166

FromMuttley@dastardlyhq.com
Date2024-09-22 09:01 +0000
Message-ID<vcomdq$25c15$1@dont-email.me>
In reply to#120164
On Sun, 22 Sep 2024 10:48:07 +0200
Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>Am 22.09.2024 um 09:58 schrieb Muttley@dastardlyhq.com:
>
>> For complex types any sane person would just use an STL container as the
>> basis of a ring buffer instead of reinventing the wheel like you've done.
>
>And the STL-container is a magnitude more complex. I developed

So what? The containers are already written for you and many clever eyes and 
minds have made sure they're as efficient as possible.

>this little alternative because I needed a qeue for MSVC which
>is as efficient as libstdc++'s or libc++'s deque.

So why didn't you just use std::deque then with a couple of wrapper functions.

[toc] | [prev] | [next] | [standalone]


#120170

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-09-22 11:49 +0200
Message-ID<vcop7k$25nld$1@raubtier-asyl.eternal-september.org>
In reply to#120166
Am 22.09.2024 um 11:01 schrieb Muttley@dastardlyhq.com:

> So what? The containers are already written for you and many clever eyes and
> minds have made sure they're as efficient as possible.

You're not just trying to explain away complexity with me because
it's too much for you.

> So why didn't you just use std::deque then with a couple of wrapper functions.

Because MSVC's std::deque and Boost's boost::container::deque is
multiple times slower. I needed a fast solution for all platforms.

[toc] | [prev] | [next] | [standalone]


#120180

FromMuttley@dastardlyhq.com
Date2024-09-22 15:13 +0000
Message-ID<vcpc6h$28gkc$1@dont-email.me>
In reply to#120170
On Sun, 22 Sep 2024 11:49:45 +0200
Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>Am 22.09.2024 um 11:01 schrieb Muttley@dastardlyhq.com:
>
>> So what? The containers are already written for you and many clever eyes and
>> minds have made sure they're as efficient as possible.
>
>You're not just trying to explain away complexity with me because
>it's too much for you.

If you say so poppet.

>
>> So why didn't you just use std::deque then with a couple of wrapper
>functions.
>
>Because MSVC's std::deque and Boost's boost::container::deque is
>multiple times slower. I needed a fast solution for all platforms.

Then use a vector. 

No doubt you'd write own crypto libraries too given half a chance.

[toc] | [prev] | [next] | [standalone]


#120185

FromBonita Montero <Bonita.Montero@gmail.com>
Date2024-09-22 17:28 +0200
Message-ID<vcpd2n$28k8u$1@raubtier-asyl.eternal-september.org>
In reply to#120180
Am 22.09.2024 um 17:13 schrieb Muttley@dastardlyhq.com:
> On Sun, 22 Sep 2024 11:49:45 +0200
> Bonita Montero <Bonita.Montero@gmail.com> boringly babbled:
>> Am 22.09.2024 um 11:01 schrieb Muttley@dastardlyhq.com:
>>
>>> So what? The containers are already written for you and many clever eyes and
>>> minds have made sure they're as efficient as possible.
>>
>> You're not just trying to explain away complexity with me because
>> it's too much for you.
> 
> If you say so poppet.

You deny a lot of advanced technologies.

> Then use a vector.

Then I'd to manage the whole ring-issues. So I wrote the code once
and now I have a maximally efficient solution which is only 400 LOCs.

> No doubt you'd write own crypto libraries too given half a chance.

If I had no alternative like in this case ... But that's unlikely.

[toc] | [prev] | [next] | [standalone]


Page 1 of 3  [1] 2 3  Next page →

Back to top | Article view | comp.lang.c++


csiph-web