An open API service indexing awesome lists of open source software.

https://github.com/patrickroberts/pr

An assortment of standalone C++ utilities
https://github.com/patrickroberts/pr

Last synced: 7 months ago
JSON representation

An assortment of standalone C++ utilities

Awesome Lists containing this project

README

          

# `pr`

An assortment of standalone C++ utilities

## [`include/pr/context.hpp`](include/pr/context.hpp)

Synopsis

```cpp
namespace pr {

template
concept /*storable*/ = std::same_as>;

template *storable*/ T>
inline thread_local constinit T * /*context*/ = nullptr;

template
concept /*makeable*/ =
/*storable*/> and not std::is_rvalue_reference_v;

template
class /*provider*/ {
using value_type = std::remove_reference_t;

// `mutable` prevents UB when `make_context` initializes a `const auto`
[[no_unique_address]] mutable T inner_; // exposition-only
value_type *outer_; // exposition-only

public:
template
requires std::constructible_from
explicit /*provider*/(ArgsT &&...args) noexcept(
std::is_nothrow_constructible_v);

/*provider*/(const /*provider*/ &) = delete;
/*provider*/(/*provider*/ &&) = delete;

~/*provider*/() noexcept;
};

template *makeable*/ T, class... ArgsT>
requires std::constructible_from
[[nodiscard]] auto make_context(ArgsT &&...args) noexcept(
std::is_nothrow_constructible_v) -> /*provider*/;

template
concept /*gettable*/ = /*storable*/>;

template *gettable*/ T>
[[nodiscard]] auto get_context() noexcept -> T *;

} // namespace pr
```

---

pr::make_context

```cpp
template *makeable*/ T, class... ArgsT>
requires std::constructible_from
[[nodiscard]] auto make_context(ArgsT &&...args) noexcept(
std::is_nothrow_constructible_v) -> /*provider*/;
```

Constructs and returns `/*provider*/`, whose constructor initializes its members as if by `inner_(std::forward(args)...), outer_(std::exchange(/*context*/, std::addressof(inner_)))`. Its destructor restores `/*context*/` to the value of `outer_`. `T` must be a cv-unqualified non-reference or lvalue-reference type, or the instantiation is ill-formed, which can result in substitution failure when the call appears in the immediate context of a template instantiation.

---

pr::get_context

```cpp
template *gettable*/ T>
[[nodiscard]] auto get_context() noexcept -> T *;
```

Returns `/*context*/`, whose value has been initialized by thread-local calls to `pr::make_context(...)` or `pr::make_context(...)`, or `nullptr` otherwise. `T` must be an optionally const-qualified non-reference type, or the instantiation is ill-formed, which can result in substitution failure when the call appears in the immediate context of a template instantiation.

## [`include/pr/shared_view.hpp`](include/pr/shared_view.hpp)

Synopsis

```cpp
namespace pr {
namespace ranges {

template
concept copyable_view = /* see description */;

template
requires std::is_object_v
class shared_view : public std::ranges::view_interface> {
std::shared_ptr base_; // exposition-only

public:
shared_view() requires std::default_initializable;

explicit shared_view(RangeT &&base);

auto base() const noexcept -> RangeT &;

auto begin() -> std::ranges::iterator_t;

auto end() -> std::ranges::sentinel_t;
};

namespace views {

inline constexpr /* unspecified */ shared = /* unspecified*/;

} // namespace views
} // namespace ranges

namespace views = ranges::views;

} // namespace pr

template
inline constexpr bool
std::ranges::enable_borrowed_range> =
std::ranges::enable_borrowed_range;
```

---

pr::ranges::copyable_view

#### Concept

```cpp
namespace pr::ranges {

template
concept copyable_view =
std::ranges::view and std::copyable;

}
```

The `pr::ranges::copyable_view` concept is a refinement of `std::ranges::view` for which `std::copyable` is satisfied.

---

pr::views::shared

#### Call signature

```cpp
template
requires /* see below */
constexpr auto shared(RangeT &&range) -> copyable_view auto;
```

Given an expression `e` of type `T`, the expression `pr::views::shared(e)` is expression-equivalent to:
- `std::views::all(e)`, if it is a well-formed expression and `std::views::all_t` models `std::copyable`;
- `pr::ranges::shared_view{e}` otherwise.

---

pr::ranges::shared_view

Data members

| Member object | Definition |
| ----------------- | ----------------------------------------------------------------------------- |
| `base_` (private) | A `std::shared_ptr` of the underlying range. (exposition-only member object*) |

Member functions

#### `pr::ranges::shared_view::shared_view`

| | |
| ------------------------------------------------------------ | -------- |
| `shared_view() requires std::default_initializable;` | (1) |
| `explicit shared_view(RangeT &&base);` | (2) |

Constructs a `shared_view`.

1) Default constructor. Initializes `base_` as if by `base_(std::make_shared())`.
2) Initializes the underlying `base_` with `std::make_shared(std::move(base))`.

---

#### `pr::ranges::shared_view::base`

| |
| ---------------------------------------- |
| `auto base() const noexcept -> RangeT &` |

Equivalent to `return *base_;`.

---

#### `pr::ranges::shared_view::begin`

| |
| -------------------------------------------------- |
| `auto begin() -> std::ranges::iterator_t;` |

Equivalent to `return std::ranges::begin(*base_);`.

---

#### `pr::ranges::shared_view::end`

| |
| ------------------------------------------------ |
| `auto end() -> std::ranges::iterator_t;` |

Equivalent to `return std::ranges::end(*base_);`.

Helper templates

```cpp
template
inline constexpr bool
std::ranges::enable_borrowed_range> =
std::ranges::enable_borrowed_range;
```

This specialization of `std::ranges::enable_borrowed_range` makes `shared_view` satisfy `borrowed_range` when the underlying range satisfies it.

## [`include/pr/simple.hpp`](include/pr/simple.hpp)

Synopsis

```cpp
namespace pr {

template
inline constexpr bool /*enable*/ = false;

template
concept trait = std::is_aggregate_v and std::is_empty_v and
/*enable*/;

template
concept /*interface*/ = /*enable*/;

template
concept /*inplace*/ = /*enable*/;

template
concept /*pointer*/ = /*enable*/;

template
concept /*small*/ = /*enable*/;

template
concept /*small*/ = /*inplace*/ or /*pointer*/ or /*small*/;

template
concept /*storable-to*/ = /*storage*/ and /* see below */;

template
concept /*table*/ = /*enable*/;

template
concept /*simple*/ = /*enable*/;

template
concept trait_of = pr::trait and /*simple*/ and
/*enable*/;

template
concept simplifies = pr::trait_of;

template
concept implements = not /*simple*/> and
pr::trait and Trait::template enable;

template
concept /*different-from*/ =
not std::same_as, std::remove_cvref_t>;

template
concept concrete = /*different-from*/ and
/*interface*/ and implements;

template
concept /*invocable-r*/ = std::is_invocable_r_v;

template
concept /*reference*/ = std::is_reference_v;

template
concept /*prvalue*/ = not /*reference*/;

template
concept /*inplace-storable-to*/ =
/*storage*/ and not /*pointer*/ and
/* see below */;

template
struct inplace_storage;

struct pointer_storage;

template
struct small_storage;

struct trait_base {};

template
struct interface;

struct move_constructs;

struct inplace_table;

struct pointer_table;

template *interface*/ Interface,
/*storage*/ Storage = pr::small_storage,
/*table*/ Table = pr::pointer_table>
class simple {
public:
using interface_type = Interface;
using storage_type = Storage;
using table_type = /* unspecified */;

private:
table_type m_table; // exposition-only
storage_type m_storage; // exposition-only

public:
template T, /*invocable-r*/ F>
requires /*inplace*/ and
/*inplace-storable-to*/
simple(std::in_place_type_t tag,
F &&func) noexcept(std::is_nothrow_invocable_r_v);

template T, /*invocable-r*/ F>
requires /*pointer*/ or /*small*/
constexpr simple(std::in_place_type_t tag,
F &&func) noexcept(std::is_nothrow_invocable_r_v and
/*reference*/);

template T, /*invocable-r*/ F>
requires /*small*/ and
/*inplace-storable-to*/ and /*prvalue*/
constexpr simple(std::in_place_type_t tag,
F &&func) noexcept(std::is_nothrow_invocable_r_v);

template T, typename... Args>
requires /*storable-to*/ and
std::constructible_from
constexpr simple(std::in_place_type_t tag, Args &&...args) noexcept(
std::is_nothrow_constructible_v and
/* see below */);

template T>
requires /*storable-to*/ and
std::constructible_from
constexpr simple(T &&object) noexcept(
std::is_nothrow_constructible_v and /* see below */);

template T>
requires /*pointer*/ or /*small*/
constexpr simple(std::unique_ptr &&ptr) noexcept;

simple(const simple &) = delete;
simple(simple &&) = delete;

auto operator=(const simple &) -> simple & = delete;
auto operator=(simple &&) -> simple & = delete;

constexpr auto operator[](pr::trait_of auto trait) const noexcept;

constexpr ~simple() noexcept(/*inplace*/);
};

} // namespace pr
```

Example

See it on [Compiler Explorer](https://godbolt.org/z/7d4MGh5E4)

```cpp
#include

struct copy_constructs : pr::trait_base {
template
static constexpr bool enable = true;

template T>
static constexpr auto fn(const T &object) -> T;

template T>
static constexpr auto fn(const T &object) -> T {
return T(object);
}
};

struct speaks : pr::trait_base {
template
static constexpr bool enable = requires(const T &object) {
{ object.speak() } -> std::convertible_to;
};

template T>
static constexpr auto fn(const T &object) -> std::string;

template T>
static constexpr auto fn(const T &object) -> std::string {
return object.speak();
}
};

class animal {
using interface_type = pr::interface;

pr::simple impl;

public:
template T>
constexpr animal(T &&object) : impl(std::forward(object)) {}

constexpr animal(const animal &other)
: impl(other.impl[copy_constructs{}](other.impl)) {}

constexpr auto speak() const -> std::string { return impl[speaks{}](impl); }
};

struct cow {
constexpr auto speak() const { return "moo"; }
};

struct pig {
constexpr auto speak() const { return "oink"; }
};

struct dog {
constexpr auto speak() const { return "woof"; }
};

// compiles with -std=c++26 using [p2738]
static_assert([] {
std::vector animals{cow{}, pig{}, dog{}};

return animals[0].speak() == "moo" and
animals[1].speak() == "oink" and
animals[2].speak() == "woof";
}());
```