Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fast Metal #41

Merged
merged 9 commits into from
Aug 18, 2016
30 changes: 30 additions & 0 deletions include/metal/detail/lookup.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,36 @@ namespace metal
{};
#endif

template<typename>
struct _lookup_first
{};

template<typename x, typename... tail>
struct _lookup_first<list<x, tail...>>
{
using type = x;
};

template<typename vals>
struct _lookup<vals, indices<vals>, number<0>> :
_lookup_first<vals>
{};

template<typename>
struct _lookup_second
{};

template<typename x, typename y, typename... tail>
struct _lookup_second<list<x, y, tail...>>
{
using type = y;
};

template<typename vals>
struct _lookup<vals, indices<vals>, number<1>> :
_lookup_second<vals>
{};

template<typename vals, typename keys, typename key>
using lookup = typename _lookup<vals, keys, key>::type;
}
Expand Down
42 changes: 9 additions & 33 deletions include/metal/lambda/arg.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,6 @@ namespace metal
using type = lambda<impl>;
};

template<>
struct arg_impl<2U>
{
template<typename, typename val, typename...>
using impl = val;

using type = lambda<impl>;
};

template<>
struct arg_impl<1U>
{
template<typename val, typename...>
struct _impl
{
using type = val;
};

template<typename... vals>
using impl = typename _impl<vals...>::type;

using type = lambda<impl>;
};

template<>
struct arg_impl<0U>
{};
Expand All @@ -62,15 +38,15 @@ namespace metal
/// \ingroup lambda
/// Default placeholder.
/// \{
using _1 = metal::arg<1U>;
using _2 = metal::arg<2U>;
using _3 = metal::arg<3U>;
using _4 = metal::arg<4U>;
using _5 = metal::arg<5U>;
using _6 = metal::arg<6U>;
using _7 = metal::arg<7U>;
using _8 = metal::arg<8U>;
using _9 = metal::arg<9U>;
using _1 = metal::arg<1U>;
using _2 = metal::arg<2U>;
using _3 = metal::arg<3U>;
using _4 = metal::arg<4U>;
using _5 = metal::arg<5U>;
using _6 = metal::arg<6U>;
using _7 = metal::arg<7U>;
using _8 = metal::arg<8U>;
using _9 = metal::arg<9U>;
/// \}
}

Expand Down
5 changes: 2 additions & 3 deletions include/metal/list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,20 @@
#include <metal/list/find.hpp>
#include <metal/list/find_if.hpp>
#include <metal/list/flatten.hpp>
#include <metal/list/fold.hpp>
#include <metal/list/fold_left.hpp>
#include <metal/list/fold_right.hpp>
#include <metal/list/front.hpp>
#include <metal/list/indices.hpp>
#include <metal/list/insert.hpp>
#include <metal/list/join.hpp>
#include <metal/list/list.hpp>
#include <metal/list/merge.hpp>
#include <metal/list/none.hpp>
#include <metal/list/partition.hpp>
#include <metal/list/pop_back.hpp>
#include <metal/list/pop_front.hpp>
#include <metal/list/push_back.hpp>
#include <metal/list/push_front.hpp>
#include <metal/list/range.hpp>
#include <metal/list/reduce.hpp>
#include <metal/list/remove.hpp>
#include <metal/list/remove_if.hpp>
#include <metal/list/replace.hpp>
Expand Down
45 changes: 34 additions & 11 deletions include/metal/list/copy_if.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,47 @@
#ifndef METAL_LIST_COPY_IF_HPP
#define METAL_LIST_COPY_IF_HPP

#include <metal/list/list.hpp>
#include <metal/list/join.hpp>
#include <metal/list/transform.hpp>
#include <metal/lambda/apply.hpp>
#include <metal/lambda/quote.hpp>
#include <metal/lambda/lambda.hpp>
#include <metal/lambda/partial.hpp>
#include <metal/number/if.hpp>

namespace metal
{
namespace detail
{
template<typename, typename>
struct _copy_if_impl;
}

/// \ingroup list
/// ...
template<typename seq, typename lbd>
using copy_if = apply<
partial<lambda<join>, list<>>,
transform<bind<lambda<if_>, lbd, lambda<list>, quote<list<>>>, seq>
>;
using copy_if =
typename detail::_copy_if_impl<seq, transform<lbd, seq>>::type;
}

#include <metal/list/list.hpp>
#include <metal/list/join.hpp>
#include <metal/number/if.hpp>
#include <metal/number/number.hpp>

namespace metal
{
namespace detail
{
template<typename, typename>
struct _copy_if_impl
{};

template<>
struct _copy_if_impl<list<>, list<>>
{
using type = list<>;
};

template<typename... vals, int_... vs>
struct _copy_if_impl<list<vals...>, list<number<vs>...>> :
_join<if_<number<vs>, list<vals>, list<>>...>
{};
}
}

#endif
86 changes: 65 additions & 21 deletions include/metal/list/find_if.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,79 @@
#ifndef METAL_LIST_FIND_IF_HPP
#define METAL_LIST_FIND_IF_HPP

#include <metal/list/transform.hpp>

namespace metal
{
namespace detail
{
template<typename seq>
struct _find_if_impl;
}

/// \ingroup list
/// ...
template<typename seq, typename lbd>
using find_if = typename detail::_find_if_impl<transform<lbd, seq>>::type;
}

#include <metal/list/list.hpp>
#include <metal/list/size.hpp>
#include <metal/list/front.hpp>
#include <metal/list/indices.hpp>
#include <metal/list/flatten.hpp>
#include <metal/list/transform.hpp>
#include <metal/lambda/arg.hpp>
#include <metal/lambda/bind.hpp>
#include <metal/lambda/quote.hpp>
#include <metal/lambda/lambda.hpp>
#include <metal/list/indices.hpp>
#include <metal/number/number.hpp>
#include <metal/number/if.hpp>

#include <initializer_list>

namespace metal
{
/// \ingroup list
/// ...
template<typename seq, typename lbd>
using find_if = front<
flatten<
list<
transform<
bind<lambda<if_>, _1, _2, quote<list<>>>,
transform<lbd, seq>,
indices<seq>
>,
size<seq>
>
>
>;
namespace detail
{
template<typename seq>
struct _find_if_impl
{};

template<>
struct _find_if_impl<list<>> :
number<0>
{};

#if __cpp_constexpr >= 201304
template<typename... _>
constexpr int_ ifind(_... vs) {
int_ ret = 0;
for(int_ x : std::initializer_list<int_>{vs...})
if(x) break;
else ++ret;

return ret;
}

template<int_... vs>
struct _find_if_impl<list<number<vs>...>> :
number<ifind(vs...)>
{};
#else
template<typename seq, typename = indices<seq>>
struct _find_index
{};

template<int_... vs, typename... is>
struct _find_index<list<number<vs>...>, list<is...>>
{
using type = front<
flatten<list<if_<number<vs>, is, list<>>..., size<list<is...>>>>
>;
};

template<int_... vs>
struct _find_if_impl<list<number<vs>...>> :
_find_index<list<number<vs>...>>
{};
#endif
}
}

#endif
83 changes: 0 additions & 83 deletions include/metal/list/fold.hpp

This file was deleted.

Loading