Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ matrix:
env:
- TOOLSET=clang++-3.9
- CPP_EXTRA_FEATURES="cxx_relaxed_constexpr"
- LIBCXX=On

- os: osx
compiler: clang
Expand Down
2 changes: 1 addition & 1 deletion src/kvasir/mpl/algorithm/group.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
#include "../sequence/take.hpp"
#include "../types/int.hpp"
#include "../types/list.hpp"
#include "../types/traits.hpp"
#include "../utility/conditional.hpp"
#include "../utility/is_same.hpp"

namespace kvasir {
namespace mpl {
Expand Down
26 changes: 26 additions & 0 deletions src/kvasir/mpl/algorithm/index_if.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright Odin Holmes 2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#pragma once
#include <tuple>
#include "make_sequence.hpp"
#include "zip_with.hpp"
#include "../functional/bind.hpp"
#include "../functional/flow.hpp"
#include "../sequence/at.hpp"
#include "../sequence/join.hpp"

namespace kvasir {
namespace mpl {
namespace detail {
template <typename F, typename C = listify>
struct index_if {
template <typename... Ts>
using f = typename zip_fixed<if_<at<uint_<1>, F>, front<cfe<list>>, always<list<>>>,
call<make_int_sequence<>, uint_<sizeof...(Ts)>>,
join<C>>::template f<Ts...>;
};
} // namespace detail
} // namespace mpl
} // namespace kvasir
2 changes: 1 addition & 1 deletion src/kvasir/mpl/algorithm/transform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace kvasir {
namespace mpl {
/// \brief executes the continuation `F` on every element in the input pack passing the
/// results to the continuation `C`
template <typename F=identity, typename C = listify>
template <typename F = identity, typename C = listify>
struct transform {
template <typename... Ts>
using f = typename dcall<C, sizeof...(Ts)>::template f<typename F::template f<Ts>...>;
Expand Down
42 changes: 42 additions & 0 deletions src/kvasir/mpl/algorithm/zip_with.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@
#include "../types/nothing.hpp"
#include "../utility/always.hpp"

#include "../sequence/drop.hpp"
#include "../sequence/pop_front.hpp"
#include "../sequence/push_front.hpp"
#include "../sequence/size.hpp"

#include "../algorithm/make_sequence.hpp"
#include "../algorithm/rotate.hpp"

namespace kvasir {
namespace mpl {
namespace detail {
Expand Down Expand Up @@ -89,7 +93,45 @@ namespace kvasir {
template <typename... Ts>
using f = typename detail::zip_with_unpack<F, C, Ts...>::f;
};
namespace detail {
/// \brief n-ary version of transform with all but one of the sequences as fixed
/// parameters
template <typename F, typename... Ls>
struct zip_fixed {
private:
using fixed_size = uint_<(sizeof...(Ls) - 1)>;
using C = typename drop<fixed_size>::template f<Ls...>;

public:
template <typename... Ts>
using f =
typename rotate<uint_<sizeof...(Ls)>,
pop_front<zip_with<F, C>>>::template f<Ls..., list<Ts...>>;
};
/// \exclude
template <typename F, template <typename...> class L, typename... Ls, typename C>
struct zip_fixed<F, L<Ls...>, C> {
template <typename... Ts>
using f = typename dcall<C, sizeof...(Ts)>::template f<
typename dcall<F, sizeof...(Ts)>::template f<Ls, Ts>...>;
};
/// \exclude
template <typename F, template <typename...> class L1, template <typename...> class L2,
typename... L1s, typename... L2s, typename C>
struct zip_fixed<F, L1<L1s...>, L2<L2s...>, C> {
template <typename... Ts>
using f = typename dcall<C, sizeof...(Ts)>::template f<
typename dcall<F, sizeof...(Ts)>::template f<L1s, L2s, Ts>...>;
};

/// \brief binary transform of an index sequence and the dynamic input sequence
template <typename F, typename C>
struct zip_with_index {
template <typename... Ts>
using f = typename zip_fixed<F, call<make_int_sequence<>, uint_<sizeof...(Ts)>>,
C>::template f<Ts...>;
};
} // namespace detail
namespace eager {
template <template <typename...> class Func, typename... Lists>
using zip_with = call<zip_with<cfe<Func>>, Lists...>;
Expand Down
42 changes: 42 additions & 0 deletions src/kvasir/mpl/functional/bind.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,47 @@ namespace kvasir {
template <typename... Ts>
using f = typename dcallf<bool(sizeof...(Ts) > 0)>::template f1<F, Ts...>;
};
/// \brief makes a continuation from an eager metafunction /
/// wraps a template template parameter in such a way that it can be used as a
/// continuation capable meta closure.
/// \requires fixed parameters: a template template parameter (the eager metafunction)
/// dynamic parameters: one type parameter
/// \effects the result will be whatever the eager metafunction maps to when passed the
/// dynamic parameters
/// \notes when passed an alias the result is the same as a traditional call to the at
/// metafunction/ \notes it is perfectly valid to pass a template such as tuple or pair as a
/// 'metafunction'
template <template <typename...> class F, typename C = identity>
struct cfe1 {
template <typename T>
using f = typename C::template f<F<T>>;
};
/// \exclude
template <template <typename...> class F>
struct cfe1<F, identity> {
template <typename T>
using f = F<T>;
};
/// \brief makes a continuation from an eager metafunction /
/// wraps a template template parameter in such a way that it can be used as a
/// continuation capable meta closure.
/// \requires fixed parameters: a template template parameter (the eager metafunction)
/// dynamic parameters: two type parameters
/// \effects the result will be whatever the eager metafunction maps to when passed the
/// dynamic parameters
/// \notes when passed an alias the result is the same as a traditional call to the at
/// metafunction/ \notes it is perfectly valid to pass a template such as tuple or pair as a
/// 'metafunction'
template <template <typename...> class F, typename C = identity>
struct cfe2 {
template <typename T, typename U>
using f = typename C::template f<F<T,U>>;
};
/// \exclude
template <template <typename...> class F>
struct cfe2<F, identity> {
template <typename T, typename U>
using f = F<T, U>;
};
} // namespace mpl
} // namespace kvasir
2 changes: 2 additions & 0 deletions src/kvasir/mpl/mpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "algorithm/fold_left.hpp"
#include "algorithm/fold_right.hpp"
#include "algorithm/group.hpp"
#include "algorithm/index_if.hpp"
#include "algorithm/make_sequence.hpp"
#include "algorithm/partition.hpp"
#include "algorithm/product.hpp"
Expand Down Expand Up @@ -82,6 +83,7 @@
#include "types/list.hpp"
#include "types/nothing.hpp"
#include "types/traits.hpp"
#include "types/type.hpp"

#include "utility/always.hpp"
#include "utility/conditional.hpp"
Expand Down
Loading