diff --git a/src/content/docs/cpp/library/ranges.mdx b/src/content/docs/cpp/library/ranges.mdx
new file mode 100644
index 0000000..546b14c
--- /dev/null
+++ b/src/content/docs/cpp/library/ranges.mdx
@@ -0,0 +1,763 @@
+---
+title: "Ranges library (since C++20)"
+cppref-url: "http://en.cppreference.com/w/cpp/ranges.html"
+---
+
+import { CppHeader, DR, DRList, Desc, DescList, DocLink, Revision, WG21PaperLink } from '@components/index';
+
+The ranges library is an extension and generalization of the algorithms and iterator libraries that makes them more powerful by making them composable and less error-prone.
+
+The library creates and manipulates range *views*, lightweight objects that indirectly represent iterable sequences (*ranges*). Ranges are an abstraction on top of
+
+* `[begin, end)` – iterator pairs, e.g. ranges made by implicit conversion from containers. All algorithms that take iterator pairs now have overloads that accept ranges (e.g. `ranges::sort`)
+* begin `+` `[0,` size`)` – counted sequences, e.g. range returned by `views::counted`
+* `[begin,` *predicate*`)` – conditionally-terminated sequences, e.g. range returned by `views::take_while`
+* `[begin, ..)` – unbounded sequences, e.g. range returned by `views::iota`
+
+The ranges library includes range algorithms, which are applied to ranges eagerly, and [range adaptors](#Range_adaptors), which are applied to views lazily. Adaptors can be composed into pipelines, so that their actions take place as the view is iterated.
+
+```cpp
+namespace std {
+ namespace views = ranges::views;
+}
+```
+
+The namespace alias `std::views` is provided as a shorthand for `std::ranges::views`.
+
+##### Defined in namespace `std::ranges`
+
+### Range access
+
+##### Defined in header
+##### Defined in header
+
+
+
+ `ranges::begin` :badge[C++20]
+ returns an iterator to the beginning of a range
+ (customization point object)
+
+
+ `ranges::end` :badge[C++20]
+ returns a sentinel indicating the end of a range
+ (customization point object)
+
+
+ `ranges::cbegin` :badge[C++20]
+ returns an iterator to the beginning of a read-only range
+ (customization point object)
+
+
+ `ranges::cend` :badge[C++20]
+ returns a sentinel indicating the end of a read-only range
+ (customization point object)
+
+
+ `ranges::rbegin` :badge[C++20]
+ returns a reverse iterator to a range
+ (customization point object)
+
+
+ `ranges::rend` :badge[C++20]
+ returns a reverse end iterator to a range
+ (customization point object)
+
+
+ `ranges::crbegin` :badge[C++20]
+ returns a reverse iterator to a read-only range
+ (customization point object)
+
+
+ `ranges::crend` :badge[C++20]
+ returns a reverse end iterator to a read-only range
+ (customization point object)
+
+
+ `ranges::reserve_hint` :badge[C++26]
+ returns an integer equal to the reserve hint given by a range
+ (customization point object)
+
+
+ `ranges::size` :badge[C++20]
+ returns an integer equal to the size of a range
+ (customization point object)
+
+
+ `ranges::ssize` :badge[C++20]
+ returns a signed integer equal to the size of a range
+ (customization point object)
+
+
+ `ranges::empty` :badge[C++20]
+ checks whether a range is empty
+ (customization point object)
+
+
+ `ranges::data` :badge[C++20]
+ obtains a pointer to the beginning of a contiguous range
+ (customization point object)
+
+
+ `ranges::cdata` :badge[C++20]
+ obtains a pointer to the beginning of a read-only contiguous range
+ (customization point object)
+
+
+
+### Range primitives
+
+##### Defined in header
+
+
+
+ `ranges::iterator_t` `ranges::const_iterator_t` `ranges::sentinel_t` `ranges::const_sentinel_t`
+ obtains iterator and sentinel types of a range
+ (alias template)
+
+
+ `ranges::range_difference_t` `ranges::range_size_t` `ranges::range_value_t`
+ obtains size, difference, and value types of a range
+ (alias template)
+
+
+ `ranges::range_reference_t` `ranges::range_const_reference_t` `ranges::range_rvalue_reference_t` `ranges::range_common_reference_t`
+ obtains reference types of a range
+ (alias template)
+
+
+
+### Dangling iterator handling
+
+##### Defined in header
+
+
+
+ `ranges::dangling`
+ a placeholder type indicating that an iterator or a `subrange` should not be returned since it would be dangling
+ (class)
+
+
+ `ranges::borrowed_iterator_t` `ranges::borrowed_subrange_t`
+ obtains iterator type or `subrange` type of a `borrowed_range`
+ (alias template)
+
+
+
+### Other utilities
+
+##### Defined in header
+
+
+
+ `ranges::elements_of`
+ tags a range to be treated as a sequence rather than a single value
+ (class template)
+
+
+
+### Range concepts
+
+##### Defined in header
+
+
+
+ `ranges::range`
+ specifies that a type is a range, that is, it provides a `begin` iterator and an `end` sentinel
+ (concept)
+
+
+ `ranges::borrowed_range`
+ specifies that a type is a `range` and iterators obtained from an expression of it can be safely returned without danger of dangling
+ (concept)
+
+
+ `ranges::approximately_sized_range`
+ specifies that a range can estimate its size in constant time
+ (concept)
+
+
+ `ranges::sized_range`
+ specifies that a range knows its size in constant time
+ (concept)
+
+
+ `ranges::view`
+ specifies that a range is a view, that is, it has constant time copy/move/assignment
+ (concept)
+
+
+ `ranges::input_range`
+ specifies a range whose iterator type satisfies `input_iterator`
+ (concept)
+
+
+ `ranges::output_range`
+ specifies a range whose iterator type satisfies `output_iterator`
+ (concept)
+
+
+ `ranges::forward_range`
+ specifies a range whose iterator type satisfies `forward_iterator`
+ (concept)
+
+
+ `ranges::bidirectional_range`
+ specifies a range whose iterator type satisfies `bidirectional_iterator`
+ (concept)
+
+
+ `ranges::random_access_range`
+ specifies a range whose iterator type satisfies `random_access_iterator`
+ (concept)
+
+
+ `ranges::contiguous_range`
+ specifies a range whose iterator type satisfies `contiguous_iterator`
+ (concept)
+
+
+ `ranges::common_range`
+ specifies that a range has identical iterator and sentinel types
+ (concept)
+
+
+ `ranges::viewable_range`
+ specifies the requirements for a `range` to be safely convertible to a `view`
+ (concept)
+
+
+ `ranges::constant_range`
+ specifies that a range has read-only elements
+ (concept)
+
+
+
+### Range conversions
+
+##### Defined in header
+
+
+
+ `ranges::to`
+ constructs a new non-view object from an input range
+ (function template)
+
+
+
+### Views
+
+##### Defined in header
+
+
+
+ `ranges::view_interface`
+ helper class template for defining a `view`, using the curiously recurring template pattern
+ (class template)
+
+
+ `ranges::subrange`
+ combines an iterator-sentinel pair into a `view`
+ (class template)
+
+
+
+### Range factories
+
+##### Defined in header
+##### Defined in namespace `std::ranges`
+
+
+
+ `ranges::empty_view` `views::empty`
+ an empty `view` with no elements
+ (class template) (variable template)
+
+
+ `ranges::single_view` `views::single`
+ a `view` that contains a single element of a specified value
+ (class template) (customization point object)
+
+
+ `ranges::iota_view` `views::iota`
+ a `view` consisting of a sequence generated by repeatedly incrementing an initial value
+ (class template) (customization point object)
+
+
+ `ranges::repeat_view` `views::repeat`
+ a `view` consisting of a generated sequence by repeatedly producing the same value
+ (class template) (customization point object)
+
+
+ `ranges::basic_istream_view` `views::istream`
+ a `view` consisting of the elements obtained by successive application of `operator>>` on the associated input stream
+ (class template) (customization point object)
+
+
+
+### Range adaptors
+
+##### Defined in header
+##### Defined in namespace `std::ranges`
+
+
+
+ `ranges::range_adaptor_closure`
+ helper base class template for defining a range adaptor closure object
+ (class template)
+
+
+ `views::all_t` `views::all`
+ a `view` that includes all elements of a `range`
+ (alias template) (range adaptor object)
+
+
+ `ranges::ref_view`
+ a `view` of the elements of some other `range`
+ (class template)
+
+
+ `ranges::owning_view`
+ a `view` with unique ownership of some `range`
+ (class template)
+
+
+ `ranges::as_rvalue_view` `views::as_rvalue`
+ a `view` of a sequence that casts each element to an rvalue
+ (class template) (range adaptor object)
+
+
+ `ranges::filter_view` `views::filter`
+ a `view` that consists of the elements of a `range` that satisfies a predicate
+ (class template) (range adaptor object)
+
+
+ `ranges::transform_view` `views::transform`
+ a `view` of a sequence that applies a transformation function to each element
+ (class template) (range adaptor object)
+
+
+ `ranges::take_view` `views::take`
+ a `view` consisting of the first N elements of another `view`
+ (class template) (range adaptor object)
+
+
+ `ranges::take_while_view` `views::take_while`
+ a `view` consisting of the initial elements of another `view`, until the first element on which a predicate returns `false`
+ (class template) (range adaptor object)
+
+
+ `ranges::drop_view` `views::drop`
+ a `view` consisting of elements of another `view`, skipping the first N elements
+ (class template) (range adaptor object)
+
+
+ `ranges::drop_while_view` `views::drop_while`
+ a `view` consisting of the elements of another `view`, skipping the initial subsequence of elements until the first element where the predicate returns `false`
+ (class template) (range adaptor object)
+
+
+ `ranges::join_view` `views::join`
+ a `view` consisting of the sequence obtained from flattening a `view` of `range`s
+ (class template) (range adaptor object)
+
+
+ `ranges::join_with_view` `views::join_with`
+ a `view` consisting of the sequence obtained from flattening a view of ranges, with the delimiter in between elements
+ (class template) (range adaptor object)
+
+
+ `ranges::lazy_split_view` `views::lazy_split`
+ a `view` over the subranges obtained from splitting another `view` using a delimiter
+ (class template) (range adaptor object)
+
+
+ `ranges::split_view` `views::split`
+ a `view` over the subranges obtained from splitting another `view` using a delimiter
+ (class template) (range adaptor object)
+
+
+ `ranges::concat_view` `views::concat`
+ a `view` consisting of concatenation of the adapted views
+ (class template) (customization point object)
+
+
+ `views::counted`
+ creates a subrange from an iterator and a count
+ (customization point object)
+
+
+ `ranges::common_view` `views::common`
+ converts a `view` into a `common_range`
+ (class template) (range adaptor object)
+
+
+ `ranges::reverse_view` `views::reverse`
+ a `view` that iterates over the elements of another bidirectional view in reverse order
+ (class template) (range adaptor object)
+
+
+ `ranges::as_const_view` `views::as_const`
+ converts a `view` into a `constant_range`
+ (class template) (range adaptor object)
+
+
+ `ranges::elements_view` `views::elements`
+ takes a `view` consisting of `tuple-like` values and a number N and produces a `view` of N`th` element of each tuple
+ (class template) (range adaptor object)
+
+
+ `ranges::keys_view` `views::keys`
+ takes a `view` consisting of pair-like values and produces a `view` of the first elements of each pair
+ (class template) (range adaptor object)
+
+
+ `ranges::values_view` `views::values`
+ takes a `view` consisting of pair-like values and produces a `view` of the second elements of each pair
+ (class template) (range adaptor object)
+
+
+ `ranges::enumerate_view` `views::enumerate`
+ a `view` that maps each element of adapted sequence to a tuple of both the element's position and its value
+ (class template) (range adaptor object)
+
+
+ `ranges::zip_view` `views::zip`
+ a `view` consisting of tuples of references to corresponding elements of the adapted views
+ (class template) (customization point object)
+
+
+ `ranges::zip_transform_view` `views::zip_transform`
+ a `view` consisting of results of application of a transformation function to corresponding elements of the adapted views
+ (class template) (customization point object)
+
+
+ `ranges::adjacent_view` `views::adjacent`
+ a `view` consisting of tuples of references to adjacent elements of the adapted view
+ (class template) (range adaptor object)
+
+
+ `ranges::adjacent_transform_view` `views::adjacent_transform`
+ a `view` consisting of results of application of a transformation function to adjacent elements of the adapted view
+ (class template) (range adaptor object)
+
+
+ `ranges::chunk_view` `views::chunk`
+ a range of `view`s that are `N`-sized non-overlapping successive chunks of the elements of another `view`
+ (class template) (range adaptor object)
+
+
+ `ranges::slide_view` `views::slide`
+ a `view` whose M`th` element is a `view` over the M`th` through (M + N - 1)`th` elements of another `view`
+ (class template) (range adaptor object)
+
+
+ `ranges::chunk_by_view` `views::chunk_by`
+ splits the `view` into subranges between each pair of adjacent elements for which the given predicate returns `false`
+ (class template) (range adaptor object)
+
+
+ `ranges::stride_view` `views::stride`
+ a `view` consisting of elements of another `view`, advancing over N elements at a time
+ (class template) (range adaptor object)
+
+
+ `ranges::cartesian_product_view` `views::cartesian_product`
+ a `view` consisting of tuples of results calculated by the n-ary cartesian product of the adapted views
+ (class template) (customization point object)
+
+
+ `ranges::cache_latest_view` `views::cache_latest`
+ a `view` that caches the last-accessed element of its underlying sequence
+ (class template) (range adaptor object)
+
+
+ `ranges::to_input_view` `views::to_input`
+ converts a `view` into a range that is `input_range`-only and non-`common_range`
+ (class template) (range adaptor object)
+
+
+
+### Range generators :badge[C++23]
+
+##### Defined in header
+##### Defined in namespace `std`
+
+
+
+ `generator`
+ A `view` that represents synchronous coroutine generator
+ (class template)
+
+
+
+### Helper items
+
+#### Range adaptor objects
+
+See `RangeAdaptorObject` (RAO).
+
+#### Range adaptor closure objects
+
+See `RangeAdaptorClosureObject` (RACO).
+
+#### Customization point objects
+
+See Customization point object (CPO).
+
+#### Assignable wrapper
+
+Some range adaptors wrap their elements or function objects with the `*copyable-box*``*movable-box*`. The wrapper augments the wrapped object with assignability when needed.
+
+#### Non-propagating cache
+
+Some range adaptors are specified in terms of an exposition-only class template `*non-propagating-cache*`, which behaves almost like `std::optional` (see description for differences).
+
+#### Conditionally-`const` type
+
+```cpp
+template< bool Const, class T >
+using /*maybe-const*/ = std::conditional_t;
+```
+The alias template `/*maybe-const*/` is a shorthand used to conditionally apply a `const` qualifier to the type `T`.
+
+#### Integer-like type helper templates
+
+```cpp
+template< /*is-integer-like*/ T >
+using /*make-signed-like-t*/ = /* see description */;
+```
+(1)
+```cpp
+template< /*is-integer-like*/ T >
+using /*make-unsigned-like-t*/ = /* see description */;
+```
+(2)
+```cpp
+template< /*is-integer-like*/ T >
+/*make-unsigned-like-t*/ /*to-unsigned-like*/( T t )
+{
+ return static_cast*make-unsigned-like-t*/>(t);
+}
+```
+(3)
+
+1. For an integer-like type `T`:
+ * If `T` is an integer type, `/*make-signed-like-t*/` is `std::make_signed_t`.
+ * Otherwise, `/*make-signed-like-t*/` is a corresponding unspecified signed-integer-like type of the same width as `T`.
+
+2. For an integer-like type `T`:
+ * If `T` is an integer type, `/*make-unsigned-like-t*/` is `std::make_unsigned_t`.
+ * Otherwise, `/*make-signed-like-t*/` is a corresponding unspecified unsigned-integer-like type of the same width as `T`.
+
+3. Explicitly converts `t` to `/*make-unsigned-like-t*/`.
+
+#### Customization point object helpers
+
+```cpp
+template< ranges::input_range R >
+constexpr auto& /*possibly-const-range*/(R& r) noexcept
+{
+ if constexpr (ranges::input_range)
+ return const_cast(r);
+ else
+ return r;
+}
+```
+(1)
+```cpp
+template< class T >
+constexpr auto /*as-const-pointer*/( const T* p ) noexcept
+{
+ return p;
+}
+```
+(2)
+
+Some range access customization point objects are specified in terms of these exposition-only function templates.
+
+1. `/*possibly-const-range*/` returns the const-qualified version of `r` if `const R` models `input_range`; otherwise, returns `r` without any casting.
+2. `/*as-const-pointer*/` returns a pointer to object of constant type.
+
+#### Range adaptor helpers
+
+```cpp
+template< class F, class Tuple >
+constexpr auto /*tuple-transform*/( F&& f, Tuple&& tuple )
+{
+ return std::apply([](Ts&&... args)
+ {
+ return std::tuple...>
+ (std::invoke(f, std::forward(args))...);
+ }, std::forward(tuple));
+}
+```
+(1)
+```cpp
+template< class F, class Tuple >
+constexpr void /*tuple-for-each*/( F&& f, Tuple&& tuple )
+{
+ std::apply([](Ts&&... args)
+ {
+ (static_cast(std::invoke(f, std::forward(args))), ...);
+ }, std::forward(tuple));
+}
+```
+(2)
+```cpp
+template< class T >
+constexpr T& /*as-lvalue*/( T&& t )
+{
+ return static_cast(t);
+}
+```
+(3)
+
+Some range adaptors are specified in terms of these exposition-only function templates.
+
+1. `/*tuple-transform*/` returns a new tuple constructed by applying `f` to each element of `tuple`.
+2. `/*tuple-for-each*/` applies `f` to each element of `tuple` and returns nothing.
+3. `/*as-lvalue*/` forwards rvalue `t` as lvalue.
+
+#### Helper concepts
+
+Following exposition-only concepts are used for several types, but they are not parts of the interface of standard library.
+
+```cpp
+template< class R >
+concept /*simple-view*/ =
+ ranges::view && ranges::range &&
+ std::same_as, ranges::iterator_t> &&
+ std::same_as, ranges::sentinel_t>;
+```
+(1)
+```cpp
+template< class I >
+concept /*has-arrow*/ =
+ ranges::input_iterator &&
+ (std::is_pointer_v || requires(const I i) { i.operator->(); });
+```
+(2)
+```cpp
+template< class T, class U >
+concept /*different-from*/ =
+ !std::same_as, std::remove_cvref_t>;
+```
+(3)
+```cpp
+template< class R >
+concept /*range-with-movable-references*/ =
+ ranges::input_range &&
+ std::move_constructible> &&
+ std::move_constructible>;
+```
+(4)
+```cpp
+template< bool C, class... Views >
+concept /*all-random-access*/ =
+ (ranges::random_access_range
+ > && ...);
+```
+(5)
+```cpp
+template< bool C, class... Views >
+concept /*all-bidirectional*/ =
+ (ranges::bidirectional_range
+ > && ...);
+```
+(6)
+```cpp
+template< bool C, class... Views >
+concept /*all-forward*/ =
+ (ranges::forward_range
+ > && ...);
+```
+(7)
+
+### Notes
+
+| Feature-test macro | Value | Std | Feature |
+| :----------------- | :---- | :-- | :------ |
+| `__cpp_lib_generator` | `202207L` | | `std::generator` – synchronous coroutine generator for ranges |
+| `__cpp_lib_ranges` | `201911L` | | Ranges library and constrained algorithms |
+| | `202106L` | (DR20) | Non-default-initializable views |
+| | `202110L` | (DR20) | Views with ownership |
+| | `202202L` | | `ranges::range_adaptor_closure` |
+| | `202207L` | | Relaxing [range adaptors](#Range_adaptors) to allow for move-only types |
+| | `202211L` | | Removing "poison pills" overloads in `ranges::begin` etc |
+| | `202302L` | | Relaxing ranges to allow certain projections |
+| | `202406L` | (DR20) | Removing the common reference requirement from the indirectly invocable concepts |
+| `__cpp_lib_ranges_as_const` | `202207L` | | `std::const_iterator`, `ranges::as_const_view` |
+| `__cpp_lib_ranges_as_rvalue` | `202207L` | | `ranges::as_rvalue_view` |
+| `__cpp_lib_ranges_cache_latest` | `202411L` | | `ranges::cache_latest_view` |
+| `__cpp_lib_ranges_cartesian_product` | `202207L` | | `ranges::cartesian_product_view` |
+| `__cpp_lib_ranges_chunk` | `202202L` | | `ranges::chunk_view` |
+| `__cpp_lib_ranges_chunk_by` | `202202L` | | `ranges::chunk_by_view` |
+| `__cpp_lib_ranges_concat` | `202403L` | | `ranges::concat_view` |
+| `__cpp_lib_ranges_enumerate` | `202302L` | | `ranges::enumerate_view` |
+| `__cpp_lib_ranges_join_with` | `202202L` | | `ranges::join_with_view` |
+| `__cpp_lib_ranges_repeat` | `202207L` | | `ranges::repeat_view` |
+| `__cpp_lib_ranges_reserve_hint` | `202502L` | | `ranges::reserve_hint` and `ranges::approximately_sized_range` |
+| `__cpp_lib_ranges_slide` | `202202L` | | `ranges::slide_view` |
+| `__cpp_lib_ranges_stride` | `202207L` | | `ranges::stride_view` |
+| `__cpp_lib_ranges_to_container` | `202202L` | | `ranges::to` |
+| `__cpp_lib_ranges_to_input` | `202502L` | | `ranges::to_input_view` |
+| `__cpp_lib_ranges_zip` | `202110L` | | `ranges::zip_view`,
`ranges::zip_transform_view`,
`ranges::adjacent_view`,
`ranges::adjacent_transform_view` |
+
+### Example
+
+```cpp
+#include
+#include
+
+int main()
+{
+ auto const ints = {0, 1, 2, 3, 4, 5};
+ auto even = [](int i) { return 0 == i % 2; };
+ auto square = [](int i) { return i * i; };
+
+ // the "pipe" syntax of composing the views:
+ for (int i : ints | std::views::filter(even) | std::views::transform(square))
+ std::cout << i << ' ';
+
+ std::cout << '\n';
+
+ // a traditional "functional" composing syntax:
+ for (int i : std::views::transform(std::views::filter(ints, even), square))
+ std::cout << i << ' ';
+}
+```
+
+Output:
+
+```text
+0 4 16
+0 4 16
+```
+
+### Defect reports
+
+The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
+
+
+
+ was unclear how range adaptor objects bound trailing arguments
+ they are bound by value
+
+
+ `*possibly-const-range*` and `*as-const-pointer*` were not declared `noexcept`
+ declared `noexcept`
+
+
+ `*possibly-const-range*` would not add const-qualification for ranges that has already modeled `constant_range`
+ adds const-qualification for such ranges
+
+
+ `*has-arrow*` did not require `i` to be const-qualified
+ requires
+
+
+
+### See also
+
+* Iterator library
+* Constrained algorithms