Skip to content

Instantly share code, notes, and snippets.

@Dobiasd
Last active August 26, 2017 17:31
Show Gist options
  • Save Dobiasd/63cf2b35bfc5d62cb780fa597f508c6a to your computer and use it in GitHub Desktop.
Save Dobiasd/63cf2b35bfc5d62cb780fa597f508c6a to your computer and use it in GitHub Desktop.
namespace internal
{
template <typename Container, typename F>
Container transform(internal::reuse_container_t, F f, Container&& xs)
{
internal::check_arity<1, F>();
std::transform(std::begin(xs), std::end(xs), std::begin(xs), f);
return std::forward<Container>(xs);
}
template <typename ContainerOut, typename F, typename ContainerIn>
ContainerOut transform(internal::create_new_container_t, F f,
const ContainerIn& xs)
{
internal::check_arity<1, F>();
ContainerOut ys;
internal::prepare_container(ys, size_of_cont(xs));
auto it = internal::get_back_inserter<ContainerOut>(ys);
std::transform(std::begin(xs), std::end(xs), it, f);
return ys;
}
} // namespace internal
// API search type: transform : ((a -> b), [a]) -> [b]
// fwd bind count: 1
// Apply a function to every element in a sequence.
// transform((*2), [1, 3, 4]) == [2, 6, 8]
// Also known as map or fmap.
template <typename F, typename ContainerIn,
typename ContainerOut = typename internal::same_cont_new_t_from_unary_f<
internal::remove_const_and_ref_t<ContainerIn>, F, 0>::type>
ContainerOut transform(F f, ContainerIn&& xs)
{
using ContainerInClean = internal::remove_const_and_ref_t<ContainerIn>;
using reuse_t = typename std::conditional<
std::is_same<
internal::can_reuse_v<ContainerIn>,
internal::reuse_container_t
>::value &&
std::is_base_of<
std::true_type,
internal::has_order<ContainerIn>
>::value &&
std::is_same<
ContainerInClean,
ContainerOut
>::value,
internal::reuse_container_t,
internal::create_new_container_t>::type;
return internal::transform<ContainerOut>(
reuse_t{}, f, std::forward<ContainerIn>(xs));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment