-
Notifications
You must be signed in to change notification settings - Fork 68
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
establishes the basis for numeric ranges
This commit does all the necessary groundwork to get a basis for accumulate to be a ranges citizen. We achieve this by introducing: * the concept Magma * the concept IndirectMagma * a new set of arithmetic operation function objects * an accumulate niebloid * accumulate tests == Notes std::multiplies and std::divides have been renamed to `product` and `quotient`, respectively. Each arithmetic operation has its own detail concept that effectively check things like "has plus". Care was taken to ensure that the requirements for each operator were as complete as possible. For example, since subtraction is the inverse of addition, anything that supports ranges::ext::minus should also support ranges::ext::plus. == Known issues It's believed that each of the detail concepts are ill-specified with respect to references. For example, most expressions are checked à la `{ std::forward<T>(t) + std::forward<T>(t) } -> Common<T>;`, but the type of `t` is `__uncvref(t)` due to difficulties getting some expressions to compile. Reviewers should note this problem when evaluating the design of the detail concepts.
- Loading branch information
Christopher Di Bella
committed
Jun 22, 2019
1 parent
2c74dfb
commit ac25864
Showing
14 changed files
with
593 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
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,39 @@ | ||
// cmcstl2 - A concept-enabled C++ standard library | ||
// | ||
// Copyright Casey Carter | ||
// Copyright Christopher Di Bella | ||
// | ||
// Use, modification and distribution is subject to the | ||
// Boost Software License, Version 1.0. (See accompanying | ||
// file LICENSE_1_0.txt or copy at | ||
// http://www.boost.org/LICENSE_1_0.txt) | ||
// | ||
// Project home: https://github.com/caseycarter/cmcstl2 | ||
// | ||
#ifndef STL2_DETAIL_CONCEPTS_NUMERIC_MAGMA_HPP | ||
#define STL2_DETAIL_CONCEPTS_NUMERIC_MAGMA_HPP | ||
|
||
#include <stl2/detail/concepts/core.hpp> | ||
#include <stl2/detail/concepts/callable.hpp> | ||
#include <stl2/detail/fwd.hpp> | ||
|
||
STL2_OPEN_NAMESPACE { | ||
namespace ext { | ||
template<class BOp, class T, class U> | ||
META_CONCEPT Magma = | ||
Common<T, U> && | ||
RegularInvocable<BOp, T, T> && | ||
RegularInvocable<BOp, U, U> && | ||
RegularInvocable<BOp, T, U> && | ||
RegularInvocable<BOp, U, T> && | ||
Common<invoke_result_t<BOp&, T, U>, T> && | ||
Common<invoke_result_t<BOp&, T, U>, U> && | ||
Same<invoke_result_t<BOp&, T, U>, invoke_result_t<BOp&, U, T>>; | ||
// axiom: Let `bop` be an object of type `BOp`, `t` be an object of type `T`, and `u` be an | ||
// object of type `U`. The expression `invoke(bop, t, u)` must return a result that is | ||
// representable by `common_type_t<T, U>`. | ||
// axiom: The result of `invoke(bop, t, u)` needn't be the same as `invoke(bop, u, t)`. | ||
} // namespace ext | ||
} STL2_CLOSE_NAMESPACE | ||
|
||
#endif // STL2_DETAIL_CONCEPTS_NUMERIC_MAGMA_HPP |
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,22 @@ | ||
// cmcstl2 - A concept-enabled C++ standard library | ||
// | ||
// Copyright Casey Carter | ||
// Copyright Christopher Di Bella | ||
// | ||
// Use, modification and distribution is subject to the | ||
// Boost Software License, Version 1.0. (See accompanying | ||
// file LICENSE_1_0.txt or copy at | ||
// http://www.boost.org/LICENSE_1_0.txt) | ||
// | ||
// Project home: https://github.com/caseycarter/cmcstl2 | ||
// | ||
#ifndef STL2_DETAIL_FUNCTIONAL_ARITHMETIC_HPP | ||
#define STL2_DETAIL_FUNCTIONAL_ARITHMETIC_HPP | ||
|
||
#include <stl2/detail/functional/arithmetic/plus.hpp> | ||
#include <stl2/detail/functional/arithmetic/minus.hpp> | ||
#include <stl2/detail/functional/arithmetic/product.hpp> | ||
#include <stl2/detail/functional/arithmetic/quotient.hpp> | ||
#include <stl2/detail/functional/arithmetic/modulus.hpp> | ||
|
||
#endif // STL2_DETAIL_FUNCTIONAL_ARITHMETIC_HPP |
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,56 @@ | ||
// cmcstl2 - A concept-enabled C++ standard library | ||
// | ||
// Copyright Casey Carter | ||
// Copyright Christopher Di Bella | ||
// | ||
// Use, modification and distribution is subject to the | ||
// Boost Software License, Version 1.0. (See accompanying | ||
// file LICENSE_1_0.txt or copy at | ||
// http://www.boost.org/LICENSE_1_0.txt) | ||
// | ||
// Project home: https://github.com/caseycarter/cmcstl2 | ||
// | ||
#ifndef STL2_DETAIL_FUNCTIONAL_ARITHMETIC_MINUS_HPP | ||
#define STL2_DETAIL_FUNCTIONAL_ARITHMETIC_MINUS_HPP | ||
|
||
#include <stl2/detail/concepts/core.hpp> | ||
#include <stl2/detail/functional/arithmetic/plus.hpp> | ||
#include <stl2/detail/fwd.hpp> | ||
#include <type_traits> | ||
#include <utility> | ||
|
||
STL2_OPEN_NAMESPACE { | ||
namespace ext { | ||
template<class T, class U> | ||
META_CONCEPT __differenceable_with = __summable_with<T, U> && | ||
requires(__uncvref<T> t, __uncvref<U> u) { | ||
{ +std::forward<T>(t) } -> Same<T>; | ||
{ -std::forward<T>(t) } -> Same<T>; | ||
{ +std::forward<U>(u) } -> Same<U>; | ||
{ -std::forward<U>(u) } -> Same<U>; | ||
{ t -= std::forward<U>(u) } -> CommonReference<T&>; | ||
{ u -= std::forward<T>(t) } -> CommonReference<U&>; | ||
{ std::forward<T>(t) - std::forward<T>(t) } -> Common<T>; | ||
{ std::forward<U>(u) - std::forward<U>(u) } -> Common<U>; | ||
{ std::forward<T>(t) - std::forward<U>(u) } -> Common<T>; | ||
{ std::forward<T>(t) - std::forward<U>(u) } -> Common<U>; | ||
requires Same<decltype(std::forward<T>(t) - std::forward<U>(u)), | ||
decltype(std::forward<U>(t) - std::forward<T>(u))>; | ||
}; | ||
// axiom: `t - t` is equivalent to `T{}` | ||
// axiom: `t - (-t)` is equivalent to `t + t` | ||
// axiom: `-t - t` is equivalent to `-(t + t)` | ||
// axiom: `t + t - t` is equivalent to `t` | ||
|
||
struct minus { | ||
template<class T, __differenceable_with<T> U> | ||
constexpr decltype(auto) operator()(T&& t, U&& u) const { | ||
return std::forward<T>(t) - std::forward<U>(u); | ||
} | ||
|
||
using is_transparent = std::true_type; | ||
}; | ||
} // namespace ext | ||
} STL2_CLOSE_NAMESPACE | ||
|
||
#endif // STL2_DETAIL_FUNCTIONAL_ARITHMETIC_MINUS_HPP |
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,49 @@ | ||
// cmcstl2 - A concept-enabled C++ standard library | ||
// | ||
// Copyright Casey Carter | ||
// Copyright Christopher Di Bella | ||
// | ||
// Use, modification and distribution is subject to the | ||
// Boost Software License, Version 1.0. (See accompanying | ||
// file LICENSE_1_0.txt or copy at | ||
// http://www.boost.org/LICENSE_1_0.txt) | ||
// | ||
// Project home: https://github.com/caseycarter/cmcstl2 | ||
// | ||
#ifndef STL2_DETAIL_FUNCTIONAL_ARITHMETIC_MODULUS_HPP | ||
#define STL2_DETAIL_FUNCTIONAL_ARITHMETIC_MODULUS_HPP | ||
|
||
#include <stl2/detail/concepts/core.hpp> | ||
#include <stl2/detail/functional/arithmetic/plus.hpp> | ||
#include <stl2/detail/functional/arithmetic/quotient.hpp> | ||
#include <stl2/detail/fwd.hpp> | ||
#include <type_traits> | ||
#include <utility> | ||
|
||
STL2_OPEN_NAMESPACE { | ||
namespace ext { | ||
template<class T, class U> | ||
META_CONCEPT __modulo_with = __summable_with<T, U> && __divisible_with<T, U> && | ||
requires(__uncvref<T> t, __uncvref<U> u) { | ||
{ t %= std::forward<U>(u) } -> CommonReference<T&>; | ||
{ u %= std::forward<T>(t) } -> CommonReference<U&>; | ||
{ std::forward<T>(t) % std::forward<T>(t) } -> Common<T>; | ||
{ std::forward<U>(u) % std::forward<U>(u) } -> Common<U>; | ||
{ std::forward<T>(t) % std::forward<U>(u) } -> Common<T>; | ||
{ std::forward<T>(t) % std::forward<U>(u) } -> Common<U>; | ||
requires Same<decltype(std::forward<T>(t) / std::forward<U>(u)), | ||
decltype(std::forward<U>(t) / std::forward<T>(u))>; | ||
}; | ||
// Let n, q, r, t all be distinct objects of type T. | ||
// axiom: `t % q == q * r + n` | ||
|
||
struct modulus { | ||
template<class T, __modulo_with<T> U> | ||
constexpr decltype(auto) operator()(T&& t, U&& u) const { | ||
return std::forward<T>(t) % std::forward<U>(u); | ||
} | ||
}; | ||
} // namespace ext | ||
} STL2_CLOSE_NAMESPACE | ||
|
||
#endif // STL2_DETAIL_FUNCTIONAL_ARITHMETIC_MODULUS_HPP |
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,50 @@ | ||
// cmcstl2 - A concept-enabled C++ standard library | ||
// | ||
// Copyright Casey Carter | ||
// Copyright Christopher Di Bella | ||
// | ||
// Use, modification and distribution is subject to the | ||
// Boost Software License, Version 1.0. (See accompanying | ||
// file LICENSE_1_0.txt or copy at | ||
// http://www.boost.org/LICENSE_1_0.txt) | ||
// | ||
// Project home: https://github.com/caseycarter/cmcstl2 | ||
// | ||
#ifndef STL2_DETAIL_FUNCTIONAL_ARITHMETIC_PLUS_HPP | ||
#define STL2_DETAIL_FUNCTIONAL_ARITHMETIC_PLUS_HPP | ||
|
||
#include <stl2/detail/concepts/core.hpp> | ||
#include <stl2/detail/fwd.hpp> | ||
#include <type_traits> | ||
#include <utility> | ||
|
||
STL2_OPEN_NAMESPACE { | ||
namespace ext { | ||
template<class T, class U> | ||
META_CONCEPT __summable_with = | ||
DefaultConstructible<remove_reference_t<T>> && | ||
DefaultConstructible<remove_reference_t<U>> && | ||
CommonReference<T, U> && | ||
requires(__uncvref<T> t, __uncvref<U> u) { | ||
{ t += std::forward<U>(u) } -> CommonReference<T&>; | ||
{ u += std::forward<T>(t) } -> CommonReference<U&>; | ||
{ std::forward<T>(t) + std::forward<T>(t) } -> Common<T>; | ||
{ std::forward<U>(u) + std::forward<U>(u) } -> Common<U>; | ||
{ std::forward<T>(t) + std::forward<U>(u) } -> Common<T>; | ||
{ std::forward<T>(t) + std::forward<U>(u) } -> Common<U>; | ||
requires Same<decltype(std::forward<T>(t) + std::forward<U>(u)), | ||
decltype(std::forward<U>(t) + std::forward<T>(u))>; | ||
}; | ||
|
||
struct plus { | ||
template<class T, __summable_with<T> U> | ||
constexpr decltype(auto) operator()(T&& t, U&& u) const { | ||
return std::forward<T>(t) + std::forward<U>(u); | ||
} | ||
|
||
using is_transparent = std::true_type; | ||
}; | ||
} // namespace ext | ||
} STL2_CLOSE_NAMESPACE | ||
|
||
#endif // STL2_DETAIL_FUNCTIONAL_ARITHMETIC_PLUS_HPP |
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,55 @@ | ||
// cmcstl2 - A concept-enabled C++ standard library | ||
// | ||
// Copyright Casey Carter | ||
// Copyright Christopher Di Bella | ||
// | ||
// Use, modification and distribution is subject to the | ||
// Boost Software License, Version 1.0. (See accompanying | ||
// file LICENSE_1_0.txt or copy at | ||
// http://www.boost.org/LICENSE_1_0.txt) | ||
// | ||
// Project home: https://github.com/caseycarter/cmcstl2 | ||
// | ||
#ifndef STL2_DETAIL_FUNCTIONAL_ARITHMETIC_PRODUCT_HPP | ||
#define STL2_DETAIL_FUNCTIONAL_ARITHMETIC_PRODUCT_HPP | ||
|
||
#include <stl2/detail/concepts/core.hpp> | ||
#include <stl2/detail/fwd.hpp> | ||
#include <type_traits> | ||
#include <utility> | ||
|
||
STL2_OPEN_NAMESPACE { | ||
namespace ext { | ||
template<class T, class U> | ||
META_CONCEPT __multiplicable_with = | ||
DefaultConstructible<remove_reference_t<T>> && | ||
DefaultConstructible<remove_reference_t<U>> && | ||
Constructible<remove_reference_t<T>, int> && // specifically T{0} and T{1} | ||
Constructible<remove_reference_t<T>, int> && // specifically U{0} and U{1} | ||
CommonReference<T, U> && | ||
requires(__uncvref<T> t, __uncvref<U> u) { | ||
{ t *= std::forward<U>(u) } -> CommonReference<T&>; | ||
{ u *= std::forward<T>(t) } -> CommonReference<U&>; | ||
{ std::forward<T>(t) * std::forward<T>(t) } -> Common<T>; | ||
{ std::forward<U>(u) * std::forward<U>(u) } -> Common<U>; | ||
{ std::forward<T>(t) * std::forward<U>(u) } -> Common<T>; | ||
{ std::forward<T>(t) * std::forward<U>(u) } -> Common<U>; | ||
requires Same<decltype(std::forward<T>(t) * std::forward<U>(u)), | ||
decltype(std::forward<U>(t) * std::forward<T>(u))>; | ||
}; | ||
// axiom: T{0} is equivalent to T{}, and similarly for U | ||
// axiom: `t * T{1} == t` and `T{1} * t == t`, and similarly for U | ||
|
||
// std::multiplies renamed to std::ranges::product | ||
struct product { | ||
template<class T, __multiplicable_with<T> U> | ||
constexpr decltype(auto) operator()(T&& t, U&& u) const { | ||
return std::forward<T>(t) * std::forward<U>(u); | ||
} | ||
|
||
using is_transparent = std::true_type; | ||
}; | ||
} // namespace ext | ||
} STL2_CLOSE_NAMESPACE | ||
|
||
#endif // STL2_DETAIL_FUNCTIONAL_ARITHMETIC_PRODUCT_HPP |
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,49 @@ | ||
// cmcstl2 - A concept-enabled C++ standard library | ||
// | ||
// Copyright Casey Carter | ||
// Copyright Christopher Di Bella | ||
// | ||
// Use, modification and distribution is subject to the | ||
// Boost Software License, Version 1.0. (See accompanying | ||
// file LICENSE_1_0.txt or copy at | ||
// http://www.boost.org/LICENSE_1_0.txt) | ||
// | ||
// Project home: https://github.com/caseycarter/cmcstl2 | ||
// | ||
#ifndef STL2_DETAIL_FUNCTIONAL_ARITHMETIC_QUOTIENT_HPP | ||
#define STL2_DETAIL_FUNCTIONAL_ARITHMETIC_QUOTIENT_HPP | ||
|
||
#include <stl2/detail/concepts/core.hpp> | ||
#include <stl2/detail/functional/arithmetic/product.hpp> | ||
#include <stl2/detail/fwd.hpp> | ||
#include <type_traits> | ||
#include <utility> | ||
|
||
STL2_OPEN_NAMESPACE { | ||
namespace ext { | ||
template<class T, class U> | ||
META_CONCEPT __divisible_with = __multiplicable_with<T, U> && | ||
requires(__uncvref<T> t, __uncvref<U> u) { | ||
{ t /= std::forward<U>(u) } -> CommonReference<T&>; | ||
{ u /= std::forward<T>(t) } -> CommonReference<U&>; | ||
{ std::forward<T>(t) / std::forward<T>(t) } -> Common<T>; | ||
{ std::forward<U>(u) / std::forward<U>(u) } -> Common<U>; | ||
{ std::forward<T>(t) / std::forward<U>(u) } -> Common<T>; | ||
{ std::forward<T>(t) / std::forward<U>(u) } -> Common<U>; | ||
requires Same<decltype(std::forward<T>(t) / std::forward<U>(u)), | ||
decltype(std::forward<U>(t) / std::forward<T>(u))>; | ||
}; | ||
// axiom: `t / t` is equivalent to `T{1}` | ||
// axiom: `(t * t) / t` is equivalent to `t` | ||
|
||
// std::divides renamed to std::ranges::quotient | ||
struct quotient { | ||
template<class T, __divisible_with<T> U> | ||
constexpr decltype(auto) operator()(T&& t, U&& u) const { | ||
return std::forward<T>(t) / std::forward<U>(u); | ||
} | ||
}; | ||
} // namespace ext | ||
} STL2_CLOSE_NAMESPACE | ||
|
||
#endif // STL2_DETAIL_FUNCTIONAL_ARITHMETIC_QUOTIENT_HPP |
Oops, something went wrong.