Skip to content

Instantly share code, notes, and snippets.

@dlOuOlb
Last active July 31, 2022 12:34
Show Gist options
  • Save dlOuOlb/d86f78e8b2a28401b56700d67e9aead9 to your computer and use it in GitHub Desktop.
Save dlOuOlb/d86f78e8b2a28401b56700d67e9aead9 to your computer and use it in GitHub Desktop.
A class template about a buffer of uninitialized items.
#if __cplusplus < 202002L
# error "This code is written in C++20."
#else
export module dlOuOlb.containers:buffer;
import <concepts>; /* std::(regular|totally_ordered) */
import <cstddef>; /* std::(ptrdiff|size)_t */
import <iterator>; /* std::(\w+_)?iterator(_\w+)? */
import <ranges>; /* std::ranges::\w+ */
import <type_traits>; /* std::((conditional|remove_pointer)_t|is_(same|standard_layout|trivial)_v) */
import <vector>; /* std::vector */
namespace dlOuOlb::containers
{
export template<class Type> concept buffee = std::is_trivial_v<Type> && std::regular<Type> && std::totally_ordered<Type>;
template<buffee Type> union item final
{
Type _;
constexpr item( void ) noexcept // uninitialized members
{
using Self = std::remove_pointer_t<decltype( this )>;
static_assert( alignof( Type ) == alignof( Self ) );
static_assert( sizeof( Type ) == sizeof( Self ) );
static_assert( std::is_standard_layout_v<Self> );
static_assert( std::regular<Self> );
static_assert( std::totally_ordered<Self> );
return;
}
constexpr friend auto operator == ( const item<Type> &Former, const item<Type> &Latter )->bool { return Former._ == Latter._; }
constexpr friend auto operator <=> ( const item<Type> &Former, const item<Type> &Latter ) { return Former._ <=> Latter._; }
};
export template<buffee Type> class buffer final : private std::vector<item<Type>>
{
private:
using base = std::vector<item<Type>>;
static_assert( !base { }.capacity( ) );
static_assert( std::is_same_v<std::size_t, base::size_type> );
static_assert( std::is_same_v<std::ptrdiff_t, base::difference_type> );
public:
using base::size_type;
using base::difference_type;
using value_type = Type;
using reference = value_type &;
using const_reference = const value_type &;
using pointer = value_type *;
using const_pointer = const value_type *;
using base::size;
using base::empty;
constexpr buffer( void ) noexcept = default;
buffer( const std::size_t Count ) : base { Count }
{
using Self = std::remove_pointer_t<decltype( this )>;
static_assert( std::ranges::common_range<Self> );
static_assert( std::ranges::contiguous_range<Self> );
static_assert( std::ranges::sized_range<Self> );
this->shrink_to_fit( );
return;
}
constexpr auto data( void ) noexcept->pointer { return &this->base::data( )->_; }
constexpr auto data( void ) const noexcept->const_pointer { return &this->base::data( )->_; }
constexpr auto at( const std::size_t Index )->reference { return this->base::at( Index )._; }
constexpr auto at( const std::size_t Index ) const->const_reference { return this->base::at( Index )._; }
constexpr auto operator[ ]( const std::size_t Index )->reference { return this->base::operator[ ]( Index )._; }
constexpr auto operator[ ]( const std::size_t Index ) const->const_reference { return this->base::operator[ ]( Index )._; }
constexpr friend auto operator == ( const buffer<Type> &Former, const buffer<Type> &Latter )->bool { return static_cast<const base &>( Former ) == static_cast<const base &>( Latter ); }
constexpr friend auto operator <=> ( const buffer<Type> &Former, const buffer<Type> &Latter ) { return static_cast<const base &>( Former ) <=> static_cast<const base &>( Latter ); }
template<bool Const> class contiguous_iterator final
{
public:
using iterator_category = std::contiguous_iterator_tag;
using difference_type = std::ptrdiff_t;
using element_type = std::conditional_t<Const, const value_type, value_type>;
constexpr contiguous_iterator( void ) noexcept = default;
constexpr contiguous_iterator( element_type *const _ ) noexcept : _ { _ }
{
using Self = std::remove_pointer_t<decltype( this )>;
static_assert( std::contiguous_iterator<Self> );
static_assert( std::random_access_iterator<std::reverse_iterator<Self>> );
return;
}
constexpr friend auto operator <=> ( contiguous_iterator<Const>, contiguous_iterator<Const> ) noexcept = default;
constexpr auto operator *( void ) const->element_type & { return *this->_; }
constexpr auto operator->( void ) const noexcept->element_type * { return this->_; }
constexpr auto operator++( void ) noexcept->contiguous_iterator<Const> & { ++this->_; return *this; }
constexpr auto operator--( void ) noexcept->contiguous_iterator<Const> & { --this->_; return *this; }
constexpr auto operator++( const signed int ) noexcept->contiguous_iterator<Const> { return this->_++; }
constexpr auto operator--( const signed int ) noexcept->contiguous_iterator<Const> { return this->_--; }
constexpr auto operator[ ]( const difference_type Move ) const->element_type & { return this->_[ Move ]; }
constexpr auto operator+= ( const difference_type Move ) noexcept->contiguous_iterator<Const> & { this->_ += Move; return *this; }
constexpr auto operator-= ( const difference_type Move ) noexcept->contiguous_iterator<Const> & { this->_ -= Move; return *this; }
constexpr friend auto operator + ( const contiguous_iterator<Const> This, const difference_type Move ) noexcept->contiguous_iterator<Const> { return This._ + Move; }
constexpr friend auto operator + ( const difference_type Move, const contiguous_iterator<Const> This ) noexcept->contiguous_iterator<Const> { return This._ + Move; }
constexpr friend auto operator - ( const contiguous_iterator<Const> This, const difference_type Move ) noexcept->contiguous_iterator<Const> { return This._ - Move; }
constexpr friend auto operator - ( const contiguous_iterator<Const> This, const contiguous_iterator<Const> That ) noexcept->difference_type { return This._ - That._; }
private:
element_type *_;
};
using iterator = contiguous_iterator<false>;
using const_iterator = contiguous_iterator<true>;
constexpr auto begin( void ) noexcept->iterator { return this->data( ); }
constexpr auto end( void ) noexcept->iterator { return this->data( ) + this->size( ); }
constexpr auto begin( void ) const noexcept->const_iterator { return this->cbegin( ); }
constexpr auto end( void ) const noexcept->const_iterator { return this->cend( ); }
constexpr auto cbegin( void ) const noexcept->const_iterator { return this->data( ); }
constexpr auto cend( void ) const noexcept->const_iterator { return this->data( ) + this->size( ); }
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
constexpr auto rbegin( void ) noexcept->reverse_iterator { return std::make_reverse_iterator( this->end( ) ); }
constexpr auto rend( void ) noexcept->reverse_iterator { return std::make_reverse_iterator( this->begin( ) ); }
constexpr auto rbegin( void ) const noexcept->const_reverse_iterator { return this->crbegin( ); }
constexpr auto rend( void ) const noexcept->const_reverse_iterator { return this->crend( ); }
constexpr auto crbegin( void ) const noexcept->const_reverse_iterator { return std::make_reverse_iterator( this->cend( ) ); }
constexpr auto crend( void ) const noexcept->const_reverse_iterator { return std::make_reverse_iterator( this->cbegin( ) ); }
};
}
#endif
#if __cplusplus < 202002L
# error "This code is written in C++20."
#else
export module dlOuOlb.containers;
export import:buffer;
#endif
#if __cplusplus < 202002L
# error "This code is written in C++20."
#else
# include <format> /* std::format */
# include <iostream> /* std::(cout|endl) */
import dlOuOlb.containers; /* dlOuOlb::containers */
extern R"(C++)" auto main( void ) noexcept( false )->signed int
{
namespace S = std;
namespace OuO = dlOuOlb;
const auto Buffer = OuO::containers::buffer<unsigned char> { 8U }; // 8ZU in C++23
for( const auto Item : Buffer )
static_cast<void>( S::cout << S::format( R"({0:#X} )", Item ) ); // uninitialized reading
static_cast<void>( S::cout << S::endl );
return 0;
}
#endif
@dlOuOlb
Copy link
Author

dlOuOlb commented May 10, 2022

  • std::vector<bool> may be a space-efficient specialization.
  • dlOuOlb::buffer<bool> is not a specialization; each element occupies sizeof(bool) bytes.

@dlOuOlb
Copy link
Author

dlOuOlb commented May 24, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment