| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 |
- // This file is part of Desktop App Toolkit,
- // a set of libraries for developing nice desktop applications.
- //
- // For license and copyright information please follow this link:
- // https://github.com/desktop-app/legal/blob/master/LEGAL
- //
- #pragma once
- namespace rpl {
- namespace details {
- struct base_mapper {
- };
- template <typename Type>
- constexpr bool is_mapper_v = std::is_base_of_v<
- base_mapper,
- std::decay_t<Type>>;
- template <std::size_t Index>
- struct argument_mapper : base_mapper {
- template <
- typename Arg,
- typename ...Args,
- typename = std::enable_if_t<(sizeof...(Args) >= Index)>>
- static constexpr decltype(auto) call(Arg &&arg, Args &&...args) {
- return argument_mapper<Index - 1>::call(
- std::forward<Args>(args)...);
- }
- template <
- typename ...Args,
- typename = std::enable_if_t<(sizeof...(Args) > Index)>>
- constexpr auto operator()(Args &&...args) const {
- return call(std::forward<Args>(args)...);
- }
- };
- template <>
- struct argument_mapper<0> : base_mapper {
- template <
- typename Arg,
- typename ...Args>
- static constexpr decltype(auto) call(Arg &&arg, Args &&...args) {
- return std::forward<Arg>(arg);
- }
- template <
- typename Arg,
- typename ...Args>
- constexpr auto operator()(Arg &&arg, Args &&...args) const {
- return std::forward<Arg>(arg);
- }
- };
- template <typename Type>
- class value_mapper : public base_mapper {
- public:
- template <typename OtherType>
- constexpr value_mapper(OtherType &&value)
- : _value(std::forward<OtherType>(value)) {
- }
- template <typename ...Args>
- constexpr auto operator()(Args &&...args) const {
- return _value;
- }
- private:
- Type _value;
- };
- template <typename Type>
- struct wrap_mapper {
- using type = std::conditional_t<
- is_mapper_v<Type>,
- Type,
- value_mapper<Type>>;
- };
- template <typename Type>
- using wrap_mapper_t = typename wrap_mapper<Type>::type;
- template <typename Type, typename Operator>
- class unary_operator_mapper : public base_mapper {
- using TypeWrapper = wrap_mapper_t<std::decay_t<Type>>;
- public:
- template <typename OtherType>
- constexpr unary_operator_mapper(OtherType &&value)
- : _value(std::forward<OtherType>(value)) {
- }
- template <
- typename ...Args,
- typename Result = decltype((Operator{})(
- std::declval<TypeWrapper>()(std::declval<Args>()...)))>
- constexpr std::decay_t<Result> operator()(Args &&...args) const {
- return (Operator{})(
- _value(std::forward<Args>(args)...));
- }
- private:
- TypeWrapper _value;
- };
- template <typename Left, typename Right, typename Operator>
- class binary_operator_mapper : public base_mapper {
- using LeftWrapper = wrap_mapper_t<std::decay_t<Left>>;
- using RightWrapper = wrap_mapper_t<std::decay_t<Right>>;
- public:
- template <typename OtherLeft, typename OtherRight>
- constexpr binary_operator_mapper(OtherLeft &&left, OtherRight &&right)
- : _left(std::forward<OtherLeft>(left))
- , _right(std::forward<OtherRight>(right)) {
- }
- template <
- typename ...Args,
- typename Result = decltype((Operator{})(
- std::declval<LeftWrapper>()(std::declval<Args>()...),
- std::declval<RightWrapper>()(std::declval<Args>()...)))>
- constexpr std::decay_t<Result> operator()(Args &&...args) const {
- return (Operator{})(
- _left(std::forward<Args>(args)...),
- _right(std::forward<Args>(args)...));
- }
- private:
- LeftWrapper _left;
- RightWrapper _right;
- };
- template <
- typename Left,
- typename Right,
- typename = std::enable_if_t<
- is_mapper_v<Left> || is_mapper_v<Right>
- >>
- inline auto operator+(Left &&left, Right &&right) {
- return binary_operator_mapper<
- Left,
- Right,
- std::plus<>>(
- std::forward<Left>(left),
- std::forward<Right>(right));
- }
- template <
- typename Left,
- typename Right,
- typename = std::enable_if_t<
- is_mapper_v<Left> || is_mapper_v<Right>
- >>
- inline auto operator-(Left &&left, Right &&right) {
- return binary_operator_mapper<
- Left,
- Right,
- std::minus<>>(
- std::forward<Left>(left),
- std::forward<Right>(right));
- }
- template <
- typename Left,
- typename Right,
- typename = std::enable_if_t<
- is_mapper_v<Left> || is_mapper_v<Right>
- >>
- inline auto operator*(Left &&left, Right &&right) {
- return binary_operator_mapper<
- Left,
- Right,
- std::multiplies<>>(
- std::forward<Left>(left),
- std::forward<Right>(right));
- }
- template <
- typename Left,
- typename Right,
- typename = std::enable_if_t<
- is_mapper_v<Left> || is_mapper_v<Right>
- >>
- inline auto operator/(Left &&left, Right &&right) {
- return binary_operator_mapper<
- Left,
- Right,
- std::divides<>>(
- std::forward<Left>(left),
- std::forward<Right>(right));
- }
- template <
- typename Left,
- typename Right,
- typename = std::enable_if_t<
- is_mapper_v<Left> || is_mapper_v<Right>
- >>
- inline auto operator%(Left &&left, Right &&right) {
- return binary_operator_mapper<
- Left,
- Right,
- std::modulus<>>(
- std::forward<Left>(left),
- std::forward<Right>(right));
- }
- template <
- typename Type,
- typename = std::enable_if_t<
- is_mapper_v<Type>
- >>
- inline auto operator-(Type &&value) {
- return unary_operator_mapper<
- Type,
- std::negate<>>(
- std::forward<Type>(value));
- }
- template <
- typename Left,
- typename Right,
- typename = std::enable_if_t<
- is_mapper_v<Left> || is_mapper_v<Right>
- >>
- inline auto operator<(Left &&left, Right &&right) {
- return binary_operator_mapper<
- Left,
- Right,
- std::less<>>(
- std::forward<Left>(left),
- std::forward<Right>(right));
- }
- template <
- typename Left,
- typename Right,
- typename = std::enable_if_t<
- is_mapper_v<Left> || is_mapper_v<Right>
- >>
- inline auto operator<=(Left &&left, Right &&right) {
- return binary_operator_mapper<
- Left,
- Right,
- std::less_equal<>>(
- std::forward<Left>(left),
- std::forward<Right>(right));
- }
- template <
- typename Left,
- typename Right,
- typename = std::enable_if_t<
- is_mapper_v<Left> || is_mapper_v<Right>
- >>
- inline auto operator>(Left &&left, Right &&right) {
- return binary_operator_mapper<
- Left,
- Right,
- std::greater<>>(
- std::forward<Left>(left),
- std::forward<Right>(right));
- }
- template <
- typename Left,
- typename Right,
- typename = std::enable_if_t<
- is_mapper_v<Left> || is_mapper_v<Right>
- >>
- inline auto operator>=(Left &&left, Right &&right) {
- return binary_operator_mapper<
- Left,
- Right,
- std::greater_equal<>>(
- std::forward<Left>(left),
- std::forward<Right>(right));
- }
- template <
- typename Left,
- typename Right,
- typename = std::enable_if_t<
- is_mapper_v<Left> || is_mapper_v<Right>
- >>
- inline auto operator==(Left &&left, Right &&right) {
- return binary_operator_mapper<
- Left,
- Right,
- std::equal_to<>>(
- std::forward<Left>(left),
- std::forward<Right>(right));
- }
- template <
- typename Left,
- typename Right,
- typename = std::enable_if_t<
- is_mapper_v<Left> || is_mapper_v<Right>
- >>
- inline auto operator!=(Left &&left, Right &&right) {
- return binary_operator_mapper<
- Left,
- Right,
- std::not_equal_to<>>(
- std::forward<Left>(left),
- std::forward<Right>(right));
- }
- template <
- typename Left,
- typename Right,
- typename = std::enable_if_t<
- is_mapper_v<Left> || is_mapper_v<Right>
- >>
- inline auto operator&&(Left &&left, Right &&right) {
- return binary_operator_mapper<
- Left,
- Right,
- std::logical_and<>>(
- std::forward<Left>(left),
- std::forward<Right>(right));
- }
- template <
- typename Left,
- typename Right,
- typename = std::enable_if_t<
- is_mapper_v<Left> || is_mapper_v<Right>
- >>
- inline auto operator||(Left &&left, Right &&right) {
- return binary_operator_mapper<
- Left,
- Right,
- std::logical_or<>>(
- std::forward<Left>(left),
- std::forward<Right>(right));
- }
- template <
- typename Type,
- typename = std::enable_if_t<
- is_mapper_v<Type>
- >>
- inline auto operator!(Type &&value) {
- return unary_operator_mapper<
- Type,
- std::logical_not<>>(
- std::forward<Type>(value));
- }
- template <
- typename Left,
- typename Right,
- typename = std::enable_if_t<
- is_mapper_v<Left> || is_mapper_v<Right>
- >>
- inline auto operator&(Left &&left, Right &&right) {
- return binary_operator_mapper<
- Left,
- Right,
- std::bit_and<>>(
- std::forward<Left>(left),
- std::forward<Right>(right));
- }
- template <
- typename Left,
- typename Right,
- typename = std::enable_if_t<
- is_mapper_v<Left> || is_mapper_v<Right>
- >>
- inline auto operator|(Left &&left, Right &&right) {
- return binary_operator_mapper<
- Left,
- Right,
- std::bit_or<>>(
- std::forward<Left>(left),
- std::forward<Right>(right));
- }
- template <
- typename Left,
- typename Right,
- typename = std::enable_if_t<
- is_mapper_v<Left> || is_mapper_v<Right>
- >>
- inline auto operator^(Left &&left, Right &&right) {
- return binary_operator_mapper<
- Left,
- Right,
- std::bit_xor<>>(
- std::forward<Left>(left),
- std::forward<Right>(right));
- }
- template <
- typename Type,
- typename = std::enable_if_t<
- is_mapper_v<Type>
- >>
- inline auto operator~(Type &&value) {
- return unary_operator_mapper<
- Type,
- std::bit_not<>>(
- std::forward<Type>(value));
- }
- template <typename ...Mappers>
- class tuple_mapper {
- template <typename ...Args>
- using tuple_result = std::tuple<decltype(
- std::declval<wrap_mapper_t<std::decay_t<Mappers>>>()(
- std::declval<Args>()...))...>;
- public:
- template <typename ...OtherMappers>
- tuple_mapper(OtherMappers &&...mappers) : _mappers(
- std::forward<OtherMappers>(mappers)...) {
- }
- template <typename ...Args>
- constexpr tuple_result<Args...> operator()(
- Args &&...args) const {
- constexpr auto kArity = sizeof...(Mappers);
- return call_helper(
- std::make_index_sequence<kArity>(),
- std::forward<Args>(args)...);
- }
- private:
- template <typename ...Args, std::size_t ...I>
- inline tuple_result<Args...> call_helper(
- std::index_sequence<I...>,
- Args &&...args) const {
- return std::make_tuple(
- std::get<I>(_mappers)(std::forward<Args>(args)...)...);
- }
- std::tuple<wrap_mapper_t<std::decay_t<Mappers>>...> _mappers;
- };
- template <typename ...Args>
- tuple_mapper<Args...> tuple(Args &&...args) {
- return tuple_mapper<Args...>(std::forward<Args>(args)...);
- }
- } // namespace details
- namespace mappers {
- constexpr const details::argument_mapper<0> _1;
- constexpr const details::argument_mapper<1> _2;
- constexpr const details::argument_mapper<2> _3;
- constexpr const details::argument_mapper<3> _4;
- constexpr const details::argument_mapper<4> _5;
- constexpr const details::argument_mapper<5> _6;
- constexpr const details::argument_mapper<6> _7;
- constexpr const details::argument_mapper<7> _8;
- constexpr const details::argument_mapper<8> _9;
- constexpr const details::argument_mapper<9> _10;
- constexpr const auto _1_of_two = ((void)_2, _1);
- } // namespace mappers
- } // namespace rpl
|