Skip to content

Commit

Permalink
improve the performance of copy_if<> and replace_if<>
Browse files Browse the repository at this point in the history
squash copy_if
  • Loading branch information
brunocodutra committed Aug 18, 2016
1 parent 70a8e1c commit f67e991
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 25 deletions.
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
48 changes: 34 additions & 14 deletions include/metal/list/replace_if.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,46 @@
#define METAL_LIST_REPLACE_IF_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/number/if.hpp>

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

/// \ingroup list
/// ...
template<typename seq, typename lbd, typename val>
using replace_if = metal::transform<
metal::bind<
metal::lambda<metal::if_>,
lbd,
metal::quote<val>,
metal::_1
>,
seq
>;
using replace_if =
typename detail::_replace_if_impl<seq, transform<lbd, seq>, val>::type;
}

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

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

template<typename val>
struct _replace_if_impl<list<>, list<>, val>
{
using type = list<>;
};

template<typename... vals, int_... vs, typename val>
struct _replace_if_impl<list<vals...>, list<number<vs>...>, val>
{
using type = list<if_<number<vs>, val, vals>...>;
};
}
}

#endif

0 comments on commit f67e991

Please sign in to comment.