Skip to content

Commit

Permalink
Add more relevant example
Browse files Browse the repository at this point in the history
  • Loading branch information
neatudarius committed Sep 9, 2024
1 parent 84b4097 commit f7d0d26
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 2 deletions.
66 changes: 65 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,71 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

Implements: `std::identity` proposed in [Standard Library Concepts (P0898R3)](https://wg21.link/P0898R3).

## Building

## Usage

`std::identity` is a function object type whose `operator()` returns its argument unchanged. `std::identity` serves as the default projection in constrained algorithms. Its direct usage is usually not needed.

### Example: default projection in constrained algorithms

The following code snippet illustrates how we can achieve a default projection using `Beman::Example::identity`:


```cpp
#include <Beman/Example/identity.hpp>

// Class with a pair of values.
struct Pair
{
int n;
std::string s;

// Output the pair in the form {n, s}.
// Used by the range-printer if no custom projection is provided (default: identity projection).
friend std::ostream &operator<<(std::ostream &os, const Pair &p)
{
return os << "Pair" << '{' << p.n << ", " << p.s << '}';
}
};

// A range-printer that can print projected (modified) elements of a range.
// All the elements of the range are printed in the form {element1, element2, ...}.
// e.g., pairs with identity: Pair{1, one}, Pair{2, two}, Pair{3, three}
// e.g., pairs with custom projection: {1:one, 2:two, 3:three}
template <std::ranges::input_range R,
typename Projection>
void print(const std::string_view rem, R &&range, Projection projection = Beman::Example::identity>)
{
std::cout << rem << '{';
std::ranges::for_each(
range,
[O = 0](const auto &o) mutable
{ std::cout << (O++ ? ", " : "") << o; },
projection);
std::cout << "}\n";
};

int main()
{
// A vector of pairs to print.
const std::vector<Pair> pairs = {
{1, "one"},
{2, "two"},
{3, "three"},
};

// Print the pairs using the default projection.
std::cout << "Default projection:\n";
print("\tpairs with Beman: ", pairs);

return 0;
}

```
Full runable examples can be found in `examples/` (e.g., [./examples/Beman/Beman.Example/examples/identity_as_default_projection.cpp.cpp](./examples/Beman/Beman.Example/examples/identity_as_default_projection.cpp.cpp)).
## Building Beman.Example
### Dependencies
<!-- TODO Darius: rewrite section!-->
Expand Down
2 changes: 1 addition & 1 deletion examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

set(ALL_EXAMPLES identity_usage)
set(ALL_EXAMPLES identity_as_default_projection identity_direct_usage)

foreach(example ${ALL_EXAMPLES})
add_executable(${example} "")
Expand Down
87 changes: 87 additions & 0 deletions examples/identity_as_default_projection.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

// This example demonstrates the usage of Beman::Example::identity as a default projection in a range-printer.
// Requires: range support (C++20) and std::identity support (C++20).
// TODO Darius: Do we need to selectively compile this example?
// Or should we assume that this project is compiled with C++20 support only?

#include <Beman/Example/identity.hpp> // Beman::Example::identity

#include <algorithm>
#include <functional> // std::identity
#include <iostream>
#include <ranges>
#include <string>

// Class with a pair of values.
struct Pair
{
int n;
std::string s;

// Output the pair in the form {n, s}.
// Used by the range-printer if no custom projection is provided (default: identity projection).
friend std::ostream &operator<<(std::ostream &os, const Pair &p)
{
return os << "Pair" << '{' << p.n << ", " << p.s << '}';
}
};

// A range-printer that can print projected (modified) elements of a range.
// All the elements of the range are printed in the form {element1, element2, ...}.
// e.g., pairs with identity: Pair{1, one}, Pair{2, two}, Pair{3, three}
// e.g., pairs with custom projection: {1:one, 2:two, 3:three}
template <std::ranges::input_range R,
typename Projection>
void print_helper(const std::string_view rem, R &&range, Projection projection)
{
std::cout << rem << '{';
std::ranges::for_each(
range,
[O = 0](const auto &o) mutable
{ std::cout << (O++ ? ", " : "") << o; },
projection);
std::cout << "}\n";
};

// Print wrapper with Beman::Example::identity.
template <std::ranges::input_range R,
typename Projection = Beman::Example::identity> // <- Notice the default projection.
void print_beman(const std::string_view rem, R &&range, Projection projection = {})
{
print_helper(rem, range, projection);
}

// Print wrapper with std::identity.
template <std::ranges::input_range R,
typename Projection = std::identity> // <- Notice the default projection.
void print_std(const std::string_view rem, R &&range, Projection projection = {})
{
print_helper(rem, range, projection);
}

int main()
{
// A vector of pairs to print.
const std::vector<Pair> pairs = {
{1, "one"},
{2, "two"},
{3, "three"},
};

// Print the pairs using the default projection.
std::cout << "Default projection:\n";
print_beman("\tpairs with Beman: ", pairs);
print_std("\tpairs with std: ", pairs);

// Print the pairs using a custom projection.
std::cout << "Custom projection:\n";
print_beman("\tpairs with Beman: ", pairs,
[](const auto &p)
{ return std::to_string(p.n) + ':' + p.s; });
print_std("\tpairs with std: ", pairs,
[](const auto &p)
{ return std::to_string(p.n) + ':' + p.s; });

return 0;
}
File renamed without changes.

0 comments on commit f7d0d26

Please sign in to comment.