forked from facebook/folly
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Summary: We have a need for some common concepts that are used in many places. This is a proposal, please let me know what you think. Differential Revision: D59396081
- Loading branch information
1 parent
19e4d49
commit 738e046
Showing
4 changed files
with
419 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
/* | ||
* Copyright (c) Meta Platforms, Inc. and affiliates. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <concepts> | ||
#include <iterator> | ||
#include <ranges> | ||
|
||
namespace folly { | ||
|
||
/* | ||
* Concept to restrict perfect forwarding to a specific type. | ||
* | ||
* Example: | ||
* void foo(folly::forwarded<std::vector<int>> auto&& vec); | ||
* | ||
*/ | ||
template <typename Fwd, typename To> | ||
concept forwarded = std::same_as<std::remove_cvref_t<Fwd>, To>; | ||
|
||
/* | ||
* T is one of the specified types | ||
* | ||
* NOTE: doesn't have subsumption with `std::same_as` | ||
*/ | ||
template <typename T, typename... Ts> | ||
concept one_of = | ||
(std::is_same_v<T, Ts> || // using is_same_v because it's is faster to | ||
// compile and doesn't change behaviour | ||
...); | ||
|
||
/* | ||
* T implicitly converts to one of the specified types | ||
* | ||
* NOTE: doesn't have subsumption with `one_of` | ||
*/ | ||
template <typename From, typename... To> | ||
concept convertible_to_one_of = (std::is_convertible_v<From, To> || ...); | ||
|
||
// iterator_of ----------------------------------------------- | ||
// iterator for range of exacly one of the listed types | ||
|
||
template <typename I, typename... Ts> | ||
concept input_iterator_of = | ||
std::input_iterator<I> && one_of<std::iter_value_t<I>, Ts...>; | ||
|
||
template <typename I, typename... Ts> | ||
concept forward_iterator_of = | ||
std::forward_iterator<I> && one_of<std::iter_value_t<I>, Ts...>; | ||
|
||
template <typename I, typename... Ts> | ||
concept bidirectional_iterator_of = | ||
std::bidirectional_iterator<I> && one_of<std::iter_value_t<I>, Ts...>; | ||
|
||
template <typename I, typename... Ts> | ||
concept random_access_iterator_of = | ||
std::random_access_iterator<I> && one_of<std::iter_value_t<I>, Ts...>; | ||
|
||
template <typename I, typename... Ts> | ||
concept contiguous_iterator_of = | ||
std::contiguous_iterator<I> && one_of<std::iter_value_t<I>, Ts...>; | ||
|
||
// iterator_of_convertible_to ----------------------------------------------- | ||
// iterator for range of smth convertible to one of the listed types | ||
|
||
template <typename I, typename... Ts> | ||
concept input_iterator_of_convertible_to = std::input_iterator<I> && | ||
convertible_to_one_of<std::iter_value_t<I>, Ts...>; | ||
|
||
template <typename I, typename... Ts> | ||
concept forward_iterator_of_convertible_to = std::forward_iterator<I> && | ||
convertible_to_one_of<std::iter_value_t<I>, Ts...>; | ||
|
||
template <typename I, typename... Ts> | ||
concept bidirectional_iterator_of_convertible_to = | ||
std::bidirectional_iterator<I> && | ||
convertible_to_one_of<std::iter_value_t<I>, Ts...>; | ||
|
||
template <typename I, typename... Ts> | ||
concept random_access_iterator_of_convertible_to = | ||
std::random_access_iterator<I> && | ||
convertible_to_one_of<std::iter_value_t<I>, Ts...>; | ||
|
||
template <typename I, typename... Ts> | ||
concept contiguous_iterator_of_convertible_to = std::contiguous_iterator<I> && | ||
convertible_to_one_of<std::iter_value_t<I>, Ts...>; | ||
|
||
// range_of ----------------------------------------------- | ||
// range of one of the specified types | ||
|
||
template <typename R, typename... Ts> | ||
concept input_range_of = | ||
std::ranges::input_range<R> && one_of<std::ranges::range_value_t<R>, Ts...>; | ||
|
||
template <typename R, typename... Ts> | ||
concept forward_range_of = std::ranges::forward_range<R> && | ||
one_of<std::ranges::range_value_t<R>, Ts...>; | ||
|
||
template <typename R, typename... Ts> | ||
concept bidirectional_range_of = std::ranges::bidirectional_range<R> && | ||
one_of<std::ranges::range_value_t<R>, Ts...>; | ||
|
||
template <typename R, typename... Ts> | ||
concept random_access_range_of = std::ranges::random_access_range<R> && | ||
one_of<std::ranges::range_value_t<R>, Ts...>; | ||
|
||
template <typename R, typename... Ts> | ||
concept contiguous_range_of = std::ranges::contiguous_range<R> && | ||
one_of<std::ranges::range_value_t<R>, Ts...>; | ||
|
||
// range_of_convertible_to ----------------------------------------------- | ||
// range of one of the specified types | ||
|
||
template <typename R, typename... Ts> | ||
concept input_range_of_convertible_to = std::ranges::input_range<R> && | ||
convertible_to_one_of<std::ranges::range_value_t<R>, Ts...>; | ||
|
||
template <typename R, typename... Ts> | ||
concept forward_range_of_convertible_to = std::ranges::forward_range<R> && | ||
convertible_to_one_of<std::ranges::range_value_t<R>, Ts...>; | ||
|
||
template <typename R, typename... Ts> | ||
concept bidirectional_range_of_convertible_to = | ||
std::ranges::bidirectional_range<R> && | ||
convertible_to_one_of<std::ranges::range_value_t<R>, Ts...>; | ||
|
||
template <typename R, typename... Ts> | ||
concept random_access_range_of_convertible_to = | ||
std::ranges::random_access_range<R> && | ||
convertible_to_one_of<std::ranges::range_value_t<R>, Ts...>; | ||
|
||
template <typename R, typename... Ts> | ||
concept contiguous_range_of_convertible_to = std::ranges::contiguous_range<R> && | ||
convertible_to_one_of<std::ranges::range_value_t<R>, Ts...>; | ||
|
||
} // namespace folly |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.