STD::SET(3cxx)
π std::set< _Key, _Compare, _Alloc > π
okay bestie, welcome to the std::set< _Key,...mpare, _Alloc >(3cxx) page β that's std::set, from section 3cxx of the manual, and she is that girl. grab a boba, sit criss-cross, we're talking unique keys and logarithmic time. no cap.
πΈ NAME πΈ
std::set< _Key, _Compare, _Alloc > β a standard container made up of unique keys, which can be retrieved in logarithmic time. it's giving VIP list where nobody gets in twice, and the bouncer checks your name in log n. iconic.
β¨ SYNOPSIS β¨
#include <set>
π Public Types π
the public typedefs, the whole squad π :
using insert_return_type = typename _Rep_type::insert_return_typeusing node_type = typename _Rep_type::node_typetypedef _Key key_typeβ Public typedefs.typedef _Key value_typeβ Public typedefs.typedef _Compare key_compareβ Public typedefs.typedef _Compare value_compareβ Public typedefs.typedef _Alloc allocator_typeβ Public typedefs.
and the iterator-related typedefs, literally all iterator-related π¦:
typedef _Alloc_traits::pointer pointerβ Iterator-related typedefs.typedef _Alloc_traits::const_pointer const_pointerβ Iterator-related typedefs.typedef _Alloc_traits::reference referenceβ Iterator-related typedefs.typedef _Alloc_traits::const_reference const_referenceβ Iterator-related typedefs.typedef _Rep_type::const_iterator iteratorβ Iterator-related typedefs.typedef _Rep_type::const_iterator const_iteratorβ Iterator-related typedefs.typedef _Rep_type::const_reverse_iterator reverse_iteratorβ Iterator-related typedefs.typedef _Rep_type::const_reverse_iterator const_reverse_iteratorβ Iterator-related typedefs.typedef _Rep_type::size_type size_typeβ Iterator-related typedefs.typedef _Rep_type::difference_type difference_typeβ Iterator-related typedefs.
note the lil moment: iterator and const_iterator are both _Rep_type::const_iterator, bestie. she said const era. π«Ά
π«Ά Public Member Functions π«Ά
the constructors first, because we love a grand entrance β¨:
set ()=defaultβ Default constructor creates no elements.template<typename _InputIterator > set (_InputIterator __first, _InputIterator __last)β Builds a set from a range.template<typename _InputIterator > set (_InputIterator __first, _InputIterator __last, const _Compare &__comp, const allocator_type &__a=allocator_type())β Builds a set from a range.template<typename _InputIterator > set (_InputIterator __first, _InputIterator __last, const allocator_type &__a)β Allocator-extended range constructor.set (const _Compare &__comp, const allocator_type &__a=allocator_type())β Creates a set with no elements.set (const allocator_type &__a)β Allocator-extended default constructor.set (const set &)=defaultβ Set copy constructor.set (const set &__x, const __type_identity_t< allocator_type > &__a)β Allocator-extended copy constructor.set (initializer_list< value_type > __l, const _Compare &__comp=_Compare(), const allocator_type &__a=allocator_type())β Builds a set from an initializer_list.set (initializer_list< value_type > __l, const allocator_type &__a)β Allocator-extended initialier-list constructor. (yes that's how it's spelled in the source, we don't fix, we respect π)set (set &&)=defaultβ Set move constructorset (set &&__x, const __type_identity_t< allocator_type > &__a) noexcept(is_nothrow_copy_constructible< _Compare >::value &&_Alloc_traits::_S_always_equal())β Allocator-extended move constructor.~set ()=default
then the observer / iterator girlies πΈ:
iterator begin () const noexceptiterator cbegin () const noexceptiterator cend () const noexceptvoid clear () noexceptreverse_iterator crbegin () const noexceptreverse_iterator crend () const noexceptbool empty () const noexceptβ Returns true if the set is empty.iterator end () const noexceptreverse_iterator rbegin () const noexceptreverse_iterator rend () const noexceptsize_type size () const noexceptβ Returns the size of the set.size_type max_size () const noexceptβ Returns the maximum size of the set.
erasing, extracting, and the emplace squad π₯:
size_type erase (const key_type &__x)β Erases elements according to the provided key._GLIBCXX_ABI_TAG_CXX11 iterator erase (const_iterator __first, const_iterator __last)β Erases a[__first,__last)range of elements from a set._GLIBCXX_ABI_TAG_CXX11 iterator erase (const_iterator __position)β Erases an element from a set.node_type extract (const key_type &__x)β Extract a node.node_type extract (const_iterator __pos)β Extract a node.allocator_type get_allocator () const noexceptβ Returns the allocator object with which the set was constructed.template<typename... _Args> std::pair< iterator, bool > emplace (_Args &&... __args)β Attempts to build and insert an element into the set.template<typename... _Args> iterator emplace_hint (const_iterator __pos, _Args &&... __args)β Attempts to insert an element into the set.
the insert era, she has so many fits π:
template<typename _InputIterator > void insert (_InputIterator __first, _InputIterator __last)β A template function that attempts to insert a range of elements.std::pair< iterator, bool > insert (const value_type &__x)β Attempts to insert an element into the set.iterator insert (const_iterator __hint, node_type &&__nh)β Re-insert an extracted node.iterator insert (const_iterator __position, const value_type &__x)β Attempts to insert an element into the set.iterator insert (const_iterator __position, value_type &&__x)void insert (initializer_list< value_type > __l)β Attempts to insert a list of elements into the set.insert_return_type insert (node_type &&__nh)β Re-insert an extracted node.std::pair< iterator, bool > insert (value_type &&__x)
comp, merge, assignment, swap π§:
key_compare key_comp () constβ Returns the comparison object with which the set was constructed.template<typename _Compare1 > void merge (multiset< _Key, _Compare1, _Alloc > &&__source)template<typename _Compare1 > void merge (multiset< _Key, _Compare1, _Alloc > &__source)template<typename _Compare1 > void merge (set< _Key, _Compare1, _Alloc > &&__source)template<typename _Compare1 > void merge (set< _Key, _Compare1, _Alloc > &__source)set & operator= (const set &)=defaultβ Set assignment operator.set & operator= (initializer_list< value_type > __l)β Set list assignment operator.set & operator= (set &&)=defaultβ Move assignment operator.void swap (set &__x) noexcept(/*conditional */)β Swaps data with another set.value_compare value_comp () constβ Returns the comparison object with which the set was constructed.
π the lookup girlies π
okay these ones are indented in the original so they get their own lil moment π:
size_type count (const key_type &__x) constβ Finds the number of elements.template<typename _Kt > auto count (const _Kt &__x) const -> decltype(_M_t._M_count_tr(__x))β Finds the number of elements.bool contains (const key_type &__x) constβ Finds whether an element with the given key exists.template<typename _Kt > auto contains (const _Kt &__x) const -> decltype(_M_t._M_find_tr(__x), void(), true)β Finds whether an element with the given key exists.iterator find (const key_type &__x)β Tries to locate an element in a set.const_iterator find (const key_type &__x) constβ Tries to locate an element in a set.template<typename _Kt > auto find (const _Kt &__x) -> decltype(iterator{_M_t._M_find_tr(__x)})β Tries to locate an element in a set.template<typename _Kt > auto find (const _Kt &__x) const -> decltype(const_iterator{_M_t._M_find_tr(__x)})β Tries to locate an element in a set.iterator lower_bound (const key_type &__x)β Finds the beginning of a subsequence matching given key.const_iterator lower_bound (const key_type &__x) constβ Finds the beginning of a subsequence matching given key.template<typename _Kt > auto lower_bound (const _Kt &__x) -> decltype(iterator(_M_t._M_lower_bound_tr(__x)))β Finds the beginning of a subsequence matching given key.template<typename _Kt > auto lower_bound (const _Kt &__x) const -> decltype(const_iterator(_M_t._M_lower_bound_tr(__x)))β Finds the beginning of a subsequence matching given key.iterator upper_bound (const key_type &__x)β Finds the end of a subsequence matching given key.const_iterator upper_bound (const key_type &__x) constβ Finds the end of a subsequence matching given key.template<typename _Kt > auto upper_bound (const _Kt &__x) -> decltype(iterator(_M_t._M_upper_bound_tr(__x)))β Finds the end of a subsequence matching given key.template<typename _Kt > auto upper_bound (const _Kt &__x) const -> decltype(iterator(_M_t._M_upper_bound_tr(__x)))β Finds the end of a subsequence matching given key.std::pair< iterator, iterator > equal_range (const key_type &__x)β Finds a subsequence matching given key.std::pair< const_iterator, const_iterator > equal_range (const key_type &__x) constβ Finds a subsequence matching given key.template<typename _Kt > auto equal_range (const _Kt &__x) -> decltype(pair< iterator, iterator >(_M_t._M_equal_range_tr(__x)))β Finds a subsequence matching given key.template<typename _Kt > auto equal_range (const _Kt &__x) const -> decltype(pair< iterator, iterator >(_M_t._M_equal_range_tr(__x)))β Finds a subsequence matching given key.
(and yes, those last upper_bound / equal_range decltypes literally say iterator in there, even on the const overloads β that's what the page says, so that's what we're serving. π)
π Friends π
template<typename _K1 , typename _C1 , typename _A1 > bool operator< (const set< _K1, _C1, _A1 > &, const set< _K1, _C1, _A1 > &)template<typename _K1 , typename _C1 , typename _A1 > bool operator== (const set< _K1, _C1, _A1 > &, const set< _K1, _C1, _A1 > &)template<typename , typename > struct std::_Rb_tree_merge_helper
π Detailed Description π
template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>>
class std::set< _Key, _Compare, _Alloc >
"A standard container made up of unique keys, which can be retrieved in logarithmic time."
Since: C++98 (an elder icon, honestly π)
Template Parameters:
_Keyβ Type of key objects._Compareβ Comparison function object type, defaults toless<_Key>._Allocβ Allocator type, defaults toallocator<_Key>.
Meets the requirements of a container, a reversible container, and an associative container (using unique keys). check, check, check β¨
Sets support bidirectional iterators. π¦
The private tree data is declared exactly the same way for set and multiset; the distinction is made entirely in how the tree functions are called (*_unique versus *_equal, same as the standard). like, same wig, different personality. π
π Member Typedef Documentation π
okay bestie, this is the whole nickname shelf β every typedef std::set hands you so you don't have to type out those cursed template params every single time. slay, honestly. π
allocator_type
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
typedef _Alloc std::set< _Key, _Compare, _Alloc >::allocator_type
Public typedefs. it's the allocator, living its best life, exactly what you passed in as _Alloc. β¨
const_iterator
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
typedef _Rep_type::const_iterator std::set< _Key, _Compare, _Alloc >::const_iterator
Iterator-related typedefs. the read-only iterator, straight from _Rep_type::const_iterator. π¦
const_pointer
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
typedef _Alloc_traits::const_pointer std::set< _Key, _Compare, _Alloc >::const_pointer
Iterator-related typedefs. pointer to const, via _Alloc_traits::const_pointer. no touching, no scribbling, we respect the vibe. π
const_reference
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
typedef _Alloc_traits::const_reference std::set< _Key, _Compare, _Alloc >::const_reference
Iterator-related typedefs. a reference-to-const, _Alloc_traits::const_reference. look, don't poke. πΈ
const_reverse_iterator
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
typedef _Rep_type::const_reverse_iterator std::set< _Key, _Compare, _Alloc >::const_reverse_iterator
Iterator-related typedefs. read-only, but backwards. main character energy in reverse. π₯
difference_type
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
typedef _Rep_type::difference_type std::set< _Key, _Compare, _Alloc >::difference_type
Iterator-related typedefs. for when you need to know "how far apart are these, bestie" β _Rep_type::difference_type. β
iterator
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
typedef _Rep_type::const_iterator std::set< _Key, _Compare, _Alloc >::iterator
Iterator-related typedefs. and yes β iterator here is literally _Rep_type::const_iterator. not a typo, not me being messy, it's exactly what the page says. sets are read-only like that. π
key_compare
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
typedef _Compare std::set< _Key, _Compare, _Alloc >::key_compare
Public typedefs. the comparator you handed in as _Compare. it's giving ordering authority. π
key_type
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
typedef _Key std::set< _Key, _Compare, _Alloc >::key_type
Public typedefs. it's _Key. that's the whole tweet. π«Ά
pointer
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
typedef _Alloc_traits::pointer std::set< _Key, _Compare, _Alloc >::pointer
Iterator-related typedefs. _Alloc_traits::pointer, fancy-pointer style. β¨
reference
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
typedef _Alloc_traits::reference std::set< _Key, _Compare, _Alloc >::reference
Iterator-related typedefs. _Alloc_traits::reference. π
reverse_iterator
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
typedef _Rep_type::const_reverse_iterator std::set< _Key, _Compare, _Alloc >::reverse_iterator
Iterator-related typedefs. same situation as iterator β this one's _Rep_type::const_reverse_iterator. so it's read-only too. iykyk. π¦
size_type
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
typedef _Rep_type::size_type std::set< _Key, _Compare, _Alloc >::size_type
Iterator-related typedefs. the number-y one, _Rep_type::size_type. π
value_compare
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
typedef _Compare std::set< _Key, _Compare, _Alloc >::value_compare
Public typedefs. also _Compare. yes, same as key_compare. no cap. π
value_type
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
typedef _Key std::set< _Key, _Compare, _Alloc >::value_type
Public typedefs. _Key again β because in a set the value is the key. iconic minimalism. π
πΈ Constructor & Destructor Documentation πΈ
we're building a set, bestie!! pick your builder. there are SO many. all of them cute, all of them valid. π
set () β default
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
std::set< _Key, _Compare, _Alloc >::set () [default]
Default constructor creates no elements. empty set, zero thoughts, head empty, vibes immaculate. π
set (const _Compare & __comp, const allocator_type & __a = allocator_type())
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
std::set< _Key, _Compare, _Alloc >::set (const _Compare & __comp, const allocator_type & __a = allocator_type()) [inline], [explicit]
Creates a set with no elements. note the [explicit] β no sneaky implicit conversions, she said what she said.
Parameters
__compβ Comparator to use.__aβ An allocator object.
set (_InputIterator __first, _InputIterator __last)
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
template<typename _InputIterator >
std::set< _Key, _Compare, _Alloc >::set (_InputIterator __first, _InputIterator __last) [inline]
Builds a set from a range. give her a [first, last) and she'll handle it. π«Ά
Parameters
__firstβ An input iterator.__lastβ An input iterator.
Create a set consisting of copies of the elements from [__first,__last). This is linear in N if the range is already sorted, and NlogN otherwise (where N is distance(__first,__last)).
sorted input = instant slay. unsorted input = NlogN, still slay, just with a little more effort. β¨
set (_InputIterator __first, _InputIterator __last, const _Compare & __comp, const allocator_type & __a = allocator_type())
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
template<typename _InputIterator >
std::set< _Key, _Compare, _Alloc >::set (_InputIterator __first, _InputIterator __last, const _Compare & __comp, const allocator_type & __a = allocator_type()) [inline]
Builds a set from a range β but this time you also get to choose the comparator and the allocator. customisation, we love her. π
Parameters
__firstβ An input iterator.__lastβ An input iterator.__compβ A comparison functor.__aβ An allocator object.
Create a set consisting of copies of the elements from [__first,__last). This is linear in N if the range is already sorted, and NlogN otherwise (where N is distance(__first,__last)).
set (const set< _Key, _Compare, _Alloc > &) β copy
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
std::set< _Key, _Compare, _Alloc >::set (const set< _Key, _Compare, _Alloc > &) [default]
Set copy constructor. Whether the allocator is copied depends on the allocator traits. so likeβ¦ read the traits, bestie, they decide. π
set (set< _Key, _Compare, _Alloc > &&) β move
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
std::set< _Key, _Compare, _Alloc >::set (set< _Key, _Compare, _Alloc > &&) [default]
Set move constructor. The newly-created set contains the exact contents of the moved instance. The moved instance is a valid, but unspecified, set.
β οΈ "valid, but unspecified" means exactly what it says β don't go reading the moved-from set and expecting anything specific. she's alive, she's just not answering questions. π
set (initializer_list< value_type > __l, const _Compare & __comp = _Compare(), const allocator_type & __a = allocator_type())
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
std::set< _Key, _Compare, _Alloc >::set (initializer_list< value_type > __l, const _Compare & __comp = _Compare(), const allocator_type & __a = allocator_type()) [inline]
Builds a set from an initializer_list. the curly-brace girlies stay winning. πΈ
Parameters
__lβ Aninitializer_list.__compβ A comparison functor.__aβ An allocator object.
Create a set consisting of copies of the elements in the list. This is linear in N if the list is already sorted, and NlogN otherwise (where N is __l.size()).
set (const allocator_type & __a) β allocator-extended default
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
std::set< _Key, _Compare, _Alloc >::set (const allocator_type & __a) [inline], [explicit]
Allocator-extended default constructor. [explicit], again with the no-nonsense energy. π
set (const set< _Key, _Compare, _Alloc > & __x, const __type_identity_t< allocator_type > & __a) β allocator-extended copy
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
std::set< _Key, _Compare, _Alloc >::set (const set< _Key, _Compare, _Alloc > & __x, const __type_identity_t<
allocator_type > & __a) [inline]
Allocator-extended copy constructor. yes the __type_identity_t< allocator_type > is doing a whole thing. it's a non-deduced context, she's just built like that. β¨
set (set< _Key, _Compare, _Alloc > && __x, const __type_identity_t< allocator_type > & __a) β allocator-extended move
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
std::set< _Key, _Compare, _Alloc >::set (set< _Key, _Compare, _Alloc > && __x, const __type_identity_t<
allocator_type > & __a) [inline], [noexcept]
Allocator-extended move constructor. and it's [noexcept] β zero drama, zero throwing. π
set (initializer_list< value_type > __l, const allocator_type & __a) β allocator-extended init-list
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
std::set< _Key, _Compare, _Alloc >::set (initializer_list< value_type > __l, const allocator_type & __a) [inline]
Allocator-extended initializer-list constructor. curly braces AND a custom allocator? we're spoiled. π
set (_InputIterator __first, _InputIterator __last, const allocator_type & __a) β allocator-extended range
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
template<typename _InputIterator >
std::set< _Key, _Compare, _Alloc >::set (_InputIterator __first, _InputIterator __last, const allocator_type & __a) [inline]
Allocator-extended range constructor. range in, allocator in, set out. π¦
~set () β destructor
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
std::set< _Key, _Compare, _Alloc >::~set () [default]
The dtor only erases the elements, and note that if the elements themselves are pointers, the pointed-to memory is not touched in any way. Managing the pointer is the user's responsibility.
π¨ real talk: pointers don't get deleted for you. that's on you. the set is not your mom, she's not cleaning up after you. π
π₯ Member Function Documentation π₯
now the actual functions. let's get into it. π
begin () const
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
iterator std::set< _Key, _Compare, _Alloc >::begin () const [inline], [noexcept]
Returns a read-only (constant) iterator that points to the first element in the set. Iteration is done in ascending order according to the keys. [inline], [noexcept] β she's fast and she's calm. β¨
cbegin () const
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
iterator std::set< _Key, _Compare, _Alloc >::cbegin () const [inline], [noexcept]
Returns a read-only (constant) iterator that points to the first element in the set. Iteration is done in ascending order according to the keys. same energy as begin(), just with the explicit "const" name for the girlies who like to be unambiguous. π
cend () const
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
iterator std::set< _Key, _Compare, _Alloc >::cend () const [inline], [noexcept]
Returns a read-only (constant) iterator that points one past the last element in the set. Iteration is done in ascending order according to the keys. classic "one past the end" β never dereference her, she's a boundary, not a baddie. π«Ά
clear ()
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
void std::set< _Key, _Compare, _Alloc >::clear () [inline], [noexcept]
Erases all elements in a set. Note that this function only erases the elements, and that if the elements themselves are pointers, the pointed-to memory is not touched in any way. Managing the pointer is the user's responsibility.
π¨ same warning, same seriousness:clear()is not adelete. pointers survive. you're still on cleanup duty.
contains (const _Kt & __x) const β the transparent one
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
template<typename _Kt >
auto std::set< _Key, _Compare, _Alloc >::contains (const _Kt & __x) const ->
decltype(_M_t._M_find_tr(__x), void(), true) [inline]
Finds whether an element with the given key exists. this is the transparent-comparator flavour, with that whole decltype(_M_t._M_find_tr(__x), void(), true) return type β she's fancy, she's SFINAE-ing, she's gatekeeping at compile time. π
Parameters
__xβ Key of elements to be located.
Returns
True if there is an element with the specified key.
contains (const key_type & __x) const
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
bool std::set< _Key, _Compare, _Alloc >::contains (const key_type & __x) const [inline]
Finds whether an element with the given key exists. the plain bool version, no template shenanigans, just a straight answer. π
Parameters
__xβ Key of elements to be located.
Returns
True if there is an element with the specified key.
count (const _Kt & __x) const
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>>
template<typename _Kt >
auto std::set< _Key, _Compare, _Alloc >::count (const _Kt & __x) const ->
decltype(_M_t._M_count_tr(__x)) [inline]
Finds the number of elements. πΈ
Parameters
__xβ Element to located.
Returns
Number of elements with specified key.
This function only makes sense for multisets; for set the result will either be 0 (not present) or 1 (present).
π so for a set the answer is literally always 0 or 1. she's not being difficult, she's just built different. if you wanted 2, you wanted a multiset, bestie.
π count
template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>>
size_type std::set<_Key, _Compare, _Alloc>::count(const key_type& __x) const [inline]
Finds the number of elements, bestie. That's the whole vibe. π
Parameters
__xβ the element you're trying to locate.
Returns
- the number of elements with that specified key.
ok so real talk: this function only makes sense formultisets. For a plain oldsetthe answer is literally either0(not present) or1(present). No in-between. It's giving binary. π¦
π crbegin
template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>>
reverse_iterator std::set<_Key, _Compare, _Alloc>::crbegin() const [inline], [noexcept]
Returns a read-only (constant) iterator that points to the last element in the set β and iteration is done in descending order according to the keys. So you're walking backwards through your set, respectfully. β¨
πΈ crend
template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>>
reverse_iterator std::set<_Key, _Compare, _Alloc>::crend() const [inline], [noexcept]
Returns a read-only (constant) reverse iterator that points to the last pair in the set. Iteration is done in descending order according to the keys. The reverse stroll ends here, icon. π«Ά
π₯ emplace
template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>>
template<typename... _Args>
std::pair<iterator, bool> std::set<_Key, _Compare, _Alloc>::emplace(_Args&&... __args) [inline]
Attempts to build and insert an element into the set. Constructing it in place, no copy energy required. π
Parameters
__argsβ the arguments used to generate an element.
Returns
- a
pair, where the first element is an iterator pointing to the possibly inserted element, and the second is aboolthat'strueif the element was actually inserted. So yeah, bestie, you gotta check the bool. π
So here's the tea: this function attempts to build and insert an element into the set. A set relies on unique keys, and thus an element is only inserted if it's not already present in the set. Duplicates? Not invited to this party. β
Insertion requires logarithmic time. β±οΈ
π emplace_hint
template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>>
template<typename... _Args>
iterator std::set<_Key, _Compare, _Alloc>::emplace_hint(const_iterator __pos, _Args&&... __args) [inline]
Attempts to insert an element into the set, but with a lil hint about where to put it. Considerate. π
Parameters
__posβ an iterator that serves as a hint as to where the element should be inserted.__argsβ the arguments used to generate the element to be inserted.
Returns
- an iterator that points to the element with key equivalent to the one generated from
__args(may or may not be the element itself).
This function is not concerned about whether the insertion took place, and thus does not return a boolean like the single-argument emplace() does. So don't come looking for your bool here, it's not that kind of function. π
Note that the first parameter is only a hint and can potentially improve the performance of the insertion process. A bad hint would cause no gains in efficiency. So a wrong hint isn't a disaster, it's justβ¦ not helpful. It's giving "thanks for trying". π
For more on hinting, see: https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
Insertion requires logarithmic time (if the hint is not taken). β±οΈ
π¦ empty
template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>>
bool std::set<_Key, _Compare, _Alloc>::empty() const [inline], [noexcept]
Returns true if the set is empty. Short, sweet, iconique. β¨
β end
template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>>
iterator std::set<_Key, _Compare, _Alloc>::end() const [inline], [noexcept]
Returns a read-only (constant) iterator that points one past the last element in the set. Iteration is done in ascending order according to the keys. The classic past-the-end moment, no cap. π
Referenced by std::set< _Key, _Compare, _Alloc >::extract().
π« equal_range (the _Kt one, non-const)
template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>>
template<typename _Kt>
auto std::set<_Key, _Compare, _Alloc>::equal_range(const _Kt& __x)
-> decltype(pair<iterator, iterator>(_M_t._M_equal_range_tr(__x))) [inline]
Finds a subsequence matching the given key. π
Parameters
__xβ the key to be located.
Returns
- a pair of iterators that possibly points to the subsequence matching the given key.
This function is equivalent to
std::make_pair(c.lower_bound(val),
c.upper_bound(val))
(but it's faster than making the calls separately β speed, she has it π ).
This function probably only makes sense for multisets.
π§ equal_range (the _Kt one, const)
template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>>
template<typename _Kt>
auto std::set<_Key, _Compare, _Alloc>::equal_range(const _Kt& __x) const
-> decltype(pair<iterator, iterator>(_M_t._M_equal_range_tr(__x))) [inline]
Finds a subsequence matching the given key, but make it const. π§
Parameters
__xβ the key to be located.
Returns
- a pair of iterators that possibly points to the subsequence matching the given key.
Equivalent to
std::make_pair(c.lower_bound(val),
c.upper_bound(val))
(but faster than making the calls separately).
Again: this function probably only makes sense for multisets.
π equal_range (key_type, non-const)
template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>>
std::pair<iterator, iterator> std::set<_Key, _Compare, _Alloc>::equal_range(const key_type& __x) [inline]
Finds a subsequence matching the given key. Same mission, different signature. π―
Parameters
__xβ the key to be located.
Returns
- a pair of iterators that possibly points to the subsequence matching the given key.
Equivalent to
std::make_pair(c.lower_bound(val),
c.upper_bound(val))
(but faster than making the calls separately).
Yep β this function probably only makes sense for multisets. We keep saying it because it keeps being true, bestie. π
π equal_range (key_type, const)
template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>>
std::pair<const_iterator, const_iterator> std::set<_Key, _Compare, _Alloc>::equal_range(const key_type& __x) const [inline]
Finds a subsequence matching the given key, read-only edition. π
Parameters
__xβ the key to be located.
Returns
- a pair of iterators that possibly points to the subsequence matching the given key.
Equivalent to
std::make_pair(c.lower_bound(val),
c.upper_bound(val))
(but faster than making the calls separately).
And once more, for the people in the back: this function probably only makes sense for multisets. π
π erase (by key)
template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>>
size_type std::set<_Key, _Compare, _Alloc>::erase(const key_type& __x) [inline]
Erases elements according to the provided key. Gone, deleted, unfollowed. βοΈ
Parameters
__xβ the key of the element to be erased.
Returns
- the number of elements erased.
This function erases all the elements located by the given key from a set.
β οΈ Note that this function only erases the element, and that if the element is itself a pointer, the pointed-to memory is not touched in any way. Managing the pointer is the user's responsibility. So likeβ¦ you own that memory. It's your child now. π«Ά
π erase (range)
template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>>
_GLIBCXX_ABI_TAG_CXX11 iterator std::set<_Key, _Compare, _Alloc>::erase(const_iterator __first, const_iterator __last) [inline]
Erases a [__first,__last) range of elements from a set. Bulk delete, we love efficiency. π₯
Parameters
__firstβ iterator pointing to the start of the range to be erased.__lastβ iterator pointing to the end of the range to be erased.
Returns
- the iterator
__last.
This function erases a sequence of elements from a set.
β οΈ Same caveat, same energy: this function only erases the element, and if the element is itself a pointer, the pointed-to memory is not touched in any way. Managing the pointer is the user's responsibility. No take-backs, no auto-cleanup. π
π erase (single position)
template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>>
_GLIBCXX_ABI_TAG_CXX11 iterator std::set<_Key, _Compare, _Alloc>::erase(const_iterator __position) [inline]
Erases a single element from a set. One at a time, very intentional. π―
Parameters
__positionβ an iterator pointing to the element to be erased.
Returns
- an iterator pointing to the element immediately following
__positionprior to the element being erased. If no such element exists,end()is returned.
This function erases an element, pointed to by the given iterator, from a set.
β οΈ You already know: this function only erases the element. If the element is itself a pointer, the pointed-to memory is not touched in any way. Managing the pointer is the user's responsibility. Periodt. π
π§ extract (by key)
template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>>
node_type std::set<_Key, _Compare, _Alloc>::extract(const key_type& __x) [inline]
Extract a node. That's it, that's the description. Short king. π
π¦ extract (by position)
template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>>
node_type std::set<_Key, _Compare, _Alloc>::extract(const_iterator __pos) [inline]
Extract a node. This one takes a position. β¨
References std::set< _Key, _Compare, _Alloc >::end().
π find (the _Kt one, non-const)
template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>>
template<typename _Kt>
auto std::set<_Key, _Compare, _Alloc>::find(const _Kt& __x)
-> decltype(iterator{_M_t._M_find_tr(__x)}) [inline]
Tries to locate an element in a set. Detective mode: activated. π
Parameters
__xβ the element to be located.
Returns
- an iterator pointing to the sought-after element, or
end()if it's not found.
This function takes a key and tries to locate the element with which the key matches. If successful, the function returns an iterator pointing to the sought-after element. If unsuccessful, it returns the past-the-end (end()) iterator. So likeβ¦ always check against end(), bestie. Always. π
π find (the _Kt one, const)
template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>>
template<typename _Kt>
auto std::set<_Key, _Compare, _Alloc>::find(const _Kt& __x) const
-> decltype(const_iterator{_M_t._M_find_tr(__x)}) [inline]
Tries to locate an element in a set, but const. The vibe check continues. π
Parameters
__xβ the element to be located.
Returns
- an iterator pointing to the sought-after element, or
end()if it's not found.
Same deal: takes a key, tries to locate the matching element. Success β iterator to the sought-after element. Failure β the past-the-end (end()) iterator. π
β find (key_type)
template<typename _Key, typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>>
iterator std::set<_Key, _Compare, _Alloc>::find(const key_type& __x) [inline]
Tries to locate an element in a set. The classic. The original. The main character. π
Parameters
__xβ the element to be located.
Returns
- an iterator pointing to the sought-after element, or
end()if it's not found.
This function takes a key and tries to locate the element with which the key matches. If successful the function returns an iterator pointing to the sought-after element. If unsuccessful it returns the past-the-end (end()) iterator. Same energy as the non-const version, just, like, not allowed to touch anything π
.
π«Ά get_allocator β hand me the allocator pls
template<typename _Key , typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>> allocator_type std::set< _Key, _Compare, _Alloc >::get_allocator () const [inline], [noexcept]
Returns the allocator object with which the set was constructed. That's it. That's the whole vibe. noexcept, she's chill π§.
β¨ insert β the range edition (yes there are SO many inserts)
template<typename _Key , typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>> template<typename _InputIterator > void std::set< _Key, _Compare, _Alloc >::insert (_InputIterator __first, _InputIterator __last) [inline]
A template function that attempts to insert a range of elements, bestie. Like bulk-adding to your playlist π.
__firstβ Iterator pointing to the start of the range to be inserted.__lastβ Iterator pointing to the end of the range.
Complexity similar to that of the range constructor (keep that in mind, it's literally the spec note).
πΈ insert β the single-element one, the icon
template<typename _Key , typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>> std::pair< iterator, bool > std::set< _Key, _Compare, _Alloc >::insert (const value_type & __x) [inline]
Attempts to insert an element into the set. This is the main character of the insert family π.
__xβ Element to be inserted.
Returns: a pair, of which the first element is an iterator that points to the possibly inserted element, and the second is a bool that is true if the element was actually inserted.
So like β this function attempts to insert an element into the set. A set relies on unique keys and thus an element is only inserted if it is not already present in the set. Dupes? Not on her watch. π«
Insertion requires logarithmic time.
References std::pair< _T1, _T2 >::first, and std::pair< _T1, _T2 >::second.
Referenced by std::set< _Key, _Compare, _Alloc >::insert().
π¦ insert β the hint + node combo
template<typename _Key , typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>> iterator std::set< _Key, _Compare, _Alloc >::insert (const_iterator __hint, node_type && __nh) [inline]
Re-insert an extracted node. That's the whole description, no notes, no extras β she said what she said π.
References std::move().
π insert β hint version, for the girlies who know where things go
template<typename _Key , typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>> iterator std::set< _Key, _Compare, _Alloc >::insert (const_iterator __position, const value_type & __x) [inline]
Attempts to insert an element into the set π«Ά.
__positionβ An iterator that serves as a hint as to where the element should be inserted.__xβ Element to be inserted.
Returns: an iterator that points to the element with key of __x (may or may not be the element passed in). Read that again, bestie β may or may not. π
This function is not concerned about whether the insertion took place, and thus does not return a boolean like the single-argument insert() does. Note that the first parameter is only a hint and can potentially improve the performance of the insertion process. A bad hint would cause no gains in efficiency. Lowkey a bad hint is just a wasted hint, ok.
For more on hinting, see: https://gcc.gnu.org/onlinedocs/libstdc++/manual/associative.html#containers.associative.insert_hints
Insertion requires logarithmic time (if the hint is not taken).
π insert β initializer_list, the ~aesthetic~ one
template<typename _Key , typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>> void std::set< _Key, _Compare, _Alloc >::insert (initializer_list< value_type > __l) [inline]
Attempts to insert a list of elements into the set β¨.
__lβ Astd::initializer_list<value_type>of elements to be inserted.
Complexity similar to that of the range constructor.
References std::set< _Key, _Compare, _Alloc >::insert().
π§ insert β node-only, the sequel
template<typename _Key , typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>> insert_return_type std::set< _Key, _Compare, _Alloc >::insert (node_type && __nh) [inline]
Re-insert an extracted node. Again. Same words, different return type, and that's genuinely all she wrote π.
References std::move().
β key_comp β the vibe-checker
template<typename _Key , typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>> key_compare std::set< _Key, _Compare, _Alloc >::key_comp () const [inline]
Returns the comparison object with which the set was constructed. You built her with a comparator, now you get to hold it. Iconic behaviour π .
π lower_bound β the templated non-const one
template<typename _Key , typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>> template<typename _Kt > auto std::set< _Key, _Compare, _Alloc >::lower_bound (const _Kt & __x) -> decltype(iterator(_M_t._M_lower_bound_tr(__x)))
[inline]
Finds the beginning of a subsequence matching given key.
__xβ Key to be located.
Returns: iterator pointing to first element equal to or greater than key, or end().
This function returns the first element of a subsequence of elements that matches the given key. If unsuccessful it returns an iterator pointing to the first element that has a greater value than given key or end() if no such element exists. She's giving "closest thing I could find" energy. π
π lower_bound β now const, because of course
template<typename _Key , typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>> template<typename _Kt > auto std::set< _Key, _Compare, _Alloc >::lower_bound (const _Kt & __x) const -> decltype(const_iterator(_M_t._M_lower_bound_tr(__x)))
[inline]
Finds the beginning of a subsequence matching given key.
__xβ Key to be located.
Returns: iterator pointing to first element equal to or greater than key, or end().
This function returns the first element of a subsequence of elements that matches the given key. If unsuccessful it returns an iterator pointing to the first element that has a greater value than given key or end() if no such element exists. Same deal, const_iterator flavoured π¦.
π― lower_bound β the plain non-template one
template<typename _Key , typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>> iterator std::set< _Key, _Compare, _Alloc >::lower_bound (const key_type & __x) [inline]
Finds the beginning of a subsequence matching given key.
__xβ Key to be located.
Returns: iterator pointing to first element equal to or greater than key, or end().
This function returns the first element of a subsequence of elements that matches the given key. If unsuccessful it returns an iterator pointing to the first element that has a greater value than given key or end() if no such element exists.
π― lower_bound β and her const twin
template<typename _Key , typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>> const_iterator std::set< _Key, _Compare, _Alloc >::lower_bound (const key_type & __x) const [inline]
Finds the beginning of a subsequence matching given key.
__xβ Key to be located.
Returns: iterator pointing to first element equal to or greater than key, or end().
This function returns the first element of a subsequence of elements that matches the given key. If unsuccessful it returns an iterator pointing to the first element that has a greater value than given key or end() if no such element exists. Yes, that's four lower_bounds. No, we're not skipping any. Periodt. π
π max_size β the ceiling
template<typename _Key , typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>> size_type std::set< _Key, _Compare, _Alloc >::max_size () const [inline], [noexcept]
Returns the maximum size of the set. That's it, she's noexcept and unbothered π§.
π operator= β copy assignment, but like, defaulted
template<typename _Key , typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>> set & std::set< _Key, _Compare, _Alloc >::operator= (const set< _Key, _Compare, _Alloc > &) [default]
Set assignment operator. Whether the allocator is copied depends on the allocator traits. Important caveat, don't skip it! π«Ά
π operator= β the initializer_list glow-up
template<typename _Key , typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>> set & std::set< _Key, _Compare, _Alloc >::operator= (initializer_list< value_type > __l) [inline]
Set list assignment operator πΈ.
__lβ Aninitializer_list.
This function fills a set with copies of the elements in the initializer list __l.
Note that the assignment completely changes the set and that the resulting set's size is the same as the number of elements assigned. Like, full reset. Old contents? Gone. π
π operator= β move assignment, the swift one
template<typename _Key , typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>> set & std::set< _Key, _Compare, _Alloc >::operator= (set< _Key, _Compare, _Alloc > &&) [default]
Move assignment operator. Short, sweet, defaulted π.
π¦ rbegin β going backwards, but make it const
template<typename _Key , typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>> reverse_iterator std::set< _Key, _Compare, _Alloc >::rbegin () const [inline], [noexcept]
Returns a read-only (constant) iterator that points to the last element in the set. Iteration is done in descending order according to the keys. Reading the group chat from the bottom, we love to see it. π
π¦ rend β the reverse finish line
template<typename _Key , typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>> reverse_iterator std::set< _Key, _Compare, _Alloc >::rend () const [inline], [noexcept]
Returns a read-only (constant) reverse iterator that points to the last pair in the set. Iteration is done in descending order according to the keys.
Ngl, the original literally says "the last pair" here even though sets aren't pairs β we're just relaying it word for word, bestie π.
β size β how many besties are in the set
template<typename _Key , typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>> size_type std::set< _Key, _Compare, _Alloc >::size () const [inline], [noexcept]
Returns the size of the set. Simple. Clean. noexcept. We stan π«Ά.
π swap β the trade
template<typename _Key , typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>> void std::set< _Key, _Compare, _Alloc >::swap (set< _Key, _Compare, _Alloc > & __x) [inline], [noexcept]
Swaps data with another set π₯.
__xβ A set of the same element and allocator types.
This exchanges the elements between two sets in constant time. (It is only swapping a pointer, an integer, and an instance of the Compare type (which itself is often stateless and empty), so it should be quite fast.) Note that the global std::swap() function is specialized such that std::swap(s1,s2) will feed to this function.
Whether the allocators are swapped depends on the allocator traits.
Constant time swap is genuinely so satisfying, like closing 40 tabs at once. β¨
π upper_bound β the templated one, so far
template<typename _Key , typename _Compare = std::less<_Key>, typename _Alloc = std::allocator<_Key>> template<typename _Kt > auto std::set< _Key, _Compare, _Alloc >::upper_bound (const _Kt & __x) -> decltype(iterator(_M_t._M_upper_bound_tr(__x)))
[inline]
Finds the end of a subsequence matching given key.
__xβ Key to be located.
Returns: iterator pointing to the first element greater than key, or end(). Note: greater than, not greater-or-equal β that's the lower_bound girlie's job π
.
upper_bound (the transparent, template one) π
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>> template<typename _Kt > auto std::set<
_Key, _Compare, _Alloc >::upper_bound (const _Kt & __x) const ->
decltype(iterator(_M_t._M_upper_bound_tr(__x)))
[inline]
Ok so this one is the transparent-comparator version β it takes a _Kt that doesn't have to be literally key_type, and it's const. It finds the end of a subsequence matching given key. iykyk π
Parameters
__xβ the key you're hunting for, bestie.
Returns
An iterator pointing to the first element greater than the key, or end(). That's the whole vibe: it's the "just past everything that matches" pointer. β¨
upper_bound (const key_type&, non-const) π
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>> iterator std::set< _Key, _Compare,
_Alloc >::upper_bound (const key_type & __x) [inline]
Same job, same energy, but it takes const key_type & __x and hands you back a plain iterator. It finds the end of a subsequence matching given key. π¦
Parameters
__xβ key to be located.
Returns
Iterator pointing to the first element greater than the key, or end(). Periodt. π
upper_bound (const key_type&, const) π
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>> const_iterator std::set< _Key, _Compare,
_Alloc >::upper_bound (const key_type & __x) const [inline]
The const sibling of the one above β takes const key_type & __x, gives you a const_iterator. Still out here finding the end of a subsequence matching given key. Iconic consistency, honestly. πΈ
Parameters
__xβ key to be located.
Returns
Iterator pointing to the first element greater than the key, or end().
π«Ά Friendly reminder of the trio: the_Ktone is the transparent/template overload, and the twokey_typeones differ only byconst-ness ofthisand whether you getiteratororconst_iterator.
value_comp π§
template<typename _Key , typename _Compare = std::less<_Key>, typename
_Alloc = std::allocator<_Key>> value_compare std::set< _Key, _Compare,
_Alloc >::value_comp () const [inline]
This one just returns the comparison object with which the set was constructed. No cap β it literally hands you back the value_compare your set was built with. Lowkey useful, highkey underrated. β
π Author π
Generated automatically by Doxygen for libstdc++ from the source code.
Likeβ¦ not a human, bestie. A tool. It read the source and wrote the docs for us and honestly? Slay. π
and that's the whole page, bestie!! π the little footer at the very bottom is just the page's source/version line and the date it was generated β the manpage equivalent of a timestamp on a group-chat screenshot. go forth and upper_bound responsibly. π¦ππ₯
π¦ where this page comes from
- ubuntu noble: libstdc++-14-doc 14-20240412-0ubuntu1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms