@@ -4,14 +4,26 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
44
55# beman.any_view: A generalized type-erased view with customizable properties
66
7- ![ Library Status] ( https://github. com/bemanproject/beman/blob/c6997986557ec6dda98acbdf502082cdf7335526 /images/badges/beman_badge-beman_library_under_development.svg )
7+ ![ Library Status] ( https://raw.githubusercontent. com/bemanproject/beman/refs/heads/main /images/badges/beman_badge-beman_library_under_development.svg )
88![ Continuous Integration Tests] ( https://github.com/bemanproject/any_view/actions/workflows/ci_tests.yml/badge.svg )
99![ Lint Check (pre-commit)] ( https://github.com/bemanproject/any_view/actions/workflows/pre-commit.yml/badge.svg )
1010
11- ** Implements** : ` std::ranges::any_view ` proposed in [ any_view (P3411R2)] ( https://huixie90.github.io/cpp_papers/generated/any_view ) .
11+ ** Implements** : ` std::ranges::any_view ` proposed in [ any_view (P3411R2)] ( https://wg21.link/p3411r2 ) .
1212
1313** Status** : [ Under development and not yet ready for production use.] ( https://github.com/bemanproject/beman/blob/main/docs/BEMAN_LIBRARY_MATURITY_MODEL.md#under-development-and-not-yet-ready-for-production-use )
1414
15+ ** Featured** : [ C++Now 2025] ( https://schedule.cppnow.org/wp-content/uploads/2025/03/A-View-for-Any-Occasion.pdf )
16+
17+ ## Motivation
18+
19+ ` any_view ` equips library APIs with the ability to declare function parameters and return types as views, while
20+ de-coupling the interface from an implementation that can fully leverage the power of C++20 ranges. By using
21+ type-erased views, the library can be compiled separately.
22+
23+ As a return type, ` any_view ` grants a library author the freedom to change how the function is implemented to return
24+ the view without modifying its interface. As a parameter type, it allows users to call the library function with any
25+ range as an argument that can be consumed directly, rather than copying it into some bespoke, library-specific type.
26+
1527## Usage
1628
1729``` cpp
@@ -64,10 +76,11 @@ For CMake based projects, you can include it as a dependency using the `FetchCon
6476include(FetchContent)
6577
6678FetchContent_Declare(
67- beman.any_view
68- GIT_REPOSITORY https://github.com/bemanproject/any_view.git
69- GIT_TAG main
70- EXCLUDE_FROM_ALL)
79+ beman.any_view
80+ GIT_REPOSITORY https://github.com/bemanproject/any_view.git
81+ GIT_TAG main
82+ EXCLUDE_FROM_ALL
83+ )
7184FetchContent_MakeAvailable(beman.any_view)
7285```
7386
@@ -88,6 +101,7 @@ target_link_libraries(yourlib PUBLIC beman::any_view)
88101``` cpp
89102namespace beman ::any_view {
90103
104+ // [ range.any]
91105enum class any_view_options {
92106 input = 0b00000001,
93107 forward = 0b00000011,
@@ -99,22 +113,24 @@ enum class any_view_options {
99113 copyable = 0b10000000,
100114};
101115
102- constexpr any_view_options operator|(any_view_options l, any_view_options r) noexcept;
103- constexpr any_view_options operator&(any_view_options l, any_view_options r) noexcept;
104- constexpr any_view_options operator^(any_view_options l, any_view_options r) noexcept;
116+ constexpr any_view_options operator|(any_view_options, any_view_options) noexcept;
117+ constexpr any_view_options operator&(any_view_options, any_view_options) noexcept;
105118
106- constexpr any_view_options operator~ (any_view_options o) noexcept;
119+ template <class T >
120+ struct /* rvalue-ref* / {
121+ using type = T;
122+ };
107123
108- constexpr any_view_options& operator|=(any_view_options& l, any_view_options r) noexcept;
109- constexpr any_view_options& operator&=(any_view_options& l, any_view_options r) noexcept;
110- constexpr any_view_options& operator^=(any_view_options& l, any_view_options r) noexcept;
124+ template <class T >
125+ struct /* rvalue-ref* /<T&> {
126+ using type = T&&;
127+ };
111128
112- template <class T > struct /* as-rvalue* / { using type = T; };
113- template <class T > struct /* as-rvalue* /<T&> { using type = T&&; };
114- template <class T > using /* as-rvalue-t* / = /* as-rvalue* /<T >::type;
129+ template <class T >
130+ using /* rvalue-ref-t* / = /* rvalue-ref* /<T >::type;
115131
116132template <class RangeT, class AnyViewT>
117- concept ext_any_compatible_viewable_range = /* see description * /;
133+ concept ext_any_compatible_viewable_range = /* ... * /;
118134
119135template <class ElementT,
120136 any_view_options OptsV = any_view_options::input,
@@ -125,30 +141,29 @@ class any_view : public std::ranges::view_interface<any_view<ElementT, OptsV, Re
125141 class iterator; // exposition-only
126142 class sentinel; // exposition-only
127143
128- using size_type = std::make_unsigned_t<DiffT>; // exposition-only
129-
130144 public:
145+ // [ range.any.ctor]
131146 template <class RangeT >
132- requires(not std::same_as< std::remove_cvref_t<RangeT > , any_view> and
133- ext_any_compatible_viewable_range<RangeT, any_view>)
134147 constexpr any_view(RangeT&& range);
135-
136- constexpr any_view(const any_view&)
137- requires(bool(OptsV & any_view_options::copyable));
138-
148+ constexpr any_view(const any_view&);
139149 constexpr any_view(any_view&&) noexcept;
140150
141- constexpr any_view& operator=(const any_view&)
142- requires(bool(OptsV & any_view_options::copyable));
143-
151+ constexpr any_view& operator=(const any_view&);
144152 constexpr any_view& operator=(any_view&&) noexcept;
145153
154+ constexpr ~any_view();
155+
156+ // [range.any.access]
146157 constexpr iterator begin();
147158
148159 constexpr sentinel end();
149160
150- constexpr size_type size() const
151- requires(bool(OptsV & any_view_options::sized));
161+ constexpr std::make_unsigned_t<DiffT> size() const;
162+
163+ // [range.any.swap]
164+ constexpr void swap(any_view&) noexcept;
165+
166+ constexpr friend void swap(any_view&, any_view&) noexcept;
152167};
153168
154169} // namespace beman::any_view
@@ -267,6 +282,74 @@ Total Test time (real) = 0.15 sec
267282
268283</details >
269284
285+ ## Performance
286+
287+ Various benchmarks are available to build and run using the CMake target ` beman.any_view.benchmarks ` .
288+
289+ <details >
290+ <summary >Example output comparing <code >reserved</code > to <code >fused</code > for <code >beman.any_view.benchmarks.all</code ></summary >
291+
292+ ``` text
293+ + cmake --build build --config Release --target beman.any_view.benchmarks.all
294+ [27/27] Linking CXX executable tests/beman/any_view/beman.any_view.benchmarks.all
295+ + build/_deps/benchmark-src/tools/compare.py benchmarksfiltered build/tests/beman/any_view/beman.any_view.benchmarks.all reserved build/tests/beman/any_view/beman.any_view.benchmarks.all fused
296+ RUNNING: build/tests/beman/any_view/beman.any_view.benchmarks.all --benchmark_filter=reserved
297+ Run on (32 X 2419.2 MHz CPU s)
298+ CPU Caches:
299+ L1 Data 48 KiB (x16)
300+ L1 Instruction 32 KiB (x16)
301+ L2 Unified 2048 KiB (x16)
302+ L3 Unified 36864 KiB (x1)
303+ Load Average: 0.25, 0.17, 0.11
304+ -----------------------------------------------------------------
305+ Benchmark Time CPU Iterations
306+ -----------------------------------------------------------------
307+ BM_all_reserved/1024 1783 ns 1783 ns 389936
308+ BM_all_reserved/2048 3839 ns 3839 ns 191729
309+ BM_all_reserved/4096 7067 ns 7067 ns 89826
310+ BM_all_reserved/8192 14756 ns 14756 ns 48245
311+ BM_all_reserved/16384 30317 ns 30317 ns 23191
312+ BM_all_reserved/32768 73651 ns 73650 ns 9626
313+ BM_all_reserved/65536 215342 ns 215341 ns 3413
314+ BM_all_reserved/131072 424794 ns 424793 ns 1654
315+ BM_all_reserved/262144 887833 ns 887828 ns 789
316+ RUNNING: build/tests/beman/any_view/beman.any_view.benchmarks.all --benchmark_filter=fused
317+ Run on (32 X 2419.2 MHz CPU s)
318+ CPU Caches:
319+ L1 Data 48 KiB (x16)
320+ L1 Instruction 32 KiB (x16)
321+ L2 Unified 2048 KiB (x16)
322+ L3 Unified 36864 KiB (x1)
323+ Load Average: 0.31, 0.19, 0.11
324+ --------------------------------------------------------------
325+ Benchmark Time CPU Iterations
326+ --------------------------------------------------------------
327+ BM_all_fused/1024 1660 ns 1660 ns 437469
328+ BM_all_fused/2048 3219 ns 3219 ns 210096
329+ BM_all_fused/4096 7100 ns 7100 ns 100823
330+ BM_all_fused/8192 15088 ns 15088 ns 45117
331+ BM_all_fused/16384 33719 ns 33719 ns 21827
332+ BM_all_fused/32768 72098 ns 72097 ns 9582
333+ BM_all_fused/65536 150699 ns 150698 ns 4629
334+ BM_all_fused/131072 316431 ns 316430 ns 2234
335+ BM_all_fused/262144 583499 ns 583500 ns 1091
336+ Comparing reserved (from build/tests/beman/any_view/beman.any_view.benchmarks.all) to fused (from build/tests/beman/any_view/beman.any_view.benchmarks.all)
337+ Benchmark Time CPU Time Old Time New CPU Old CPU New
338+ ---------------------------------------------------------------------------------------------------------------------------------
339+ BM_all_[reserved vs. fused]/1024 -0.0689 -0.0689 1783 1660 1783 1660
340+ BM_all_[reserved vs. fused]/2048 -0.1615 -0.1615 3839 3219 3839 3219
341+ BM_all_[reserved vs. fused]/4096 +0.0047 +0.0047 7067 7100 7067 7100
342+ BM_all_[reserved vs. fused]/8192 +0.0225 +0.0225 14756 15088 14756 15088
343+ BM_all_[reserved vs. fused]/16384 +0.1122 +0.1122 30317 33719 30317 33719
344+ BM_all_[reserved vs. fused]/32768 -0.0211 -0.0211 73651 72098 73650 72097
345+ BM_all_[reserved vs. fused]/65536 -0.3002 -0.3002 215342 150699 215341 150698
346+ BM_all_[reserved vs. fused]/131072 -0.2551 -0.2551 424794 316431 424793 316430
347+ BM_all_[reserved vs. fused]/262144 -0.3428 -0.3428 887833 583499 887828 583500
348+ OVERALL_GEOMEAN -0.1255 -0.1255
349+ ```
350+
351+ </details >
352+
270353## Contributing
271354
272355Please do! Issues and pull requests are appreciated.
0 commit comments