std::experimental(3)

🌈 std::experimental β€” Library Functions Manual 🌈

okay bestie, welcome to std::experimental πŸ’– it's literally the namespace where all the shiny new features live while they're still being workshopped. ✨


✨ NAME ✨

std::experimental β€” the namespace for all the features that are defined in ISO Technical Specifications. πŸ‘‘ no cap.


πŸ¦‹ SYNOPSIS πŸ¦‹

πŸŽ€ Classes πŸŽ€

  • class any β€” a container that holds, like, any type you want, and it does it type-safely. main character of containers fr.
  • class bad_any_cast β€” the exception class that gets thrown when an any_cast flops. 😭 it's giving rejection.
  • class bad_optional_access β€” the exception class that shows up when you dereference an optional object that's disengaged. πŸ’€
  • class basic_string_view β€” a reference to a string that does not own it. lowkey just vibing, borrowing, no strings attached (well. strings attached. but not owned).
  • struct in_place_t β€” a tag type, for in-place construction. πŸŽ€
  • struct nullopt_t β€” a tag type used to disengage optional objects. bye bestie πŸ‘‹
  • class optional β€” a class template for optional values. maybe it's there, maybe it's not, that's the vibe. ✨
  • class ostream_joiner β€” an output iterator that inserts a delimiter between elements. obsessed. πŸ₯°
  • struct owner_less< shared_ptr< _Tp > > β€” partial specialization of owner_less for shared_ptr. πŸ¦‹
  • struct owner_less< weak_ptr< _Tp > > β€” partial specialization of owner_less for weak_ptr. πŸ¦‹
  • class propagate_const β€” a const-propagating wrapper. it spreads that const energy πŸ’…

πŸ’œ Typedefs πŸ’œ

template<typename _RAIter, typename _Hash, typename _Pred, typename _Val = typename iterator_traits<_RAIter>::value_type, typename _Diff = typename iterator_traits<_RAIter>::difference_type> using __boyer_moore_base_t
template<typename _Tp> using __propagate_const_elem_type
using erased_type
using string_view
using u16string_view
using u32string_view
using wstring_view

and that's the synopsis section, bestie β€” more of this iconic page is coming, don't go anywhere 🫢

✨ Functions ✨

okay bestie, this is the list. it's long. it's iconic. grab a snack πŸ“ and let's go, because we are going through every single one of these and i'm not skipping a thing.


  • template<typename _Fn, typename _Tuple, std::size_t... _Idx> constexpr decltype(auto) __apply_impl (_Fn &&__f, _Tuple &&__t, std::index_sequence< _Idx... >) β€” the double-underscore impl squad. yes it starts with __, which is universal library-speak for "internals, do not touch, iykyk" 🀫
  • template<typename _Tp, size_t _Nm, size_t... _Idx> constexpr array< remove_cv_t< _Tp >, _Nm > __to_array (_Tp(&__a)[_Nm], index_sequence< _Idx... >) β€” another __-prefixed internals moment. no cap, if it's got two underscores, it's not for you πŸ’…
  • std::default_random_engine & _S_randint_engine () β€” a _S_-prefixed internal handing back a std::default_random_engine &. that's the whole vibe ✨
  • template<typename _ValueType> _ValueType any_cast (const any &__any) β€” official description: Access the contained object. exactly what it says, bestie πŸ’–
  • template<typename _Fn, typename _Tuple> constexpr decltype(auto) apply (_Fn &&__f, _Tuple &&__t) β€” the apply one. constexpr, takes your _Fn &&__f and _Tuple &&__t πŸ¦‹

now we're in the atomic shared_ptr neighborhood and it is giving concurrency 🫢

  • template<typename _Tp> bool atomic_compare_exchange_strong (shared_ptr< _Tp > *__p, shared_ptr< _Tp > *__v, shared_ptr< _Tp > __w) β€” strong compare-exchange, returns bool
  • template<typename _Tp> bool atomic_compare_exchange_strong_explicit (shared_ptr< _Tp > *__p, shared_ptr< _Tp > *__v, shared_ptr< _Tp > __w, memory_order __success, memory_order __failure) β€” the _explicit twin, and yes it takes both a __success and a __failure memory order. two of them. both. πŸ‘‘
  • template<typename _Tp> bool atomic_compare_exchange_weak (shared_ptr< _Tp > *__p, shared_ptr< _Tp > *__v, shared_ptr< _Tp > __w) β€” weak version, still returns bool
  • template<typename _Tp> bool atomic_compare_exchange_weak_explicit (shared_ptr< _Tp > *__p, shared_ptr< _Tp > *__v, shared_ptr< _Tp > __w, memory_order __success, memory_order __failure) β€” weak and explicit, __success + __failure again ✨
  • template<typename _Tp> void atomic_exchange (shared_ptr< _Tp > *__p, shared_ptr< _Tp > __r) β€” exchange, returns void
  • template<typename _Tp> shared_ptr< _Tp > atomic_exchange_explicit (const shared_ptr< _Tp > *__p, shared_ptr< _Tp > __r, memory_order __mo) β€” the explicit exchange, hands you back a shared_ptr< _Tp >
  • template<typename _Tp> bool atomic_is_lock_free (const shared_ptr< _Tp > *__p) β€” asks the question, answers in bool πŸ’…
  • template<typename _Tp> shared_ptr< _Tp > atomic_load (const shared_ptr< _Tp > *__p) β€” load it up, get a shared_ptr< _Tp > back
  • template<typename _Tp> shared_ptr< _Tp > atomic_load_explicit (const shared_ptr< _Tp > *__p, memory_order __mo) β€” load, but with memory_order __mo in the mix
  • template<typename _Tp> void atomic_store (shared_ptr< _Tp > *__p, shared_ptr< _Tp > __r) β€” store, returns void
  • template<typename _Tp> shared_ptr< _Tp > atomic_store_explicit (const shared_ptr< _Tp > *__p, shared_ptr< _Tp > __r, memory_order __mo) β€” the explicit store. heads up bestie, it's declared returning shared_ptr< _Tp > here, so write it exactly like that, don't get cute πŸ™ˆ

  • template<typename _Tp, typename _Tp1> shared_ptr< _Tp > const_pointer_cast (const shared_ptr< _Tp1 > &__r) noexcept β€” const_pointer_cast, noexcept, takes const shared_ptr< _Tp1 > &__r, gives you shared_ptr< _Tp > ⭐
  • template<typename _Tp, typename _Tp1> shared_ptr< _Tp > dynamic_pointer_cast (const shared_ptr< _Tp1 > &__r) noexcept β€” same shape, dynamic_pointer_cast, also noexcept 🌈

now the erase era 🧚 β€” one bullet per container, because every container gets its own overload and we respect that:

  • template<typename _CharT, typename _Traits, typename _Alloc, typename _Up> void erase (basic_string< _CharT, _Traits, _Alloc > &__cont, const _Up &__value) β€” for basic_string
  • template<typename _Tp, typename _Alloc, typename _Up> void erase (deque< _Tp, _Alloc > &__cont, const _Up &__value) β€” for deque
  • template<typename _Tp, typename _Alloc, typename _Up> void erase (forward_list< _Tp, _Alloc > &__cont, const _Up &__value) β€” for forward_list
  • template<typename _Tp, typename _Alloc, typename _Up> void erase (list< _Tp, _Alloc > &__cont, const _Up &__value) β€” for list
  • template<typename _Tp, typename _Alloc, typename _Up> void erase (vector< _Tp, _Alloc > &__cont, const _Up &__value) β€” for vector

and then erase_if, which is the whole glow-up with a predicate instead of a value. thirteen of them, bestie, and i'm listing all thirteen 😀

  • template<typename _CharT, typename _Traits, typename _Alloc, typename _Predicate> void erase_if (basic_string< _CharT, _Traits, _Alloc > &__cont, _Predicate __pred) β€” for basic_string
  • template<typename _Tp, typename _Alloc, typename _Predicate> void erase_if (deque< _Tp, _Alloc > &__cont, _Predicate __pred) β€” for deque
  • template<typename _Tp, typename _Alloc, typename _Predicate> void erase_if (forward_list< _Tp, _Alloc > &__cont, _Predicate __pred) β€” for forward_list
  • template<typename _Tp, typename _Alloc, typename _Predicate> void erase_if (list< _Tp, _Alloc > &__cont, _Predicate __pred) β€” for list
  • template<typename _Key, typename _Tp, typename _Compare, typename _Alloc, typename _Predicate> void erase_if (map< _Key, _Tp, _Compare, _Alloc > &__cont, _Predicate __pred) β€” for map
  • template<typename _Key, typename _Tp, typename _Compare, typename _Alloc, typename _Predicate> void erase_if (multimap< _Key, _Tp, _Compare, _Alloc > &__cont, _Predicate __pred) β€” for multimap
  • template<typename _Key, typename _Compare, typename _Alloc, typename _Predicate> void erase_if (multiset< _Key, _Compare, _Alloc > &__cont, _Predicate __pred) β€” for multiset
  • template<typename _Key, typename _Compare, typename _Alloc, typename _Predicate> void erase_if (set< _Key, _Compare, _Alloc > &__cont, _Predicate __pred) β€” for set
  • template<typename _Key, typename _Tp, typename _Hash, typename _CPred, typename _Alloc, typename _Predicate> void erase_if (unordered_map< _Key, _Tp, _Hash, _CPred, _Alloc > &__cont, _Predicate __pred) β€” for unordered_map
  • template<typename _Key, typename _Tp, typename _Hash, typename _CPred, typename _Alloc, typename _Predicate> void erase_if (unordered_multimap< _Key, _Tp, _Hash, _CPred, _Alloc > &__cont, _Predicate __pred) β€” for unordered_multimap
  • template<typename _Key, typename _Hash, typename _CPred, typename _Alloc, typename _Predicate> void erase_if (unordered_multiset< _Key, _Hash, _CPred, _Alloc > &__cont, _Predicate __pred) β€” for unordered_multiset
  • template<typename _Key, typename _Hash, typename _CPred, typename _Alloc, typename _Predicate> void erase_if (unordered_set< _Key, _Hash, _CPred, _Alloc > &__cont, _Predicate __pred) β€” for unordered_set
  • template<typename _Tp, typename _Alloc, typename _Predicate> void erase_if (vector< _Tp, _Alloc > &__cont, _Predicate __pred) β€” for vector

back to the good stuff 🌸

  • template<typename _Mn, typename _Nn> constexpr common_type_t< _Mn, _Nn > gcd (_Mn __m, _Nn __n) noexcept β€” Greatest common divisor. constexpr, noexcept, immaculate ✨
  • template<typename _Del, typename _Tp> _Del * get_deleter (const shared_ptr< _Tp > &__p) noexcept β€” the manpage note is literally C++14 20.8.2.2.10, so there you go, cite it with your whole chest πŸ’…
  • template<typename _Tp> constexpr const _Tp & get_underlying (const propagate_const< _Tp > &__pt) noexcept β€” const flavor of get_underlying, noexcept
  • template<typename _Tp> constexpr _Tp & get_underlying (propagate_const< _Tp > &__pt) noexcept β€” non-const flavor, also noexcept πŸ¦‹
  • template<typename _Mn, typename _Nn> constexpr common_type_t< _Mn, _Nn > lcm (_Mn __m, _Nn __n) β€” Least common multiple. yes she and gcd are a matching set, periodt πŸ’–
  • template<typename _Dest = void, typename... _Types> constexpr array< typename __make_array_elem< _Dest, _Types... >::type, sizeof...(_Types)> make_array (_Types &&... __t) β€” official note: Create a std::array from a variable-length list of arguments. variadic icon behavior πŸ”₯

the searcher generators, aka the pattern-finding trio πŸ•΅οΈβ€β™€οΈ each one is a generator function and each one keeps its defaults exactly:

  • template<typename _RAIter, typename _Hash = std::hash<typename std::iterator_traits<_RAIter>::value_type>, typename _BinaryPredicate = equal_to<>> boyer_moore_horspool_searcher< _RAIter, _Hash, _BinaryPredicate > make_boyer_moore_horspool_searcher (_RAIter __pat_first, _RAIter __pat_last, _Hash __hf=_Hash(), _BinaryPredicate __pred=_BinaryPredicate()) β€” official: Generator function for boyer_moore_horspool_searcher
  • template<typename _RAIter, typename _Hash = std::hash<typename std::iterator_traits<_RAIter>::value_type>, typename _BinaryPredicate = equal_to<>> boyer_moore_searcher< _RAIter, _Hash, _BinaryPredicate > make_boyer_moore_searcher (_RAIter __pat_first, _RAIter __pat_last, _Hash __hf=_Hash(), _BinaryPredicate __pred=_BinaryPredicate()) β€” official: Generator function for boyer_moore_searcher
  • template<typename _ForwardIterator, typename _BinaryPredicate = std::equal_to<>> default_searcher< _ForwardIterator, _BinaryPredicate > make_default_searcher (_ForwardIterator __pat_first, _ForwardIterator __pat_last, _BinaryPredicate __pred=_BinaryPredicate()) β€” official: Generator function for default_searcher

note the first two default _Hash to std::hash<...> and _BinaryPredicate to equal_to<>, while the third defaults to std::equal_to<> β€” do not "tidy" those, they're different and they're staying different πŸ™ˆ


  • template<typename _Tp> constexpr observer_ptr< _Tp > make_observer (_Tp *__p) noexcept β€” make_observer, constexpr, noexcept, takes _Tp *__p πŸ‘€
  • template<typename _CharT, typename _Traits, typename _DelimT> ostream_joiner< decay_t< _DelimT >, _CharT, _Traits > make_ostream_joiner (basic_ostream< _CharT, _Traits > &__os, _DelimT &&__delimiter) β€” official: Object generator for ostream_joiner πŸ’œ
  • template<typename _Fn> auto not_fn (_Fn &&__fn) noexcept(std::is_nothrow_constructible< std::decay_t< _Fn >, _Fn && >::value) β€” the manpage tag for this one is literally [func.not_fn] Function template not_fn. that conditional noexcept is so specific and i love her ✨

and now the comparison operators, aka the operator overload parade πŸŽ‰ buckle up, there's a lot of operator!= and we are doing every last one:

operator!= for basic_string_view:

  • template<typename _CharT, typename _Traits> constexpr bool operator!= (__type_identity_t< basic_string_view< _CharT, _Traits > > __x, basic_string_view< _CharT, _Traits > __y) noexcept
  • template<typename _CharT, typename _Traits> constexpr bool operator!= (basic_string_view< _CharT, _Traits > __x, __type_identity_t< basic_string_view< _CharT, _Traits > > __y) noexcept
  • template<typename _CharT, typename _Traits> constexpr bool operator!= (basic_string_view< _CharT, _Traits > __x, basic_string_view< _CharT, _Traits > __y) noexcept

operator!= for propagate_const:

  • template<typename _Tp, typename _Up> constexpr bool operator!= (const _Tp &__t, const propagate_const< _Up > &__pu)
  • template<typename _Tp, typename _Up> constexpr bool operator!= (const propagate_const< _Tp > &__pt, const _Up &__u)
  • template<typename _Tp, typename _Up> constexpr bool operator!= (const propagate_const< _Tp > &__pt, const propagate_const< _Up > &__pu)
  • template<typename _Tp> constexpr bool operator!= (const propagate_const< _Tp > &__pt, nullptr_t)

operator!= for shared_ptr:

  • template<typename _Tp> bool operator!= (const shared_ptr< _Tp > &__a, nullptr_t) noexcept
  • template<typename _Tp1, typename _Tp2> bool operator!= (const shared_ptr< _Tp1 > &__a, const shared_ptr< _Tp2 > &__b) noexcept

more operator!=, nullptr_t first this time:

  • template<typename _Tp> constexpr bool operator!= (nullptr_t, const propagate_const< _Tp > &__pu)
  • template<typename _Tp> bool operator!= (nullptr_t, const shared_ptr< _Tp > &__a) noexcept

operator!= for observer_ptr:

  • template<typename _Tp> constexpr bool operator!= (nullptr_t, observer_ptr< _Tp > __p) noexcept
  • template<typename _Tp> bool operator!= (observer_ptr< _Tp > __p, nullptr_t) noexcept
  • template<typename _Tp, typename _Up> constexpr bool operator!= (observer_ptr< _Tp > __p1, observer_ptr< _Up > __p2)

the literal-suffix quartet πŸ’… (copied character for character, exactly how the page prints them):

  • constexpr basic_string_view< char > operator''sv (const char *__str, size_t __len) noexcept
  • constexpr basic_string_view< char16_t > operator''sv (const char16_t *__str, size_t __len) noexcept
  • constexpr basic_string_view< char32_t > operator''sv (const char32_t *__str, size_t __len) noexcept
  • constexpr basic_string_view< wchar_t > operator''sv (const wchar_t *__str, size_t __len) noexcept

and here come the operator< girls 🌸

operator< for basic_string_view:

  • template<typename _CharT, typename _Traits> constexpr bool operator< (__type_identity_t< basic_string_view< _CharT, _Traits > > __x, basic_string_view< _CharT, _Traits > __y) noexcept
  • template<typename _CharT, typename _Traits> constexpr bool operator< (basic_string_view< _CharT, _Traits > __x, __type_identity_t< basic_string_view< _CharT, _Traits > > __y) noexcept
  • template<typename _CharT, typename _Traits> constexpr bool operator< (basic_string_view< _CharT, _Traits > __x, basic_string_view< _CharT, _Traits > __y) noexcept

operator< for propagate_const:

  • template<typename _Tp, typename _Up> constexpr bool operator< (const _Tp &__t, const propagate_const< _Up > &__pu)
  • template<typename _Tp, typename _Up> constexpr bool operator< (const propagate_const< _Tp > &__pt, const _Up &__u)
  • template<typename _Tp, typename _Up> constexpr bool operator< (const

…and that last one is still mid-sentence, bestie β€” its signature keeps going in the next part, so we're picking it right back up there 🫢

okay bestie we're picking up mid-sentence, literally mid-signature, because this is part 3 and part 2 left us hanging like a cliffhanger episode. Here's the tail end of the previous declaration, no context, just vibes:

propagate_const< _Tp > &__pt, const propagate_const< _Up > &__pu)

and now we get the comparison operators. There are… a lot of them. The standard library looked at "how many overloads should we ship" and said all of them. πŸ’…


✨ operator< ✨

shared_ptr versus nullptr_t, shared_ptr versus shared_ptr, nullptr_t versus shared_ptr, and then the observer_ptr one. Every direction. No gaps. We love thoroughness.

template<typename _Tp> bool operator< (const shared_ptr< _Tp > &__a,
    nullptr_t) noexcept
template<typename _Tp1, typename _Tp2> bool operator< (const shared_ptr<
    _Tp1 > &__a, const shared_ptr< _Tp2 > &__b) noexcept
template<typename _Tp> bool operator< (nullptr_t, const shared_ptr< _Tp
    > &__a) noexcept
template<typename _Tp, typename _Up> constexpr bool operator<
    (observer_ptr< _Tp > __p1, observer_ptr< _Up > __p2)

then the stream-insertion operators, which are iconic and honestly the ones you'll actually use:

template<typename _CharT, typename _Traits> basic_ostream< _CharT,
    _Traits > & operator<< (basic_ostream< _CharT, _Traits > &__os,
    basic_string_view< _CharT, _Traits > __str)
template<typename _Ch, typename _Tr, typename _Tp> std::basic_ostream<
    _Ch, _Tr > & operator<< (std::basic_ostream< _Ch, _Tr > &__os, const
    shared_ptr< _Tp > &__p)

πŸ’– operator<= πŸ’–

okay so basic_string_view gets three separate flavours of <= β€” one where the left side is a __type_identity_t< basic_string_view< _CharT, _Traits > >, one where the right side is, and one where it's just two plain basic_string_views. the way that they covered every ordering possibility… obsessed, fr fr.

template<typename _CharT, typename _Traits> constexpr bool operator<=
    (__type_identity_t< basic_string_view< _CharT, _Traits > > __x,
    basic_string_view< _CharT, _Traits > __y) noexcept
template<typename _CharT, typename _Traits> constexpr bool operator<=
    (basic_string_view< _CharT, _Traits > __x, __type_identity_t<
    basic_string_view< _CharT, _Traits > > __y) noexcept
template<typename _CharT, typename _Traits> constexpr bool operator<=
    (basic_string_view< _CharT, _Traits > __x, basic_string_view<
    _CharT, _Traits > __y) noexcept

and then propagate_const comes through with its trio:

template<typename _Tp, typename _Up> constexpr bool operator<= (const
    _Tp &__t, const propagate_const< _Up > &__pu)
template<typename _Tp, typename _Up> constexpr bool operator<= (const
    propagate_const< _Tp > &__pt, const _Up &__u)
template<typename _Tp, typename _Up> constexpr bool operator<= (const
    propagate_const< _Tp > &__pt, const propagate_const< _Up > &__pu)

and then shared_ptr again, all three directions, plus the observer_ptr one:

template<typename _Tp> bool operator<= (const shared_ptr< _Tp > &__a,
    nullptr_t) noexcept
template<typename _Tp1, typename _Tp2> bool operator<= (const
    shared_ptr< _Tp1 > &__a, const shared_ptr< _Tp2 > &__b) noexcept
template<typename _Tp> bool operator<= (nullptr_t, const shared_ptr< _Tp
    > &__a) noexcept
template<typename _Tp, typename _Up> constexpr bool operator<=
    (observer_ptr< _Tp > __p1, observer_ptr< _Up > __p2)

πŸ¦‹ operator== πŸ¦‹

the equality section and it is LONG. this is the main character of comparison operators, ngl.

basic_string_view first, same three-flavour situation:

template<typename _CharT, typename _Traits> constexpr bool operator==
    (__type_identity_t< basic_string_view< _CharT, _Traits > > __x,
    basic_string_view< _CharT, _Traits > __y) noexcept
template<typename _CharT, typename _Traits> constexpr bool operator==
    (basic_string_view< _CharT, _Traits > __x, __type_identity_t<
    basic_string_view< _CharT, _Traits > > __y) noexcept
template<typename _CharT, typename _Traits> constexpr bool operator==
    (basic_string_view< _CharT, _Traits > __x, basic_string_view<
    _CharT, _Traits > __y) noexcept

propagate_const against a plain value, against another propagate_const, and the other way round:

template<typename _Tp, typename _Up> constexpr bool operator== (const
    _Tp &__t, const propagate_const< _Up > &__pu)
template<typename _Tp, typename _Up> constexpr bool operator== (const
    propagate_const< _Tp > &__pt, const _Up &__u)
template<typename _Tp, typename _Up> constexpr bool operator== (const
    propagate_const< _Tp > &__pt, const propagate_const< _Up > &__pu)

propagate_const versus nullptr_t (both orders), because of course:

template<typename _Tp> constexpr bool operator== (const propagate_const<
    _Tp > &__pt, nullptr_t)
template<typename _Tp> constexpr bool operator== (nullptr_t, const
    propagate_const< _Tp > &__pu)

then shared_ptr doing its three-way thing:

template<typename _Tp> bool operator== (const shared_ptr< _Tp > &__a,
    nullptr_t) noexcept
template<typename _Tp1, typename _Tp2> bool operator== (const
    shared_ptr< _Tp1 > &__a, const shared_ptr< _Tp2 > &__b) noexcept
template<typename _Tp> bool operator== (nullptr_t, const shared_ptr< _Tp
    > &__a) noexcept

and observer_ptr closing it out, nullptr_t on both sides plus two observer_ptrs going head to head:

template<typename _Tp> constexpr bool operator== (nullptr_t,
    observer_ptr< _Tp > __p) noexcept
template<typename _Tp> constexpr bool operator== (observer_ptr< _Tp >
    __p, nullptr_t) noexcept
template<typename _Tp, typename _Up> constexpr bool operator==
    (observer_ptr< _Tp > __p1, observer_ptr< _Up > __p2)

πŸŽ€ operator> πŸŽ€

yes bestie, it's the same pattern again but flipped. the standard library said "symmetry" and meant it. πŸ’€

basic_string_view, three flavours:

template<typename _CharT, typename _Traits> constexpr bool operator>
    (__type_identity_t< basic_string_view< _CharT, _Traits > > __x,
    basic_string_view< _CharT, _Traits > __y) noexcept
template<typename _CharT, typename _Traits> constexpr bool operator>
    (basic_string_view< _CharT, _Traits > __x, __type_identity_t<
    basic_string_view< _CharT, _Traits > > __y) noexcept
template<typename _CharT, typename _Traits> constexpr bool operator>
    (basic_string_view< _CharT, _Traits > __x, basic_string_view<
    _CharT, _Traits > __y) noexcept

propagate_const, three flavours:

template<typename _Tp, typename _Up> constexpr bool operator> (const _Tp
    &__t, const propagate_const< _Up > &__pu)
template<typename _Tp, typename _Up> constexpr bool operator> (const
    propagate_const< _Tp > &__pt, const _Up &__u)
template<typename _Tp, typename _Up> constexpr bool operator> (const
    propagate_const< _Tp > &__pt, const propagate_const< _Up > &__pu)

shared_ptr, three flavours:

template<typename _Tp> bool operator> (const shared_ptr< _Tp > &__a,
    nullptr_t) noexcept
template<typename _Tp1, typename _Tp2> bool operator> (const shared_ptr<
    _Tp1 > &__a, const shared_ptr< _Tp2 > &__b) noexcept
template<typename _Tp> bool operator> (nullptr_t, const shared_ptr< _Tp
    > &__a) noexcept

observer_ptr, the one and only:

template<typename _Tp, typename _Up> constexpr bool operator>
    (observer_ptr< _Tp > __p1, observer_ptr< _Up > __p2)

⭐ operator>= ⭐

last one of the comparison set, and it's giving grand finale. same energy, same coverage.

basic_string_view:

template<typename _CharT, typename _Traits> constexpr bool operator>=
    (__type_identity_t< basic_string_view< _CharT, _Traits > > __x,
    basic_string_view< _CharT, _Traits > __y) noexcept
template<typename _CharT, typename _Traits> constexpr bool operator>=
    (basic_string_view< _CharT, _Traits > __x, __type_identity_t<
    basic_string_view< _CharT, _Traits > > __y) noexcept
template<typename _CharT, typename _Traits> constexpr bool operator>=
    (basic_string_view< _CharT, _Traits > __x, basic_string_view<
    _CharT, _Traits > __y) noexcept

propagate_const:

template<typename _Tp, typename _Up> constexpr bool operator>= (const
    _Tp &__t, const propagate_const< _Up > &__pu)
template<typename _Tp, typename _Up> constexpr bool operator>= (const
    propagate_const< _Tp > &__pt, const _Up &__u)
template<typename _Tp, typename _Up> constexpr bool operator>= (const
    propagate_const< _Tp > &__pt, const propagate_const< _Up > &__pu)

shared_ptr:

template<typename _Tp> bool operator>= (const shared_ptr< _Tp > &__a,
    nullptr_t) noexcept
template<typename _Tp1, typename _Tp2> bool operator>= (const
    shared_ptr< _Tp1 > &__a, const shared_ptr< _Tp2 > &__b) noexcept
template<typename _Tp> bool operator>= (nullptr_t, const shared_ptr< _Tp
    > &__a) noexcept

observer_ptr:

template<typename _Tp, typename _Up> constexpr bool operator>=
    (observer_ptr< _Tp > __p1, observer_ptr< _Up > __p2)

🌸 random numbers, sampling & casting 🌸

we're out of comparison land, finally, and into utility territory. a random integer between __a and __b:

template<typename _IntType> _IntType randint (_IntType __a, _IntType
    __b)

a pointer cast that keeps the shared_ptr flavour:

template<typename _Tp, typename _Tp1> shared_ptr< _Tp >
    reinterpret_pointer_cast (const shared_ptr< _Tp1 > &__r) noexcept

and two reseed overloads β€” one that takes nothing, one that takes a default_random_engine::result_type __value:

void reseed ()
void reseed (default_random_engine::result_type __value)

then sample, twice. the first takes a population iterator pair, an output iterator and a distance; the second one also lets you hand it a _UniformRandomNumberGenerator &&__g:

template<typename _PopulationIterator, typename _SampleIterator,
    typename _Distance> _SampleIterator sample (_PopulationIterator
    __first, _PopulationIterator __last, _SampleIterator __out,
    _Distance __n)
    Take a random sample from a population.
template<typename _PopulationIterator, typename _SampleIterator,
    typename _Distance, typename _UniformRandomNumberGenerator>
    _SampleIterator sample (_PopulationIterator __first,
    _PopulationIterator __last, _SampleIterator __out, _Distance __n,
    _UniformRandomNumberGenerator &&__g)
    Take a random sample from a population.

search with a searcher object, and shuffle:

template<typename _ForwardIterator, typename _Searcher> _ForwardIterator
    search (_ForwardIterator __first, _ForwardIterator __last, const
    _Searcher &__searcher)
template<typename _RandomAccessIterator> void shuffle
    (_RandomAccessIterator __first, _RandomAccessIterator __last)

and static_pointer_cast, the sibling of that reinterpret_pointer_cast from earlier:

template<typename _Tp, typename _Tp1> shared_ptr< _Tp >
    static_pointer_cast (const shared_ptr< _Tp1 > &__r) noexcept

🧚 swap (and it's a whole family) 🧚

okay so swap shows up five times here and each one is for a different type. no, they did not consolidate them. yes, we're fine. πŸ’…

first, the any one β€” it exchanges the states of two any objects:

void swap (any &__x, any &__y) noexcept
    Exchange the states of two any objects.

then observer_ptr:

template<typename _Tp> constexpr void swap (observer_ptr< _Tp > &__p1,
    observer_ptr< _Tp > &__p2) noexcept

then the propagate_const one, which has a noexcept spec that depends on __is_nothrow_swappable< _Tp >::value and is gated behind __is_swappable< _Tp >::value:

template<typename _Tp> constexpr enable_if_t< __is_swappable< _Tp
    >::value, void > swap (propagate_const< _Tp > &__pt,
    propagate_const< _Tp > &__pt2) noexcept(__is_nothrow_swappable< _Tp
    >::value)

then shared_ptr and weak_ptr:

template<typename _Tp> void swap (shared_ptr< _Tp > &__a, shared_ptr<
    _Tp > &__b) noexcept
template<typename _Tp> void swap (weak_ptr< _Tp > &__a, weak_ptr< _Tp >
    &__b) noexcept

πŸ“ to_array πŸ“

one (1) function that creates a std::array from an array. love a concise king. it's constexpr, and its noexcept is is_nothrow_constructible< remove_cv_t< _Tp >, _Tp & >::value:

template<typename _Tp, size_t _Nm> constexpr array< remove_cv_t< _Tp >,
    _Nm > to_array (_Tp(&__a)[_Nm]) noexcept(is_nothrow_constructible<
    remove_cv_t< _Tp >, _Tp & >::value)
    Create a std::array from an array.

πŸ’œ any_cast πŸ’œ

and here's the any_cast block, which lives nested a little deeper in the synopsis. five overloads, and every single one of them has the exact same one-liner: access the contained object. the consistency? immaculate.

first, the plain lvalue one:

template<typename _ValueType> _ValueType any_cast (any &__any)
    Access the contained object.

then the two rvalue ones, which are the picky ones β€” one is enabled when _ValueType is not move constructible or is an lvalue reference, the other is enabled when it is move constructible and is not an lvalue reference. note those = true and = false defaults on the enable_if β€” those are doing heavy lifting:

template<typename _ValueType, typename
    enable_if<!is_move_constructible< _ValueType
    >::value||is_lvalue_reference< _ValueType >::value, bool >::type
    = true> _ValueType any_cast (any &&__any)
    Access the contained object.
template<typename _ValueType, typename enable_if<
    is_move_constructible< _ValueType >::value
    &&!is_lvalue_reference< _ValueType >::value, bool >::type =
    false> _ValueType any_cast (any &&__any)
    Access the contained object.

and then the pointer versions β€” one const, one not, both noexcept:

template<typename _ValueType> const _ValueType * any_cast (const any
    *__any) noexcept
    Access the contained object.
template<typename _ValueType> _ValueType * any_cast (any *__any)
    noexcept
    Access the contained object.

and bestie that's not even the end of this synopsis, so don't you dare close the tab yet. 🫢

✨ VARIABLES ✨

okay bestie, here's the whole variable squad πŸ’– some have little descriptions, some are just pure vibes. all signatures are exact, no cap.

  • template<typename _Yp, typename _Tp> constexpr bool __sp_compatible_v
  • template<typename _Tp, typename _Yp> constexpr bool __sp_is_constructible_v
  • constexpr in_place_t in_place β€” tag for in-place construction πŸ’…
  • template<typename _Tp> constexpr bool is_bind_expression_v β€” variable template for std::is_bind_expression ✨
  • template<typename _Tp> constexpr bool is_error_code_enum_v
  • template<typename _Tp> constexpr bool is_error_condition_enum_v
  • template<typename _Tp> constexpr int is_placeholder_v β€” variable template for std::is_placeholder 🫢
  • constexpr nullopt_t nullopt β€” tag to disengage optional objects (like saying "no thoughts, head empty" to an optional) 😭
  • template<typename _R1, typename _R2> constexpr bool ratio_equal_v
  • template<typename _R1, typename _R2> constexpr bool ratio_greater_equal_v
  • template<typename _R1, typename _R2> constexpr bool ratio_greater_v
  • template<typename _R1, typename _R2> constexpr bool ratio_less_equal_v
  • template<typename _R1, typename _R2> constexpr bool ratio_less_v
  • template<typename _R1, typename _R2> constexpr bool ratio_not_equal_v
  • template<typename _Tp> constexpr size_t tuple_size_v

and then there's the whole type-trait crew, all just vibing:

template<typename _Tp> constexpr bool is_void_v
template<typename _Tp> constexpr bool is_null_pointer_v
template<typename _Tp> constexpr bool is_integral_v
template<typename _Tp> constexpr bool is_floating_point_v
template<typename _Tp> constexpr bool is_array_v
template<typename _Tp> constexpr bool is_pointer_v
template<typename _Tp> constexpr bool is_lvalue_reference_v
template<typename _Tp> constexpr bool is_rvalue_reference_v
template<typename _Tp> constexpr bool is_member_object_pointer_v
template<typename _Tp> constexpr bool is_member_function_pointer_v
template<typename _Tp> constexpr bool is_enum_v
template<typename _Tp> constexpr bool is_union_v
template<typename _Tp> constexpr bool is_class_v
template<typename _Tp> constexpr bool is_function_v
template<typename _Tp> constexpr bool is_reference_v
template<typename _Tp> constexpr bool is_arithmetic_v
template<typename _Tp> constexpr bool is_fundamental_v
template<typename _Tp> constexpr bool is_object_v
template<typename _Tp> constexpr bool is_scalar_v
template<typename _Tp> constexpr bool is_compound_v
template<typename _Tp> constexpr bool is_member_pointer_v
template<typename _Tp> constexpr bool is_const_v
template<typename _Tp> constexpr bool is_volatile_v
template<typename _Tp> constexpr bool is_trivial_v
template<typename _Tp> constexpr bool is_trivially_copyable_v
template<typename _Tp> constexpr bool is_standard_layout_v
template<typename _Tp> constexpr bool is_pod_v
template<typename _Tp> constexpr bool is_literal_type_v
template<typename _Tp> constexpr bool is_empty_v
template<typename _Tp> constexpr bool is_polymorphic_v
template<typename _Tp> constexpr bool is_abstract_v
template<typename _Tp> constexpr bool is_final_v
template<typename _Tp> constexpr bool is_signed_v
template<typename _Tp> constexpr bool is_unsigned_v
template<typename _Tp, typename... _Args> constexpr bool is_constructible_v
template<typename _Tp> constexpr bool is_default_constructible_v
template<typename _Tp> constexpr bool is_copy_constructible_v
template<typename _Tp> constexpr bool is_move_constructible_v
template<typename _Tp, typename _Up> constexpr bool is_assignable_v
template<typename _Tp> constexpr bool is_copy_assignable_v
template<typename _Tp> constexpr bool is_move_assignable_v
template<typename _Tp> constexpr bool is_destructible_v
template<typename _Tp, typename... _Args> constexpr bool is_trivially_constructible_v
template<typename _Tp> constexpr bool is_trivially_default_constructible_v
template<typename _Tp> constexpr bool is_trivially_copy_constructible_v
template<typename _Tp> constexpr bool is_trivially_move_constructible_v
template<typename _Tp, typename _Up> constexpr bool is_trivially_assignable_v
template<typename _Tp> constexpr bool is_trivially_copy_assignable_v
template<typename _Tp> constexpr bool is_trivially_move_assignable_v
template<typename _Tp> constexpr bool is_trivially_destructible_v
template<typename _Tp, typename... _Args> constexpr bool is_nothrow_constructible_v
template<typename _Tp> constexpr bool is_nothrow_default_constructible_v
template<typename _Tp> constexpr bool is_nothrow_copy_constructible_v
template<typename _Tp> constexpr bool is_nothrow_move_constructible_v
template<typename _Tp, typename _Up> constexpr bool is_nothrow_assignable_v
template<typename _Tp> constexpr bool is_nothrow_copy_assignable_v
template<typename _Tp> constexpr bool is_nothrow_move_assignable_v
template<typename _Tp> constexpr bool is_nothrow_destructible_v
template<typename _Tp> constexpr bool has_virtual_destructor_v
template<typename _Tp> constexpr size_t alignment_of_v
template<typename _Tp> constexpr size_t rank_v
template<typename _Tp, unsigned _Idx = 0> constexpr size_t extent_v
template<typename _Tp, typename _Up> constexpr bool is_same_v
template<typename _Tp> constexpr bool is_same_v< _Tp, _Tp >
template<typename _Base, typename _Derived> constexpr bool is_base_of_v
template<typename _From, typename _To> constexpr bool is_convertible_v
template<typename... _Bn> constexpr bool conjunction_v
template<typename... _Bn> constexpr bool disjunction_v
template<typename _Pp> constexpr bool negation_v

then the metafunction besties:

  • template<typename...> using void_t β€” a metafunction that always yields void, used for detecting valid types (iykyk) πŸ’–
  • template<typename _Default, template< typename... > class _Op, typename... _Args> using detected_or β€” a metafunction that always yields void, used for detecting valid types πŸ¦‹
  • template<typename _Default, template< typename... > class _Op, typename... _Args> using detected_or_t β€” a metafunction that always yields void, used for detecting valid types ✨
  • template<template< typename... > class _Op, typename... _Args> using detected_t β€” a metafunction that always yields void, used for detecting valid types 🌸
  • template<template< typename... > class _Op, typename... _Args> using is_detected β€” a metafunction that always yields void, used for detecting valid types πŸ’…
  • template<typename _Expected, template< typename... > class _Op, typename... _Args> using is_detected_exact β€” a metafunction that always yields void, used for detecting valid types 🫢
  • template<typename _To, template< typename... > class _Op, typename... _Args> using is_detected_convertible β€” a metafunction that always yields void, used for detecting valid types 😭
  • template<template< typename... > class _Op, typename... _Args> constexpr bool is_detected_v β€” a metafunction that always yields void, used for detecting valid types πŸ”₯
  • template<typename _Expected, template< typename... > class _Op, typename... _Args> constexpr bool is_detected_exact_v β€” a metafunction that always yields void, used for detecting valid types πŸ‘‘
  • template<typename _To, template< typename... > class _Op, typename... _Args> constexpr bool is_detected_convertible_v β€” a metafunction that always yields void, used for detecting valid types 🌈

✨ DETAILED DESCRIPTION ✨

so basically, this is the namespace for all the features defined in ISO Technical Specifications. it's giving experimental, bestie πŸ’–


✨ FUNCTION DOCUMENTATION ✨

✨ gcd ✨

template<typename _Mn, typename _Nn> common_type_t< _Mn, _Nn >
std::experimental::fundamentals_v2::gcd (_Mn __m, _Nn __n) [constexpr], [noexcept]

greatest common divisor. the math bestie we all need πŸ’…

✨ get_deleter ✨

template<typename _Del, typename _Tp> _Del *
std::experimental::fundamentals_v2::get_deleter (const shared_ptr< _Tp > & __p) [inline], [noexcept]

C++14 20.8.2.2.10. yeah, that's the reference, no cap 🫢

✨ lcm ✨

template<typename _Mn, typename _Nn> common_type_t< _Mn, _Nn >
std::experimental::fundamentals_v2::lcm (_Mn __m, _Nn __n) [constexpr]

least common multiple. the other half of the math duo ✨

✨ make_boyer_moore_horspool_searcher ✨

template<typename _RAIter, typename _Hash = std::hash<typename std::iterator_traits<_RAIter>::value_type>, typename _BinaryPredicate = equal_to<>> boyer_moore_horspool_searcher< _RAIter, _Hash, _BinaryPredicate >
std::experimental::fundamentals_v1::make_boyer_moore_horspool_searcher (_RAIter __pat_first, _RAIter __pat_last, _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate()) [inline]

generator function for boyer_moore_horspool_searcher. it references std::move() πŸ’–

✨ make_boyer_moore_searcher ✨

template<typename _RAIter, typename _Hash = std::hash<typename std::iterator_traits<_RAIter>::value_type>, typename _BinaryPredicate = equal_to<>> boyer_moore_searcher< _RAIter, _Hash, _BinaryPredicate >
std::experimental::fundamentals_v1::make_boyer_moore_searcher (_RAIter __pat_first, _RAIter __pat_last, _Hash __hf = _Hash(), _BinaryPredicate __pred = _BinaryPredicate()) [inline]

generator function for boyer_moore_searcher. also references std::move() πŸ¦‹

✨ make_default_searcher ✨

template<typename _ForwardIterator, typename _BinaryPredicate = std::equal_to<>> default_searcher< _ForwardIterator, _BinaryPredicate >
std::experimental::fundamentals_v1::make_default_searcher (_ForwardIterator __pat_first, _ForwardIterator __pat_last, _BinaryPredicate __pred = _BinaryPredicate()) [inline]

generator function for default_searcher. simple, iconic 🌸

✨ make_ostream_joiner ✨

template<typename _CharT, typename _Traits, typename _DelimT> ostream_joiner< decay_t< _DelimT >, _CharT, _Traits >
std::experimental::fundamentals_v2::make_ostream_joiner (basic_ostream< _CharT, _Traits > & __os, _DelimT && __delimiter) [inline]

object generator for ostream_joiner. it references std::forward() πŸ’…

✨ not_fn ✨

template<typename _Fn> auto std::experimental::fundamentals_v2::not_fn (_Fn && __fn) [inline], [noexcept]

[func.not_fn] function template not_fn. it references std::forward() 🫢

✨ sample ✨

template<typename _PopulationIterator, typename _SampleIterator, typename _Distance, typename _UniformRandomNumberGenerator> _SampleIterator
std::experimental::fundamentals_v2::sample (_PopulationIterator __first, _PopulationIterator __last, _SampleIterator __out, _Distance __n, _UniformRandomNumberGenerator && __g)

take a random sample from a population. it references std::forward() 😭


✨ VARIABLE DOCUMENTATION ✨

✨ is_bind_expression_v ✨

template<typename _Tp> bool
std::experimental::fundamentals_v1::is_bind_expression_v [constexpr]

variable template for std::is_bind_expression. it's giving bind expression energy πŸ”₯

✨ is_placeholder_v ✨

template<typename _Tp> int
std::experimental::fundamentals_v1::is_placeholder_v [constexpr]

variable template for std::is_placeholder. the placeholder vibe check πŸ‘‘


✨ AUTHOR ✨

this page was generated automatically by Doxygen for libstdc++ from the source code. slay πŸ’…


and that's the tea! this page comes from libstdc++, for std::experimental(3). no date given, but you know it's fresh. bye bestie! πŸ’–βœ¨πŸŒˆ

πŸ“¦ where this page comes from
  • arch rolling: gcc 16.2.1+r23+gd564253eb6c8-1 Β· GPL-3.0-or-later WITH GCC-exception-3.1 AND GFDL-1.3-or-later
  • fedora 44: libstdc++-docs 16.2.1-2.fc44
  • fedora 44: libstdc++-docs 16.2.1-3.fc44 Β· GPL-3.0-or-later AND LGPL-3.0-or-later AND (GPL-3.0-or-later WITH GCC-exception-3.1) AND (GPL-3.0-or-later WITH Texinfo-exception) AND (LGPL-2.1-or-later WITH GCC-exception-2.0) AND (GPL-2.0-or-later WITH GCC-exception-2.0) AND (GPL-2.0-or-later WITH GNU-compiler-exception) AND BSL-1.0 AND GFDL-1.3-or-later AND Linux-man-pages-copyleft-2-para AND SunPro AND BSD-1-Clause AND BSD-2-Clause AND BSD-2-Clause-Views AND BSD-3-Clause AND BSD-4-Clause AND BSD-Source-Code AND Zlib AND MIT AND Apache-2.0 AND (Apache-2.0 WITH LLVM-Exception) AND ZPL-2.1 AND ISC AND LicenseRef-Fedora-Public-Domain AND HP-1986 AND curl AND Martin-Birgmeier AND HPND-Markus-Kuhn AND dtoa AND SMLNJ AND AMD-newlib AND OAR AND HPND-merchantability-variant AND HPND-Intel
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms