Skip to content

lackhole/stl-preview

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

STL Preview

logo.png

Description

Use the latest STL implementation regardless of your C++ version (C++14 ~)

// All implementations are written under C++14 standard semantics
#include "preview/ranges.h"

auto map = preview::views::iota('A', 'E') | 
           preview::views::enumerate | 
           preview::ranges::to<std::map>(); // See notes about CTAD below

std::cout << map[0] << ' '
          << map[1] << ' '
          << map[2] << '\n';
// A B C

preview is standard-conforming, and is compatible with existing STL

// Pre-C++20 iterators are fully compatible
auto floats = std::istringstream{"1.1  2.2\t3.3\v4.4\f55\n66\r7.7  8.8"};
ranges::copy(views::istream<float>(floats), std::ostream_iterator<float>{std::cout, ", "});

// Complex ranges/iterators are also compatible with both pre C++20 and 
// post C++20 std::iterator_traits
auto r = preview::views::iota(0) |
      preview::views::take(10) |
      preview::views::filter([](auto x) { return x % 2 == 0; });

static_assert(std::is_same<
    std::iterator_traits<decltype(r.begin())>::reference,
    int
>::value, "");

Up to C++26 STL are available

void foo(preview::span<int>) {}

int main() {
  // span with C++26 standard
  foo({1, 2, 3});
  
  preview::variant<int, float, double> v{1.0f};
  v.visit([](auto x) {
    // member visit(): C++26 standard
  });
  
  // views::concat
  std::vector<char> v = {'h', 'e', 'l'};
  std::string s = "lo, ";
  preview::string_view sv = "world";
  std::list<char> l = {'!'};

  // hello, world!
  for (auto c : preview::views::concat(v, s, sv, l)) {
    std::cout << c;
  }
  
  // expected
  auto process = [](preview::string_view str) -> preview::expected<int, std::string> {
    return parse_number(str)
      .transform([](double v) { return static_cast<int>(v); })
      .transform_error([](parse_error e) {
        return e == parse_error::invalid_input ? "invalid input" : "overflow";
      });
  };
  std::cout << process("42").value_or(-1) << '\n;'; // 42
  std::cout << process("inf").value_or(-1) << '\n'; // -1
}

Compiler Support

Build Status

Compiler Minimum version tested Maximum version tested
MSVC 19.16.27051.0 (Visual Studio 2017) 19.40.33811.0 (Visual Studio 2022)
gcc 9.5.0 13.1.0
clang 11.1.0 15.0.7
Apple clang 14.0.0.14000029 15.0.0.15000040 (Silicon)
Android NDK r18 (clang 7.0) r26 (clang 17.0.2)
Emscripten 3.1.20 (clang 16.0.0) latest(3.1.61) (clang 19.0.0)
MinGW 13.1.0 14.2.0
Intel C++ ? icx 2024.2

Build & Install

CMake

Copy this repository under your project and use add_subdirectory

add_subdirectory(path/to/preview)
target_link_libraries(your-project INTERFACE preview)

Non-CMake

Although it is not recommended, you can just copy & paste files under include/ into your project.

  • Note: Without CMake configuration, heuristic compiler/STL checks will be performed.

Installation

With the reason stated in Non-CMake, installation is possible but not recommended.

Implementation Status

Implementation available in C++14 ~ :

Header Total C++17 C++20 C++23 C++26
algorithm
any
array
bit
concepts
cstddef
expected
functional
iterator
memory
numbers
numeric
optional
random
ranges
span
string_view *
tuple
type_traits
utility
variant
atomic
barrier
charconv
chrono
cmath
compare
coroutine N/A
debugging
exception
execution
flat_map
flat_set
format
filesystem N/A
hazard_pointer
inplace_vector
latch
linalg
mdspan
memory_resource
mutex
new
print
rcu
semaphore
shared_mutex
stop_token
string
source_location N/A
syncstream
spanstream
stacktrace N/A
text_encoding
thread
version

Detailed status

Features

Description

  • : C++YY standard implemented in C++XX
  • : C++YY standard, not implemented yet
  • If the implementation is impossible(i.e., needs compiler support / hardware info) it is marked as N/A
  • Some features are working in progress
  • Introduced: First introduced version
  • Revision: Behavior changed/updated version

Headers

<algorithm>

Introduced Revision
search
clamp
for_each_n
sample
shift_left
shift_right
ranges::in_fun_result
ranges::in_in_result
ranges::in_out_result
ranges::in_in_out_result
ranges::in_out_out_result
ranges::min_max_result
ranges::in_found_result
ranges::in_value_result
ranges::out_value_result
ranges::all_of
ranges::any_of
ranges::none_of
ranges::for_each
ranges::for_each_n
ranges::count
ranges::count_if
ranges::mismatch
ranges::find
ranges::find_if
ranges::find_if_not
ranges::find_last
ranges::find_last_if
ranges::find_last_if_not
ranges::find_end
ranges::find_first_of
ranges::adjacent_find
ranges::search
ranges::search_n
ranges::contains
ranges::contains_subrange
ranges::starts_with
ranges::ends_with
ranges::fold_left
ranges::fold_left_first
ranges::fold_right
ranges::fold_right_last
ranges::fold_left_with_iter
ranges::fold_left_first_with_iter
ranges::copy
ranges::copy_if
ranges::copy_n
ranges::copy_backward
ranges::move
ranges::move_backward
ranges::fill
ranges::fill_n
ranges::transform
ranges::generate
ranges::generate_n
ranges::remove
ranges::remove_if
ranges::remove_copy
ranges::remove_copy_if
ranges::replace
ranges::replace_if
ranges::replace_copy
ranges::replace_copy_if
ranges::swap_ranges
ranges::reverse
ranges::reverse_copy
ranges::rotate
ranges::rotate_copy
ranges::shift_left
ranges::shift_right
ranges::sample
ranges::shuffle
ranges::unique
ranges::unique_copy
ranges::is_partitioned
ranges::partition
ranges::partition_copy
ranges::stable_partition
ranges::partition_point
ranges::is_sorted
ranges::is_sorted_until
ranges::sort
ranges::partial_sort
ranges::partial_sort_copy
ranges::stable_sort
ranges::nth_element
ranges::lower_bound
ranges::upper_bound
ranges::binary_search
ranges::equal_range
ranges::merge
ranges::inplace_merge
ranges::includes
ranges::set_difference
ranges::set_intersection
ranges::set_symmetric_difference
ranges::set_union
ranges::is_heap
ranges::is_heap_until
ranges::make_heap
ranges::push_heap
ranges::pop_heap
ranges::sort_heap
ranges::max
ranges::max_element
ranges::min
ranges::min_element
ranges::minmax
ranges::minmax_element
ranges::clamp
ranges::equal
ranges::lexicographical_compare
ranges::is_permutation
ranges::next_permutation
ranges::prev_permutation

<any>

Introduced Revision
any *
bad_any_cast
swap(any)
make_any
any_cast
  • Notes
    • preview::any
      • preview::any is an alias of std::any if using C++17 or later to prevent implicit construction of std::any from preview::any and vice-versa. See any.h for more detail.

<array>

Introduced Revision
to_array

<atomic>

Introduced Revision
atomic_ref
atomic_signed_lock_free
atomic_unsigned_lock_free
atomic_wait
atomic_wait_explicit
atomic_notify_one
atomic_notify_all
atomic_flag_test
atomic_flag_test_explicit
atomic_flag_wait
atomic_flag_wait_explicit
atomic_flag_notify_one
atomic_flag_notifly_all
atomic_fetch_max
atomic_fetch_max_explicit
atomic_fetch_min
atomic_fetch_min_explicit

<barrier>

Introduced Revision
barrier

<bit>

Introduced Revision
endian
bit_cast
byteswap
has_single_bit
bit_ceil
bit_floor
bit_width
rotl
rotr
countl_zero
countl_one
countr_zero
countr_one
popcount

<charconv>

Introduced Revision
chars_format
from_chars_result
to_chars_result
from_chars
to_chars

<chrono>

Introduced Revision
std::chrono::duration
std::chrono::time_point
clock_time_conversion
is_clock
utc_clock
tai_clock
gps_clock
file_clock
local_t
last_spec
day
month
year
weekday
weekday_indexed
weekday_last
month_day
month_day_last
month_weekday
month_weekday_last
year_month
year_month_day
year_month_day_last
year_month_weekday
year_month_weekday_last
hh_mm_ss
tzdb
tzdb_list
tzdb_zone
get_tzdb
get_tzdb_list
reload_tzdb
remote_version
locate_zone
sys_info
local_info
choose
zoned_traits
zoned_time
time_zone_link
nonexistent_local_time
ambiguous_local_time
leap_second
leap_second_info
get_leap_second_info
is_am
is_pm
make_12
make_24

<cmath>

Introduced Revision
assoc_laguerre
assoc_legendre
beta
comp_ellint_1
comp_ellint_2
comp_ellint_3
cyl_bessel_i
cyl_bessel_j
cyl_bessel_k
cyl_neumann
ellint_1
ellint_2
ellint_3
expint
hermite
legendre
laguerre
riemann_zeta
sph_bessel
sph_legendre
sph_neumann
hypot(x, y, z)

<compare>

N/A

<concepts>

Introduced Revision
same_as
derived_from
convertible_to
common_reference_with
common_with
integral
signed_integral
unsigned_integral
floating_point
assignable_from
swappable
destructible
constructible_from
default_initializable
move_constructible
copy_constructible
equality_comparable
equality_comparable_with
totally_ordered
movable
copyable
semiregular
regular
invocable
regular_invocable
predicate
relation
equivalence_relation
strict_weak_order
ranges::swap

<coroutine>

N/A

<cstddef>

Introduced Revision
byte
to_integer

<debugging>

Introduced Revision
breakpoint
breakpoint_if_debugging
is_debugger_present

<exception>

Introduced Revision
uncaught_exceptions (N/A)

<expected>

Introduced Revision
expected
unexpected
bad_expected_access
unexpect
unexpect_t

<execution>

N/A

<flat_map>

Introduced Revision
flat_map
flat_multimap
sorted_unique
sorted_unique_t
sorted_equivalent
sorted_equivalent_t

<flat_set>

Introduced Revision
flat_set
flat_multiset

<format>

Introduced Revision
formatter
basic_format_parse_context
basic_format_context
basic_format_arg
basic_format_args
basic_format_string
format_error
format
format_to
format_to_n
formatted_size
vformat
vformat_to
visit_format_arg deprecated in C++26
make_format_args
make_wformat_args
formattable
range_format
range_formatter
formatter<pair-or-tuple>
formatter<range>
format_kind
enable_nonlocking_formatter_optimization
runtime_format

<filesystem>

N/A

<functional>

Introduced Revision
reference_wrapper *
default_searcher
boyer_moore_searcher
boyer_moore_horspool_searcher
invoke
not_fn
bind_front
identity
unwrap_reference
unwrap_ref_decay
ranges::equal_to
ranges::not_equal_to
ranges::greater
ranges::less
ranges::greater_equal
ranges::less_equal
compare_three_way
ranges::three_way
invoke_r
bind_back
move_only_function
copyable_function
function_ref
  • Notes
    • reference_wrapper
      • Non-standard member function operator*() is defined only for the purpose of mixed use with std::invoke.
      • Before C++20, preview::reference_wrapper cannot be used in deduced context of std::reference_wrapper. In sucn case, non-standard member function to_std() can be used.
        template<typename T>
        void foo(std::reference_wrapper<T> x) {}
        
        int main() {
          int x = 10;
          auto ref = preview::ref(x);
          foo(ref); // Compile error before C++20
          foo(ref.to_std());
        
          std::cout << std::boolalpha << (ref == 10) << std::endl;
        }

<hazard_pointer>

Introduced Revision
hazard_pointer_obj_base
hazard_pointer
make_hazard_pointer

<inplace_vector>

Introduced Revision
inplace_vector

<iterator>

Introduced Revision
contiguous_iterator_tag *
indirectly_readable
indirectly_writable
weakly_incrementable
incrementable
input_or_output_iterator
sentinel_for
sized_sentinel_for
input_iterator
output_iterator
forward_iterator
bidirectional_iterator
random_access_iterator
contiguous_iterator *
indirectly_unary_invocable
indirectly_regular_unary_invocable
indirect_unary_predicate
indirect_binary_predicate
indirect_equivalence_relation
indirect_strict_weak_order
indirectly_movable
indirectly_movable_storable
indirectly_copyable
indirectly_copyable_storable
indirectly_swappable
indirectly_comparable
permutable
mergeable
sortable
indirect_result_t
projected *
projected_value_t
incrementable_traits
indirectly_readable_traits
iter_value_t
iter_reference_t
iter_const_reference_t
iter_difference_t
iter_rvalue_reference_t
iter_common_reference_t
iterator_traits
move_sentinel
basic_const_iterator
const_iterator
const_sentinel
common_iterator
default_sentinel_t
default_sentinel
counted_iterator
unreachable_sentinel_t
unreachable_sentinel
iter_move
iter_swap
make_const_iterator
make_const_sentinel
ranges::advance
ranges::distance
ranges::next
ranges::prev
size(C)
ssize(C)
empty(C)
data(C)
  • Notes
    • contiguous_iterator_tag
      • Alias to std::contiguous_iterator_tag if defined, preview::detail::pseudo_contiguous_iterator_tag otherwise.

    • contiguous_iterator<I>
      • May incorrectly evaluates to true for some random_access_iterator if I::iterator_category does not satisfy derived_from<contiguous_iterator_tag>(typically before C++20)
      • Following pre-C++20 iterators explicitly evaluates to false
        • std::vector<bool>::xxx_iterator
        • std::deque<T>::xxx_iterator

    • projected
      • Indirect layer doesn't work without using concepts. Check preview::projectable before using preview::projected directly.

<latch>

Introduced Revision
latch

<linalg>

Introduced Revision
layout_blas_packed
scaled_accessor
conjugated_accessor
layout_transpose
column_major
column_major_t
row_major
row_major_t
upper_triangle
upper_triangle_t
lower_triangle
lower_triangle_t
implicit_unit_diagonal
implicit_unit_diagonal_t
explicit_unit_diagonal
explicit_unit_diagonal_t
scaled
conjugated
transposed
conjugated_transposed
setup_givens_rotation
apply_givens_rotation
swap_elements
scale
copy
add
dot
dotc
vector_sum_of_squares
vector_two_norm
vector_abs_sum
vector_idx_abs_max
matrix_frob_norm
matrix_one_norm
matrix_inf_norm
matrix_vector_product
symmetric_matrix_vector_product
hermitian_matrix_vector_product
triangular_matrix_vector_product
triangular_matrix_vector_solve
matrix_rank_1_update
matrix_rank_1_update_c
symmetric_matrix_rank_1_update
hermitian_matrix_rank_1_update
symmetric_matrix_rank_2_update
hermitian_matrix_rank_2_update
matrix_product
symmetric_matrix_product
hermitian_matrix_product
triangular_matrix_product
triangular_matrix_left_product
triangular_matrix_right_product
symmetric_matrix_rank_k_update
hermitian_matrix_rank_k_update
symmetric_matrix_rank_2k_update
hermitian_matrix_rank_2k_update
triangular_matrix_matrix_left_solve
triangular_matrix_matrix_right_solve

<mdspan>

Introduced Revision
mdspan
extents
layout_left
layout_right
layout_stride
layout_stride
submdspan
submdspan_extents
strided_slice
submdspan_mapping_result
full_extent
full_extent_t

<memory>

Introduced Revision
pointer_traits
aligned_alloc
destroy_at
destroy
destroy_n
xxx_pointer_cast
uninitialized_default_construct
uninitialized_default_construct_n
uninitialized_move
uninitialized_move_n
uninitialized_value_construct
uninitialized_value_construct_n
atomic<shared_ptr>
atomic<unique_ptr>
assume_aligned
construct_at
make_shared_for_overwrite
make_unique_for_overwrite
allocate_shared_for_overwrite
to_address *
uses_allocator_construction_args
make_obj_using_allocator
uninitialized_construct_using_allocator
operator<<(std::unique_ptr)
ranges::construct_at
ranges::destroy
ranges::destroy_n
ranges::destroy_at
ranges::uninitialized_copy
ranges::uninitialized_copy_n
ranges::uninitialized_fill
ranges::uninitialized_fill_n
ranges::uninitialized_move
ranges::uninitialized_move_n
ranges::uninitialized_default_construct
ranges::uninitialized_default_construct_n
ranges::uninitialized_value_construct
ranges::uninitialized_value_construct_n
allocation_result
inout_ptr
inout_ptr_t
out_ptr
out_ptr_t
start_lifetime_as
start_lifetime_as_array
owner_hash
owner_equal
  • Notes
    • to_address
      • If std::pointer_traits::to_address is available, it is used before preview::pointer_traits::to_address.
        • ⚠️ std::pointer_traits::to_address is not sfinae-friendly until MSVC 2022, so not used.

<memory_resource>

N/A

<mutex>

Introduced Revision
scoped_lock

<new>

Introduced Revision
align_val_t
hardware_destructive_interference_size
hardware_constructive_interference_size
launder
destroying_delete
destroying_delete_t

<numbers>

Introduced Revision
e
log2e
log10e
pi
inv_pi
inv_sqrtpi
ln2
ln10
sqrt2
sqrt3
inv_sqrt3
egamma
phi

<numeric>

Introduced Revision
exclusive_scan
transform_exclusive_scan
inclusive_scan
transform_inclusive_scan
gcd
lcm
reduce
transform_reduce
midpoint
ranges::iota
add_sat
sub_sat
mul_sat
div_sat
saturate_cast

<print>

Introduced Revision
print
println
vprint_unicode
vprint_unicode_buffered
vprint_nonunicode
vprint_nonunicode_buffered

<optional>

Introduced Revision
optional *
bad_optional_access
std::hash<optional>
nullopt *
nullopt_t *
swap(optional)
make_optional
  • Notes
    • nullopt, nullopt_t
      • std::nullopt is used if available, preview::nullopt otherwise.
    • C++26

<random>

Introduced Revision
uniform_random_bit_generator

<ranges>

Introduced Revision
ranges::range
ranges::borrowed_range
ranges::sized_range
ranges::view
ranges::input_range
ranges::output_range
ranges::forward_range
ranges::bidirectional_range
ranges::random_access_range
ranges::contiguous_range
ranges::common_range
ranges::viewable_range
ranges::constant_range
ranges::to *
ranges::iterator_t
ranges::const_iterator_t
ranges::sentinel_t
ranges::const_sentinel_t
ranges::range_difference_t
ranges::range_size_t
ranges::range_value_t
ranges::range_refernce_t
ranges::range_const_reference_t
ranges::range_rvalue_reference_t
ranges::range_common_reference_t
ranges::view_interface
ranges::subrange
ranges::dangling
ranges::borrowed_iterator_t
ranges::borrowed_subrange_t
ranges::range_adaptor_closure
ranges::empty_view
views::empty
ranges::single_view
views::single
ranges::iota_view
views::iota
ranges::iota_view
views::iota
ranges::basic_istream_view
views::istream
ranges::repeat_view
views::repeat
ranges::cartesian_product_view
views::cartesian_product
views::all_t
views::all
ranges::ref_view
ranges::owning_view
ranges::filter_view
views::filter
ranges::transform_view
views::transform
ranges::take_view
views::take
ranges::take_while_view
views::take_while
ranges::drop_view
views::drop
ranges::drop_while_view
views::drop_while
ranges::join_view
views::join
ranges::lazy_split_view
views::lazy_split
ranges::split_view
views::split
views::counted
ranges::common_view
views::common
ranges::reverse_view
views::reverse
ranges::as_const_view
views::as_const
ranges::as_rvalue_view
views::as_rvalue
ranges::elements_view
views::elements
ranges::keys_view
views::keys
ranges::values_view
views::values
ranges::enumerate_view
views::enumerate
ranges::zip_view
views::zip
ranges::zip_transform_view
views::zip_transform
ranges::adjacent_view
views::adjacent
ranges::adjacent_transform_view
views::adjacent_transform
ranges::join_with_view
views::join_with
ranges::stride_view
views::stride
ranges::slide_view
views::slide
ranges::chunk_view
views::chunk
ranges::chunk_by_view
views::chunk_by
ranges::concat_view
views::concat
*
ranges::begin
ranges::end
ranges::cbegin
ranges::cend
ranges::crbegin
ranges::crend
ranges::size
ranges::ssize
ranges::empty
ranges::data
ranges::cdata
ranges::subrange_kind
ranges::from_range_t
ranges::from_range
  • Notes
    • ranges::to
      • CTAD for Args... may be incorrect before C++17
      • Equipped with C++23 conversions(e.g., pair-like -> std::pair)
    • ranges::concat_view
      • Implemented before standardization
      • Needs update

<rcu>

Introduced Revision
rcu_obj_base
rcu_domain
rcu_default_domain
rcu_synchronize
rcu_barrier
rcu_retire

<semaphore>

Introduced Revision
counting_semaphore
binary_semaphore

<shared_mutex>

Introduced Revision
shared_mutex

<stop_token>

Introduced Revision
stop_token
stop_source
stop_callback
nostopstate_t
nostopstate

<string>

Introduced Revision
erase(std::basic_string)
erase_if(std::basic_string)
basic_string

<string_view>

Introduced Revision
basic_string_view *
std::hash<basic_string_view>
operator""_sv
  • Notes
    • C++26
      • P2591 (R5)
      • P2697 (R1)
        • Implemented as preview::basic_string_view::operator bitset
      • P2495 (R3)
        • Implemented as preview::basic_string_view::operator string-streams
        • Memory allocation is performed (conversion to std::basic_string)

<source_location>

N/A

Introduced Revision
source_location

<syncstream>

Introduced Revision
basic_syncbuf
basic_osyncstream
std::swap(basic_syncbuf)

<span>

Introduced Revision
span
dynamic_extent
as_bytes
as_writable_bytes

<spanstream>

Introduced Revision
basic_spanbuf
basic_ispanstream
basic_ospanstream
basic_spanstream

<stacktrace>

Introduced Revision
stacktrace_entry
basic_stacktrace
hash<stracktrace_entry>
hash<basic_stacktrace>

<text_encoding>

Introduced Revision
text_encoding

<thread>

Introduced Revision
jthread

<tuple>

Introduced Revision
apply
make_from_tuple
tuple_like pair_like
basic_common_reference<tuple-like>
common_type<tuple-like>
formatter<tuple-like>

<type_traits>

Introduced Revision
common_type
bool_constant
has_unique_object_representations N/A
is_aggregate N/A
is_swappable_with
is_swappable...
is_invocable
invoke_result
void_t
conjunction
disjunction
negation
common_reference
basic_common_reference
is_bounded_array
is_unbounded_array
is_scoped_enum N/A
is_constant_evaluated N/A
is_corresponding_member N/A
is_layout_compatible N/A
is_nothrow_convertible
is_pointer_interconvertible_base_of N/A
is_pointer_interconvertible_with_class N/A
remove_cvref
type_identity
is_implicit_lifetime N/A
is_scoped_enum N/A
reference_converts_from_temporary N/A
reference_constructs_from_temporary N/A
is_within_lifetime N/A
is_virtual_base_of
  • Notes
    • common_type
      • If common_type fails to define member typedef type, it falls back to std::common_type
      struct common_a {};
      struct common_b {};
      struct common_c {};
      
      template<>
      struct std::common_type<common_a, common_b> {
        using type = common_c;
      };
      
      // fallback to std::common_type for user specialization types
      static_assert(std::is_same_v<preview::common_type_t<common_a, common_b>, common_c>);
      
      // MSVC and GCC (before C++23) does not satisfy C++23 standard for std::common_type<tuple-like>  
      static_assert(std::is_same_v<
          std::common_type_t<std::tuple<int, int>, std::pair<int, double>>, 
          std::pair<int, int>>);
      
      // Since std::common_type does not satisfy C++23, preview::common_type does not fallback to std::common_type
      static_assert(std::is_same_v<
          preview::common_type_t< std::tuple<int, int>, std::pair<int, double>>, 
          std::pair<int, double>>);

<utility>

Introduced Revision
as_const
in_place
in_place_t
cmp_equal...
in_range
forward_like
to_underlying
unreachable N/A
nontype
nontype_t

<variant>

Introduced Revision
variant
monostate
bad_variant_access
variant_size
variant_alternative
std::hash<variant>
variant_npos
visit
get_if

<version>

Introduced Revision