@@ -1,5 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/container/handle_manager.h> | |||
#include <cpputils/container/nullable.h> | |||
#include <cpputils/container/smart_ptr.h> |
@@ -1,14 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/misc/convert.h> | |||
#include <cpputils/misc/enum.h> | |||
#include <cpputils/misc/exception.h> | |||
#include <cpputils/misc/flags.h> | |||
#include <cpputils/misc/indent.h> | |||
#include <cpputils/misc/misc.h> | |||
#include <cpputils/misc/stream.h> | |||
#include <cpputils/misc/string.h> | |||
#include <cpputils/misc/time.h> | |||
#include <cpputils/misc/transform_iterator.h> | |||
#include <cpputils/misc/type_helper.h> | |||
#include <cpputils/misc/wrapper.h> |
@@ -1,7 +1,3 @@ | |||
#pragma once | |||
#include <cpputils/mp/core.h> | |||
#include <cpputils/mp/misc.h> | |||
#include <cpputils/mp/intern.h> | |||
#include <cpputils/mp/container.h> | |||
#include <cpputils/mp/operations.h> | |||
#include <cpputils/mp/core.h> |
@@ -1,34 +0,0 @@ | |||
== License of this adaptation == | |||
Copyright Erik Junghanns. | |||
== Original boost::hana license == | |||
Copyright Louis Dionne 2013-2017 | |||
Boost Software License - Version 1.0 - August 17th, 2003 | |||
Permission is hereby granted, free of charge, to any person or organization | |||
obtaining a copy of the software and accompanying documentation covered by | |||
this license (the "Software") to use, reproduce, display, distribute, | |||
execute, and transmit the Software, and to prepare derivative works of the | |||
Software, and to permit third-parties to whom the Software is furnished to | |||
do so, all subject to the following: | |||
The copyright notices in the Software and this entire statement, including | |||
the above license grant, this restriction and the following disclaimer, | |||
must be included in all copies of the Software, in whole or in part, and | |||
all derivative works of the Software, unless such copies or derivative | |||
works are solely in the form of machine-executable object code generated by | |||
a source language processor. | |||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT | |||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE | |||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, | |||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
DEALINGS IN THE SOFTWARE. | |||
@@ -1,2 +0,0 @@ | |||
This is an adaptation of the boost::hana library. | |||
See https://github.com/boostorg/hana |
@@ -1,6 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/container/basic_tuple.h> | |||
#include <cpputils/mp/container/map.h> | |||
#include <cpputils/mp/container/pair.h> | |||
#include <cpputils/mp/container/type.h> |
@@ -1,159 +0,0 @@ | |||
#pragma once | |||
#include <utility> | |||
#include <cpputils/mp/core/modifier.h> | |||
#include <cpputils/mp/core/conditionals.h> | |||
#include <cpputils/mp/misc/make.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/intern/ebo.h> | |||
#include <cpputils/mp/operations/at.h> | |||
#include <cpputils/mp/operations/unpack.h> | |||
#include <cpputils/mp/operations/transform.h> | |||
namespace utl { | |||
namespace mp { | |||
struct tag_basic_tuple { }; | |||
namespace __impl | |||
{ | |||
template<size_t> | |||
struct basic_tuple_index; | |||
template<typename Indices, typename... Xn> | |||
struct basic_tuple_impl; | |||
struct basic_tuple_from_other { }; | |||
template<size_t... N, typename... Xn> | |||
struct basic_tuple_impl<std::index_sequence<N...>, Xn...> | |||
: intern::ebo<basic_tuple_index<N>, Xn>... | |||
{ | |||
static constexpr size_t _size = sizeof...(Xn); | |||
constexpr basic_tuple_impl() = default; | |||
template<typename Other> | |||
explicit constexpr basic_tuple_impl(basic_tuple_from_other, Other&& other) | |||
: intern::ebo<basic_tuple_index<N>, Xn>(intern::ebo_get<basic_tuple_index<N>>(std::forward<Other>(other)))... | |||
{ } | |||
template<typename... Yn> | |||
explicit constexpr basic_tuple_impl(Yn&&... yn) | |||
: intern::ebo<basic_tuple_index<N>, Xn>(std::forward<Yn>(yn))... | |||
{ } | |||
}; | |||
} | |||
template<typename... Xn> | |||
struct basic_tuple final | |||
: __impl::basic_tuple_impl<std::make_index_sequence<sizeof...(Xn)>, Xn...> | |||
{ | |||
using tag = tag_basic_tuple; | |||
using base_type = __impl::basic_tuple_impl<std::make_index_sequence<sizeof...(Xn)>, Xn...>; | |||
constexpr basic_tuple() = default; | |||
template<typename Other, typename = enable_if<is_same<basic_tuple, decay_type<Other>>>> | |||
constexpr basic_tuple(Other&& other) | |||
: base_type(__impl::basic_tuple_from_other { }, std::forward<Other>(other)) | |||
{ } | |||
template<typename... Yn> | |||
explicit constexpr basic_tuple(Yn&&... yn) | |||
: base_type(std::forward<Yn>(yn)...) | |||
{ } | |||
template<typename N> | |||
constexpr auto at(const N& n) const | |||
{ return mp::at(*this, n); } | |||
template<typename F> | |||
constexpr auto unpack(F&& f) const | |||
{ return mp::unpack(*this, std::forward<F>(f)); } | |||
template<typename F> | |||
constexpr auto transform(F&& f) const | |||
{ return mp::transform(*this, std::forward<F>(f)); } | |||
}; | |||
constexpr auto make_basic_tuple = make<tag_basic_tuple>; | |||
namespace __impl | |||
{ | |||
/* tag_of */ | |||
template<typename... Xn> | |||
struct tag_of_impl<basic_tuple<Xn...>> | |||
{ using type = tag_basic_tuple; }; | |||
/* make */ | |||
template<> | |||
struct make_impl<tag_basic_tuple> | |||
{ | |||
template<typename... Xn> | |||
static constexpr auto apply(Xn&&... xn) | |||
{ return basic_tuple<decay_type<Xn>...> { std::forward<Xn>(xn)... }; } | |||
}; | |||
/* unpack */ | |||
template<> | |||
struct unpack_impl<tag_basic_tuple> | |||
{ | |||
template<size_t... I, typename... Xn, typename F> | |||
static constexpr auto apply(const basic_tuple_impl<std::index_sequence<I...>, Xn...>& xs, F&& f) | |||
{ | |||
return std::forward<F>(f)( | |||
intern::ebo_get<basic_tuple_index<I>>( | |||
static_cast<const intern::ebo<basic_tuple_index<I>, Xn>&>(xs) | |||
)... | |||
); | |||
} | |||
template<size_t... I, typename... Xn, typename F> | |||
static constexpr auto apply(basic_tuple_impl<std::index_sequence<I...>, Xn...>& xs, F&& f) | |||
{ | |||
return std::forward<F>(f)( | |||
intern::ebo_get<basic_tuple_index<I>>( | |||
static_cast<intern::ebo<basic_tuple_index<I>, Xn>&>(xs) | |||
)... | |||
); | |||
} | |||
template<size_t... I, typename... Xn, typename F> | |||
static constexpr auto apply(basic_tuple_impl<std::index_sequence<I...>, Xn...>&& xs, F&& f) | |||
{ | |||
return std::forward<F>(f)( | |||
intern::ebo_get<basic_tuple_index<I>>( | |||
static_cast<intern::ebo<basic_tuple_index<I>, Xn>&&>(xs) | |||
)... | |||
); | |||
} | |||
}; | |||
/* at */ | |||
template<> | |||
struct at_impl<tag_basic_tuple> | |||
{ | |||
template<typename Xs, typename N> | |||
static constexpr auto apply(Xs&& xs, const N&) | |||
{ | |||
constexpr size_t index = N::value; | |||
return intern::ebo_get<basic_tuple_index<index>>(std::forward<Xs>(xs)); | |||
} | |||
}; | |||
} | |||
template <size_t N, typename... Xn> | |||
constexpr auto at_c(const basic_tuple<Xn...>& x) | |||
{ return intern::ebo_get<__impl::basic_tuple_index<N>>(x); } | |||
template <size_t N, typename... Xn> | |||
constexpr auto at_c(basic_tuple<Xn...>& x) | |||
{ return intern::ebo_get<__impl::basic_tuple_index<N>>(x); } | |||
template <size_t N, typename... Xn> | |||
constexpr auto at_c(basic_tuple<Xn...>&& x) | |||
{ return intern::ebo_get<__impl::basic_tuple_index<N>>(std::forward<basic_tuple<Xn...>>(x)); } | |||
} | |||
} |
@@ -1,36 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/misc/to.h> | |||
#include <cpputils/mp/misc/make.h> | |||
#include <cpputils/mp/container/basic_tuple.h> | |||
namespace utl { | |||
namespace mp { | |||
struct tag_map { }; | |||
constexpr auto make_map = make<tag_map>; | |||
constexpr auto to_map = make<tag_map>; | |||
namespace __impl /* forward declaration */ | |||
{ | |||
template<typename... Pairs> | |||
struct make_map_type; | |||
} | |||
template<typename... Pairs> | |||
using map = typename __impl::make_map_type<Pairs...>::type; | |||
namespace __impl /* implementation */ | |||
{ | |||
template<typename... Pairs> | |||
struct make_map_type | |||
{ | |||
using storage_type = basic_tuple<Pairs...>; | |||
}; | |||
} | |||
} | |||
} |
@@ -1,239 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/core.h> | |||
#include <cpputils/mp/misc/make.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/intern/ebo.h> | |||
#include <cpputils/mp/intern/operators_orderable.h> | |||
#include <cpputils/mp/intern/operators_comparable.h> | |||
#include <cpputils/mp/operations/first.h> | |||
#include <cpputils/mp/operations/second.h> | |||
#include <cpputils/mp/operations/compare/less.h> | |||
#include <cpputils/mp/operations/compare/less_equal.h> | |||
#include <cpputils/mp/operations/compare/equal.h> | |||
#include <cpputils/mp/operations/logical/or.h> | |||
#include <cpputils/mp/operations/logical/and.h> | |||
#include <cpputils/mp/operations/logical/not.h> | |||
namespace utl { | |||
namespace mp { | |||
struct tag_pair { }; | |||
constexpr auto make_pair = make<tag_pair>; | |||
namespace __impl | |||
{ | |||
template<int> | |||
struct pair_index; | |||
} | |||
template<typename First, typename Second> | |||
struct pair : | |||
private intern::ebo<__impl::pair_index<0>, First>, | |||
private intern::ebo<__impl::pair_index<1>, Second> | |||
{ | |||
using tag = tag_pair; | |||
using this_type = pair<First, Second>; | |||
// default constructor | |||
template<typename... dummy, typename = enable_if_c< | |||
is_constructible<First, dummy...>::value && | |||
is_constructible<Second, dummy...>::value>> | |||
constexpr pair() | |||
: intern::ebo<__impl::pair_index<0>, First>() | |||
, intern::ebo<__impl::pair_index<1>, Second>() | |||
{ } | |||
// variadic constructors | |||
template<typename... dummy, typename = enable_if_c< | |||
is_constructible<First, const First&, dummy...>::value && | |||
is_constructible<Second, const Second&, dummy...>::value>> | |||
constexpr pair(First f, Second s) | |||
: intern::ebo<__impl::pair_index<0>, First>(f) | |||
, intern::ebo<__impl::pair_index<1>, Second>(s) | |||
{ } | |||
template<typename F, typename S, typename = enable_if_c< | |||
is_convertible<F&&, First>::value && | |||
is_convertible<S&&, Second>::value>> | |||
constexpr pair(F&& f, S&& s) | |||
: intern::ebo<__impl::pair_index<0>, First>(std::forward<F>(f)) | |||
, intern::ebo<__impl::pair_index<1>, Second>(std::forward<S>(s)) | |||
{ } | |||
// copy and move constructor | |||
template<typename F, typename S, typename = enable_if_c< | |||
is_constructible<First, const F&>::value && | |||
is_constructible<Second, const S&>::value && | |||
is_convertible<const F&, First>::value && | |||
is_convertible<const S&, Second>::value>> | |||
constexpr pair(const pair<F, S>& other) | |||
: intern::ebo<__impl::pair_index<0>, First>(mp::first(other)) | |||
, intern::ebo<__impl::pair_index<1>, Second>(mp::second(other)) | |||
{ } | |||
template<typename F, typename S, typename = enable_if_c< | |||
is_constructible<First, const F&>::value && | |||
is_constructible<Second, const S&>::value && | |||
is_convertible<const F&, First>::value && | |||
is_convertible<const S&, Second>::value>> | |||
constexpr pair(pair<F, S>&& other) | |||
: intern::ebo<__impl::pair_index<0>, First>(mp::first(std::forward<pair<F, S>>(other))) | |||
, intern::ebo<__impl::pair_index<1>, Second>(mp::second(std::forward<pair<F, S>>(other))) | |||
{ } | |||
// copy and move assignment | |||
template <typename F, typename S, typename = enable_if_c< | |||
is_assignable<First&, const F&>::value && | |||
is_assignable<Second&, const S&>::value>> | |||
constexpr pair& operator=(const pair<F, S>& other) { | |||
mp::first(*this) = mp::first(other); | |||
mp::second(*this) = mp::second(other); | |||
return *this; | |||
} | |||
template <typename F, typename S, typename = enable_if_c< | |||
is_assignable<First&, const F &>::value && | |||
is_assignable<Second&, const S &>::value>> | |||
constexpr pair& operator=(pair<F, S>&& other) { | |||
mp::first(*this) = mp::first(std::move<pair<F, S>>(other)); | |||
mp::second(*this) = mp::second(std::move<pair<F, S>>(other)); | |||
return *this; | |||
} | |||
constexpr auto first() const | |||
{ return mp::first(*this); } | |||
constexpr auto second() const | |||
{ return mp::second(*this); } | |||
// Prevent the compiler from defining the default copy and move | |||
// constructors, which interfere with the SFINAE above. | |||
~pair() = default; | |||
friend struct __impl::first_impl<tag_pair>; | |||
friend struct __impl::second_impl<tag_pair>; | |||
}; | |||
namespace intern { | |||
template<> | |||
struct operators_comparable<tag_pair> | |||
{ static constexpr bool value = true; }; | |||
template<> | |||
struct operators_orderable<tag_pair> | |||
{ static constexpr bool value = true; }; | |||
} | |||
namespace __impl | |||
{ | |||
/* tag_of */ | |||
template<typename First, typename Second> | |||
struct tag_of_impl<pair<First, Second>> | |||
{ using type = tag_pair; }; | |||
/* make */ | |||
template<> | |||
struct make_impl<tag_pair> | |||
{ | |||
template<typename F, typename S> | |||
static constexpr pair<decay_type<F>, decay_type<S>> apply(F&& f, S&& s) | |||
{ return { static_cast<F&&>(f), static_cast<S&&>(s) }; } | |||
}; | |||
/* first */ | |||
template<> | |||
struct first_impl<tag_pair> | |||
{ | |||
using type = int; | |||
template<typename First, typename Second> | |||
static constexpr auto apply(pair<First, Second>& p) | |||
{ | |||
return intern::ebo_get<pair_index<0>>( | |||
static_cast<intern::ebo<pair_index<0>, First>&>(p) | |||
); | |||
} | |||
template<typename First, typename Second> | |||
static constexpr auto apply(pair<First, Second>&& p) | |||
{ | |||
return intern::ebo_get<pair_index<0>>( | |||
static_cast<intern::ebo<pair_index<0>, First>&&>(p) | |||
); | |||
} | |||
template<typename First, typename Second> | |||
static constexpr auto apply(const pair<First, Second>& p) | |||
{ | |||
return intern::ebo_get<pair_index<0>>( | |||
static_cast<const intern::ebo<pair_index<0>, First>&>(p) | |||
); | |||
} | |||
}; | |||
/* second */ | |||
template<> | |||
struct second_impl<tag_pair> | |||
{ | |||
template<typename First, typename Second> | |||
static constexpr auto apply(pair<First, Second>& p) | |||
{ | |||
return intern::ebo_get<pair_index<1>>( | |||
static_cast<intern::ebo<pair_index<1>, Second>&>(p) | |||
); | |||
} | |||
template<typename First, typename Second> | |||
static constexpr auto apply(pair<First, Second>&& p) | |||
{ | |||
return intern::ebo_get<pair_index<1>>( | |||
static_cast<intern::ebo<pair_index<1>, Second>&&>(p) | |||
); | |||
} | |||
template<typename First, typename Second> | |||
static constexpr auto apply(const pair<First, Second>& p) | |||
{ | |||
return intern::ebo_get<pair_index<1>>( | |||
static_cast<const intern::ebo<pair_index<1>, Second>&>(p) | |||
); | |||
} | |||
}; | |||
/* equal */ | |||
template<> | |||
struct equal_impl<tag_pair, tag_pair> | |||
{ | |||
template<typename L, typename R> | |||
static constexpr auto apply(const L& l, const R& r) | |||
{ | |||
return and_( | |||
equal(first(l), first(r)), | |||
equal(second(l), second(r))); | |||
} | |||
}; | |||
/* less */ | |||
template<> | |||
struct less_impl<tag_pair, tag_pair> | |||
{ | |||
template<typename L, typename R> | |||
static constexpr auto apply(const L& l, const R& r) | |||
{ | |||
return or_( | |||
less(first(l), first(r)), | |||
and_( | |||
less_equal(first (l), first (r)), | |||
less (second(l), second(r)) | |||
) | |||
); | |||
} | |||
}; | |||
} | |||
} | |||
} |
@@ -1,268 +0,0 @@ | |||
#pragma once | |||
#include <utility> | |||
#include <cpputils/mp/misc/make.h> | |||
#include <cpputils/mp/core/const.h> | |||
#include <cpputils/mp/core/modifier.h> | |||
#include <cpputils/mp/operations/hash.fwd.h> | |||
#include <cpputils/mp/intern/operators_comparable.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl /* forward declaration */ | |||
{ | |||
template<typename T> | |||
struct type_impl; | |||
struct decl_type_t | |||
{ | |||
template<typename T> | |||
constexpr auto operator()(T&& t) const; | |||
}; | |||
struct type_id_t | |||
{ | |||
template <typename T> | |||
constexpr auto operator()(T&&) const; | |||
}; | |||
struct size_of_t | |||
{ | |||
template <typename T> | |||
constexpr auto operator()(T&&) const; | |||
}; | |||
struct align_of_t | |||
{ | |||
template <typename T> | |||
constexpr auto operator()(T&&) const; | |||
}; | |||
struct is_valid_type_t | |||
{ | |||
template <typename F> | |||
constexpr auto operator()(F&&) const; | |||
template <typename F, typename ...Args> | |||
constexpr auto operator()(F&&, Args&&...) const; | |||
}; | |||
template <template <typename ...> class F> | |||
struct tmplt_t; | |||
template <template <typename ...> class F> | |||
struct metafunction_t; | |||
template <typename F> | |||
struct metafunction_class_t | |||
: metafunction_t<F::template apply> | |||
{ }; | |||
template <typename F> | |||
struct integral_t; | |||
struct make_integral_t | |||
{ | |||
template <typename F> | |||
constexpr integral_t<F> operator()(F const&) const | |||
{ return { }; } | |||
}; | |||
} | |||
struct tag_type { }; | |||
template<typename T> | |||
using type = typename __impl::type_impl<T>::type; | |||
template<typename T> | |||
constexpr type<T> type_c { }; | |||
constexpr auto make_mp_type = make<tag_type>; | |||
constexpr __impl::decl_type_t decl_type { }; | |||
constexpr __impl::type_id_t type_id { }; | |||
constexpr __impl::size_of_t size_of { }; | |||
constexpr __impl::align_of_t align_of { }; | |||
constexpr __impl::is_valid_type_t is_valid_type { }; | |||
template <template <typename ...> class F> | |||
constexpr __impl::tmplt_t<F> tmplt { }; | |||
template <template <typename ...> class F> | |||
constexpr __impl::metafunction_t<F> metafunction { }; | |||
template <typename F> | |||
constexpr __impl::metafunction_class_t<F> metafunction_class { }; | |||
constexpr __impl::make_integral_t integral { }; | |||
template <template <typename ...> class F> | |||
constexpr auto trait = integral(metafunction<F>); | |||
namespace __impl /* implementation */ | |||
{ | |||
/* basic_type */ | |||
template<typename T> | |||
struct basic_type | |||
{ | |||
using tag = tag_type; | |||
using type = T; | |||
constexpr auto operator+() const | |||
{ return *this; } | |||
}; | |||
/* type */ | |||
template<typename T> | |||
struct type_impl | |||
{ | |||
struct type : basic_type<T> | |||
{ }; | |||
}; | |||
/* decl_type */ | |||
template <typename T, typename = tag_type> | |||
struct decltype_helper | |||
{ using type = remove_ref<T>; }; | |||
template <typename T> | |||
struct decltype_helper<T, tag_of<T>> | |||
{ using type = typename remove_ref<T>::type; }; | |||
template<typename T> | |||
constexpr auto decl_type_t::operator()(T&& t) const | |||
{ return type_c<typename decltype_helper<T>::type>; } | |||
/* type_id */ | |||
template <typename T, typename = tag_type> | |||
struct typeid_helper | |||
{ using type = clean_type<T>; }; | |||
template <typename T> | |||
struct typeid_helper<T, tag_of<T>> | |||
{ using type = typename remove_ref<T>::type; }; | |||
template <typename T> | |||
constexpr auto type_id_t::operator()(T&&) const | |||
{ return type_c<typename typeid_helper<T>::type>; } | |||
/* make */ | |||
template <> | |||
struct make_impl<tag_type> | |||
{ | |||
template <typename T> | |||
static constexpr auto apply(T&& t) | |||
{ return type_id(std::forward<T>(t)); } | |||
}; | |||
/* size_of */ | |||
template <typename T> | |||
constexpr auto size_of_t::operator()(T&&) const | |||
{ return c_size_t<sizeof(typename decltype_helper<T>::type)> { }; } | |||
/* align_of */ | |||
template <typename T> | |||
constexpr auto align_of_t::operator()(T&&) const | |||
{ return c_size_t<alignof(typename decltype_helper<T>::type)> { }; } | |||
/* is_valid_type */ | |||
template<typename F, typename... Args, typename = decltype(std::declval<F&&>()(std::declval<Args&&>()...))> | |||
constexpr auto is_valid_type_impl(int) | |||
{ return c_true; } | |||
template<typename F, typename... Args> | |||
constexpr auto is_valid_type_impl(...) | |||
{ return c_false; } | |||
template<typename F> | |||
struct is_valid_type_helper | |||
{ | |||
template<typename... Args> | |||
constexpr auto operator()(Args&&...) const | |||
{ return is_valid_type_impl<F, Args&&...>(int { }); } | |||
}; | |||
template <typename F> | |||
constexpr auto is_valid_type_t::operator()(F&&) const | |||
{ return is_valid_type_helper<F&&> { }; } | |||
template <typename F, typename ...Args> | |||
constexpr auto is_valid_type_t::operator()(F&&, Args&&...) const | |||
{ return is_valid_type_impl<F&&, Args&&...>(int { }); } | |||
/* tmplt */ | |||
template <template <typename ...> class F> | |||
struct tmplt_t | |||
{ | |||
template<typename... T> | |||
struct apply | |||
{ using type = F<T...>; }; | |||
template<typename... T> | |||
constexpr auto operator()(const T&...) const | |||
{ return type<F<typename T::type...>> { }; } | |||
}; | |||
/* metafunction */ | |||
template <template <typename ...> class F> | |||
struct metafunction_t | |||
{ | |||
template<typename... T> | |||
using apply = F<T...>; | |||
template<typename... T> | |||
constexpr type<typename F<typename T::type...>::type> operator()(const T&...) const | |||
{ return { }; } | |||
}; | |||
/* integral */ | |||
template <typename F> | |||
struct integral_t | |||
{ | |||
template<typename... T> | |||
constexpr auto operator()(const T& ...) const | |||
{ | |||
using result_type = typename F::template apply<typename T::type...>::type; | |||
return result_type { }; | |||
} | |||
}; | |||
/* equal */ | |||
template <> | |||
struct equal_impl<tag_type, tag_type> | |||
{ | |||
template <typename T, typename U> | |||
static constexpr auto apply(const basic_type<T>&, const basic_type<U>&) | |||
{ return c_false; } | |||
template <typename T> | |||
static constexpr auto apply(const basic_type<T>&, const basic_type<T>&) | |||
{ return c_true; } | |||
}; | |||
/* hash */ | |||
template<> | |||
struct hash_impl<tag_type> | |||
{ | |||
template <typename T> | |||
static constexpr T apply(const T& t) | |||
{ return t; } | |||
}; | |||
} | |||
namespace intern { | |||
template<> | |||
struct operators_comparable<tag_type> | |||
{ static constexpr bool value = true; }; | |||
} | |||
} | |||
} |
@@ -1,11 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/intern/comparable_equal.h> | |||
#include <cpputils/mp/intern/comparable_less.h> | |||
#include <cpputils/mp/intern/ebo.h> | |||
#include <cpputils/mp/intern/fold_left.h> | |||
#include <cpputils/mp/intern/fold_right.h> | |||
#include <cpputils/mp/intern/has_value.h> | |||
#include <cpputils/mp/intern/hash_table.h> | |||
#include <cpputils/mp/intern/operators_comparable.h> | |||
#include <cpputils/mp/intern/operators_orderable.h> |
@@ -1,39 +0,0 @@ | |||
#pragma once | |||
#include <utility> | |||
#include <cpputils/mp/core.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace intern { | |||
template<typename T, typename U = T, typename = void> | |||
struct comparable_equal | |||
: c_false_t | |||
{ }; | |||
template<typename T> | |||
struct comparable_equal<T, T, void_t< | |||
decltype(std::forward<T>(std::declval<T>()) == std::forward<T>(std::declval<T>()) ? 0 : 0), | |||
decltype(std::forward<T>(std::declval<T>()) != std::forward<T>(std::declval<T>()) ? 0 : 0)>> | |||
: c_true_t | |||
{ }; | |||
template <typename T, typename U> | |||
struct comparable_equal<T, U, enable_if_c< | |||
!is_same<T, U>::value, | |||
void_t< | |||
decltype(std::forward<T>(std::declval<T>()) == std::forward<U>(std::declval<U>()) ? 0 : 0), | |||
decltype(std::forward<U>(std::declval<U>()) == std::forward<T>(std::declval<T>()) ? 0 : 0), | |||
decltype(std::forward<T>(std::declval<T>()) != std::forward<U>(std::declval<U>()) ? 0 : 0), | |||
decltype(std::forward<U>(std::declval<U>()) != std::forward<T>(std::declval<T>()) ? 0 : 0), | |||
common_type<T, U>>>> | |||
: c_bool_t< | |||
comparable_equal<T>::value && | |||
comparable_equal<U>::value && | |||
comparable_equal<common_type<T, U>>::value> | |||
{ }; | |||
} | |||
} | |||
} |
@@ -1,36 +0,0 @@ | |||
#pragma once | |||
#include <utility> | |||
#include <cpputils/mp/core.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace intern { | |||
template<typename T, typename U = T, typename = void> | |||
struct comparable_less | |||
: c_false_t | |||
{ }; | |||
template<typename T> | |||
struct comparable_less<T, T, void_t< | |||
decltype(std::forward<T>(std::declval<T>()) < std::forward<T>(std::declval<T>()) ? 0 : 0)>> | |||
: c_true_t | |||
{ }; | |||
template <typename T, typename U> | |||
struct comparable_less<T, U, enable_if_c< | |||
!is_same<T, U>::value, | |||
void_t< | |||
decltype(std::forward<T>(std::declval<T>()) < std::forward<U>(std::declval<U>()) ? 0 : 0), | |||
decltype(std::forward<U>(std::declval<U>()) < std::forward<T>(std::declval<T>()) ? 0 : 0), | |||
common_type<T, U>>>> | |||
: c_bool_t< | |||
comparable_less<T>::value && | |||
comparable_less<U>::value && | |||
comparable_less<common_type<T, U>>::value> | |||
{ }; | |||
} | |||
} | |||
} |
@@ -1,83 +0,0 @@ | |||
#pragma once | |||
#include "../core.h" | |||
namespace utl { | |||
namespace mp { | |||
namespace intern { | |||
template<typename Key, typename Value, bool = is_empty<Value>::value && !is_final<Value>::value> | |||
struct ebo; | |||
template<typename Key, typename Value> | |||
constexpr const Value& ebo_get(const ebo<Key, Value, true>& x) | |||
{ return x; } | |||
template<typename Key, typename Value> | |||
constexpr Value& ebo_get(ebo<Key, Value, true>& x) | |||
{ return x; } | |||
template<typename Key, typename Value> | |||
constexpr Value&& ebo_get(ebo<Key, Value, true>&& x) | |||
{ return x; } | |||
template<typename Key, typename Value> | |||
constexpr const Value& ebo_get(const ebo<Key, Value, false>& x) | |||
{ return x._data; } | |||
template<typename Key, typename Value> | |||
constexpr Value& ebo_get(ebo<Key, Value, false>& x) | |||
{ return x._data; } | |||
template<typename Key, typename Value> | |||
constexpr Value&& ebo_get(ebo<Key, Value, false>&& x) | |||
{ return static_cast<Value&&>(x._data); } | |||
template<typename Key, typename Value> | |||
struct ebo<Key, Value, true> : | |||
public Value | |||
{ | |||
constexpr ebo() | |||
{ } | |||
template<typename T> | |||
explicit constexpr ebo(T&& t) : | |||
Value(std::forward<T>(t)) | |||
{ } | |||
constexpr auto get() const& | |||
{ return ebo_get(*this); } | |||
constexpr auto get() & | |||
{ return ebo_get(*this); } | |||
constexpr auto get() && | |||
{ return ebo_get(std::move(*this)); } | |||
}; | |||
template<typename Key, typename Value> | |||
struct ebo<Key, Value, false> | |||
{ | |||
Value _data; | |||
constexpr ebo() | |||
{ } | |||
template<typename T> | |||
explicit constexpr ebo(T&& t) : | |||
_data(std::forward<T>(t)) | |||
{ } | |||
constexpr auto get() const& | |||
{ return ebo_get(*this); } | |||
constexpr auto get() & | |||
{ return ebo_get(*this); } | |||
constexpr auto get() && | |||
{ return ebo_get(std::move(*this)); } | |||
}; | |||
} | |||
} | |||
} |
@@ -1,265 +0,0 @@ | |||
#pragma once | |||
#include <utility> | |||
#include <cpputils/mp/misc/when.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace intern { | |||
namespace __impl | |||
{ | |||
template <unsigned int n, typename = when<true>> | |||
struct fold_left_impl; | |||
template<> | |||
struct fold_left_impl<1> | |||
{ | |||
template<typename F, typename X1> | |||
static constexpr X1 apply(F&&, X1&& x1) | |||
{ return std::forward<X1>(x1); } | |||
}; | |||
template<> | |||
struct fold_left_impl<2> | |||
{ | |||
template<typename F, typename X1, typename X2> | |||
static constexpr auto apply(F&& f, X1&& x1, X2&& x2) | |||
{ | |||
return f( | |||
std::forward<X1>(x1), | |||
std::forward<X2>(x2)); | |||
} | |||
}; | |||
template<> | |||
struct fold_left_impl<3> | |||
{ | |||
template<typename F, typename X1, typename X2, typename X3> | |||
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3) | |||
{ | |||
return f(f( | |||
std::forward<X1>(x1), | |||
std::forward<X2>(x2)), | |||
std::forward<X3>(x3)); | |||
} | |||
}; | |||
template<> | |||
struct fold_left_impl<4> | |||
{ | |||
template<typename F, typename X1, typename X2, typename X3, typename X4> | |||
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4) | |||
{ | |||
return f(f(f( | |||
std::forward<X1>(x1), | |||
std::forward<X2>(x2)), | |||
std::forward<X3>(x3)), | |||
std::forward<X4>(x4)); | |||
} | |||
}; | |||
template<> | |||
struct fold_left_impl<5> | |||
{ | |||
template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5> | |||
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5) | |||
{ | |||
return f(f(f(f( | |||
std::forward<X1>(x1), | |||
std::forward<X2>(x2)), | |||
std::forward<X3>(x3)), | |||
std::forward<X4>(x4)), | |||
std::forward<X5>(x5)); | |||
} | |||
}; | |||
template<> | |||
struct fold_left_impl<6> | |||
{ | |||
template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6> | |||
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6) | |||
{ | |||
return f(f(f(f(f( | |||
std::forward<X1>(x1), | |||
std::forward<X2>(x2)), | |||
std::forward<X3>(x3)), | |||
std::forward<X4>(x4)), | |||
std::forward<X5>(x5)), | |||
std::forward<X6>(x6)); | |||
} | |||
}; | |||
template<> | |||
struct fold_left_impl<7> | |||
{ | |||
template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7> | |||
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7) | |||
{ | |||
return f(f(f(f(f(f( | |||
std::forward<X1>(x1), | |||
std::forward<X2>(x2)), | |||
std::forward<X3>(x3)), | |||
std::forward<X4>(x4)), | |||
std::forward<X5>(x5)), | |||
std::forward<X6>(x6)), | |||
std::forward<X7>(x7)); | |||
} | |||
}; | |||
template<> | |||
struct fold_left_impl<8> | |||
{ | |||
template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8> | |||
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8) | |||
{ | |||
return f(f(f(f(f(f(f( | |||
std::forward<X1>(x1), | |||
std::forward<X2>(x2)), | |||
std::forward<X3>(x3)), | |||
std::forward<X4>(x4)), | |||
std::forward<X5>(x5)), | |||
std::forward<X6>(x6)), | |||
std::forward<X7>(x7)), | |||
std::forward<X8>(x8)); | |||
} | |||
}; | |||
template<unsigned int n> | |||
struct fold_left_impl<n, when<(n >= 9) && (n < 18)>> | |||
{ | |||
template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8, typename X9, typename... Xn> | |||
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8, X9&& x9, Xn&&... xn) | |||
{ | |||
return fold_left_impl<sizeof...(xn) + 1>::apply( | |||
f, | |||
f(f(f(f(f(f(f(f( | |||
std::forward<X1>(x1), | |||
std::forward<X2>(x2)), | |||
std::forward<X3>(x3)), | |||
std::forward<X4>(x4)), | |||
std::forward<X5>(x5)), | |||
std::forward<X6>(x6)), | |||
std::forward<X7>(x7)), | |||
std::forward<X8>(x8)), | |||
std::forward<X9>(x9)), | |||
std::forward<Xn>(xn)... | |||
); | |||
} | |||
}; | |||
template<unsigned int n> | |||
struct fold_left_impl<n, when<(n >= 18) && (n < 36)>> | |||
{ | |||
template< | |||
typename F, | |||
typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8, typename X9, | |||
typename X10, typename X11, typename X12, typename X13, typename X14, typename X15, typename X16, typename X17, typename X18, | |||
typename... Xn> | |||
static constexpr auto apply( | |||
F&& f, | |||
X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8, X9&& x9, | |||
X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14, X15&& x15, X16&& x16, X17&& x17, X18&& x18, | |||
Xn&&... xn) | |||
{ | |||
return fold_left_impl<sizeof...(xn) + 1>::apply( | |||
f, | |||
f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f( | |||
std::forward<X1> (x1), | |||
std::forward<X2> (x2)), | |||
std::forward<X3> (x3)), | |||
std::forward<X4> (x4)), | |||
std::forward<X5> (x5)), | |||
std::forward<X6> (x6)), | |||
std::forward<X7> (x7)), | |||
std::forward<X8> (x8)), | |||
std::forward<X9> (x9)), | |||
std::forward<X10>(x10)), | |||
std::forward<X11>(x11)), | |||
std::forward<X12>(x12)), | |||
std::forward<X13>(x13)), | |||
std::forward<X14>(x14)), | |||
std::forward<X15>(x15)), | |||
std::forward<X16>(x16)), | |||
std::forward<X17>(x17)), | |||
std::forward<X18>(x18)), | |||
std::forward<Xn>(xn)... | |||
); | |||
} | |||
}; | |||
template<unsigned int n> | |||
struct fold_left_impl<n, when<(n >= 36)>> | |||
{ | |||
template< | |||
typename F, | |||
typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8, typename X9, | |||
typename X10, typename X11, typename X12, typename X13, typename X14, typename X15, typename X16, typename X17, typename X18, | |||
typename X19, typename X20, typename X21, typename X22, typename X23, typename X24, typename X25, typename X26, typename X27, | |||
typename X28, typename X29, typename X30, typename X31, typename X32, typename X33, typename X34, typename X35, typename X36, | |||
typename... Xn> | |||
static constexpr auto apply( | |||
F&& f, | |||
X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8, X9&& x9, | |||
X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14, X15&& x15, X16&& x16, X17&& x17, X18&& x18, | |||
X19&& x19, X20&& x20, X21&& x21, X22&& x22, X23&& x23, X24&& x24, X25&& x25, X26&& x26, X27&& x27, | |||
X28&& x28, X29&& x29, X30&& x30, X31&& x31, X32&& x32, X33&& x33, X34&& x34, X35&& x35, X36&& x36, | |||
Xn&&... xn) | |||
{ | |||
return fold_left_impl<sizeof...(xn) + 1>::apply( | |||
f, | |||
f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f( | |||
std::forward<X1> (x1), | |||
std::forward<X2> (x2)), | |||
std::forward<X3> (x3)), | |||
std::forward<X4> (x4)), | |||
std::forward<X5> (x5)), | |||
std::forward<X6> (x6)), | |||
std::forward<X7> (x7)), | |||
std::forward<X8> (x8)), | |||
std::forward<X9> (x9)), | |||
std::forward<X10>(x10)), | |||
std::forward<X11>(x11)), | |||
std::forward<X12>(x12)), | |||
std::forward<X13>(x13)), | |||
std::forward<X14>(x14)), | |||
std::forward<X15>(x15)), | |||
std::forward<X16>(x16)), | |||
std::forward<X17>(x17)), | |||
std::forward<X18>(x18)), | |||
std::forward<X19>(x19)), | |||
std::forward<X20>(x20)), | |||
std::forward<X21>(x21)), | |||
std::forward<X22>(x22)), | |||
std::forward<X23>(x23)), | |||
std::forward<X24>(x24)), | |||
std::forward<X25>(x25)), | |||
std::forward<X26>(x26)), | |||
std::forward<X27>(x27)), | |||
std::forward<X28>(x28)), | |||
std::forward<X29>(x29)), | |||
std::forward<X30>(x30)), | |||
std::forward<X31>(x31)), | |||
std::forward<X32>(x32)), | |||
std::forward<X33>(x33)), | |||
std::forward<X34>(x34)), | |||
std::forward<X35>(x35)), | |||
std::forward<X36>(x36)), | |||
std::forward<Xn>(xn)... | |||
); | |||
} | |||
}; | |||
struct fold_left_t | |||
{ | |||
template<typename F, typename X1, typename... Xn> | |||
constexpr auto operator()(F&& f, X1&& x1, Xn&&... xn) const | |||
{ return fold_left_impl<sizeof...(xn) + 1>::apply(std::forward<F>(f), std::forward<X1>(x1), std::forward<Xn>(xn)...); } | |||
}; | |||
} | |||
constexpr __impl::fold_left_t fold_left { }; | |||
} | |||
} | |||
} |
@@ -1,244 +0,0 @@ | |||
#pragma once | |||
#include <utility> | |||
#include <cpputils/mp/misc/when.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace intern { | |||
namespace __impl | |||
{ | |||
template <unsigned int n, typename = when<true>> | |||
struct fold_right_impl; | |||
template<> | |||
struct fold_right_impl<1> | |||
{ | |||
template<typename F, typename X1> | |||
static constexpr X1 apply(F&&, X1&& x1) | |||
{ return std::forward<X1>(x1); } | |||
}; | |||
template<> | |||
struct fold_right_impl<2> | |||
{ | |||
template<typename F, typename X1, typename X2> | |||
static constexpr auto apply(F&& f, X1&& x1, X2&& x2) | |||
{ | |||
return f( | |||
std::forward<X1>(x1), | |||
std::forward<X2>(x2)); | |||
} | |||
}; | |||
template<> | |||
struct fold_right_impl<3> | |||
{ | |||
template<typename F, typename X1, typename X2, typename X3> | |||
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3) | |||
{ | |||
return f(std::forward<X1>(x1), | |||
f(std::forward<X2>(x2), | |||
std::forward<X3>(x3))); | |||
} | |||
}; | |||
template<> | |||
struct fold_right_impl<4> | |||
{ | |||
template<typename F, typename X1, typename X2, typename X3, typename X4> | |||
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4) | |||
{ | |||
return f(std::forward<X1>(x1), | |||
f(std::forward<X2>(x2), | |||
f(std::forward<X3>(x3), | |||
std::forward<X4>(x4)))); | |||
} | |||
}; | |||
template<> | |||
struct fold_right_impl<5> | |||
{ | |||
template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5> | |||
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5) | |||
{ | |||
return f(std::forward<X1>(x1), | |||
f(std::forward<X2>(x2), | |||
f(std::forward<X3>(x3), | |||
f(std::forward<X4>(x4), | |||
std::forward<X5>(x5))))); | |||
} | |||
}; | |||
template<> | |||
struct fold_right_impl<6> | |||
{ | |||
template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6> | |||
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6) | |||
{ | |||
return f(std::forward<X1>(x1), | |||
f(std::forward<X2>(x2), | |||
f(std::forward<X3>(x3), | |||
f(std::forward<X4>(x4), | |||
f(std::forward<X5>(x5), | |||
std::forward<X6>(x6)))))); | |||
} | |||
}; | |||
template<> | |||
struct fold_right_impl<7> | |||
{ | |||
template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7> | |||
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7) | |||
{ | |||
return f(std::forward<X1>(x1), | |||
f(std::forward<X2>(x2), | |||
f(std::forward<X3>(x3), | |||
f(std::forward<X4>(x4), | |||
f(std::forward<X5>(x5), | |||
f(std::forward<X6>(x6), | |||
std::forward<X7>(x7))))))); | |||
} | |||
}; | |||
template<> | |||
struct fold_right_impl<8> | |||
{ | |||
template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8> | |||
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8) | |||
{ | |||
return f(std::forward<X1>(x1), | |||
f(std::forward<X2>(x2), | |||
f(std::forward<X3>(x3), | |||
f(std::forward<X4>(x4), | |||
f(std::forward<X5>(x5), | |||
f(std::forward<X6>(x6), | |||
f(std::forward<X7>(x7), | |||
std::forward<X8>(x8)))))))); | |||
} | |||
}; | |||
template<unsigned int n> | |||
struct fold_right_impl<n, when<(n >= 9) && (n < 18)>> | |||
{ | |||
template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8, typename X9, typename... Xn> | |||
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8, X9&& x9, Xn&&... xn) | |||
{ | |||
return f(std::forward<X1>(x1), | |||
f(std::forward<X2>(x2), | |||
f(std::forward<X3>(x3), | |||
f(std::forward<X4>(x4), | |||
f(std::forward<X5>(x5), | |||
f(std::forward<X6>(x6), | |||
f(std::forward<X7>(x7), | |||
f(std::forward<X8>(x8), | |||
fold_right_impl<sizeof...(xn) + 1>::apply(f, std::forward<X9>(x9), std::forward<Xn>(xn)...))))))))); | |||
} | |||
}; | |||
template<unsigned int n> | |||
struct fold_right_impl<n, when<(n >= 18) && (n < 36)>> | |||
{ | |||
template< | |||
typename F, | |||
typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8, typename X9, | |||
typename X10, typename X11, typename X12, typename X13, typename X14, typename X15, typename X16, typename X17, typename X18, | |||
typename... Xn> | |||
static constexpr auto apply( | |||
F&& f, | |||
X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8, X9&& x9, | |||
X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14, X15&& x15, X16&& x16, X17&& x17, X18&& x18, | |||
Xn&&... xn) | |||
{ | |||
return f(std::forward<X1> (x1), | |||
f(std::forward<X2> (x2), | |||
f(std::forward<X3> (x3), | |||
f(std::forward<X4> (x4), | |||
f(std::forward<X5> (x5), | |||
f(std::forward<X6> (x6), | |||
f(std::forward<X7> (x7), | |||
f(std::forward<X8> (x8), | |||
f(std::forward<X9> (x9), | |||
f(std::forward<X10>(x10), | |||
f(std::forward<X11>(x11), | |||
f(std::forward<X12>(x12), | |||
f(std::forward<X13>(x13), | |||
f(std::forward<X14>(x14), | |||
f(std::forward<X15>(x15), | |||
f(std::forward<X16>(x16), | |||
f(std::forward<X17>(x17), | |||
fold_right_impl<sizeof...(xn) + 1>::apply(f, std::forward<X18>(x18), std::forward<Xn>(xn)...)))))))))))))))))); | |||
} | |||
}; | |||
template<unsigned int n> | |||
struct fold_right_impl<n, when<(n >= 36)>> | |||
{ | |||
template< | |||
typename F, | |||
typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8, typename X9, | |||
typename X10, typename X11, typename X12, typename X13, typename X14, typename X15, typename X16, typename X17, typename X18, | |||
typename X19, typename X20, typename X21, typename X22, typename X23, typename X24, typename X25, typename X26, typename X27, | |||
typename X28, typename X29, typename X30, typename X31, typename X32, typename X33, typename X34, typename X35, typename X36, | |||
typename... Xn> | |||
static constexpr auto apply( | |||
F&& f, | |||
X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8, X9&& x9, | |||
X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14, X15&& x15, X16&& x16, X17&& x17, X18&& x18, | |||
X19&& x19, X20&& x20, X21&& x21, X22&& x22, X23&& x23, X24&& x24, X25&& x25, X26&& x26, X27&& x27, | |||
X28&& x28, X29&& x29, X30&& x30, X31&& x31, X32&& x32, X33&& x33, X34&& x34, X35&& x35, X36&& x36, | |||
Xn&&... xn) | |||
{ | |||
return f(std::forward<X1> (x1), | |||
f(std::forward<X2> (x2), | |||
f(std::forward<X3> (x3), | |||
f(std::forward<X4> (x4), | |||
f(std::forward<X5> (x5), | |||
f(std::forward<X6> (x6), | |||
f(std::forward<X7> (x7), | |||
f(std::forward<X8> (x8), | |||
f(std::forward<X9> (x9), | |||
f(std::forward<X10>(x10), | |||
f(std::forward<X11>(x11), | |||
f(std::forward<X12>(x12), | |||
f(std::forward<X13>(x13), | |||
f(std::forward<X14>(x14), | |||
f(std::forward<X15>(x15), | |||
f(std::forward<X16>(x16), | |||
f(std::forward<X17>(x17), | |||
f(std::forward<X18>(x18), | |||
f(std::forward<X19>(x19), | |||
f(std::forward<X20>(x20), | |||
f(std::forward<X21>(x21), | |||
f(std::forward<X22>(x22), | |||
f(std::forward<X23>(x23), | |||
f(std::forward<X24>(x24), | |||
f(std::forward<X25>(x25), | |||
f(std::forward<X26>(x26), | |||
f(std::forward<X27>(x27), | |||
f(std::forward<X28>(x28), | |||
f(std::forward<X29>(x29), | |||
f(std::forward<X30>(x30), | |||
f(std::forward<X31>(x31), | |||
f(std::forward<X32>(x32), | |||
f(std::forward<X33>(x33), | |||
f(std::forward<X34>(x34), | |||
f(std::forward<X35>(x35), | |||
fold_right_impl<sizeof...(xn) + 1>::apply(f, std::forward<X36>(x36), std::forward<Xn>(xn)...)))))))))))))))))))))))))))))))))))); | |||
} | |||
}; | |||
struct fold_right_t | |||
{ | |||
template<typename F, typename X1, typename... Xn> | |||
constexpr auto operator()(F&& f, X1&& x1, Xn&&... xn) const | |||
{ return fold_right_impl<sizeof...(xn) + 1>::apply(std::forward<F>(f), std::forward<X1>(x1), std::forward<Xn>(xn)...); } | |||
}; | |||
} | |||
constexpr __impl::fold_right_t fold_right { }; | |||
} | |||
} | |||
} |
@@ -1,16 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/operations/value.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace intern { | |||
template<typename C> | |||
struct has_value | |||
: c_bool_t<!is_default<::utl::mp::__impl::value_impl<tag_of<C>>>::value> | |||
{ }; | |||
} | |||
} | |||
} |
@@ -1,61 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/operations/hash.h> | |||
#include <cpputils/mp/operations/compare/equal.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace intern { | |||
namespace __impl | |||
{ | |||
template<typename H, size_t... I> | |||
struct bucket { }; | |||
template<typename... Buckets> | |||
struct hash_table | |||
: Buckets... | |||
{ }; | |||
/* find indices */ | |||
template<typename Hash, size_t... I> | |||
std::index_sequence<I...> find_indices_impl(const bucket<Hash, I...>&); | |||
template<typename Hash> | |||
std::index_sequence<> find_indices_impl(...); | |||
/* find index */ | |||
template<template<size_t> class KeyAtIndex, typename Key> | |||
struct find_pred | |||
{ | |||
template<typename Index> | |||
auto operator()(const Index&) const -> | |||
decltype(equal(std::declval<KeyAtIndex<Index::value>>(), std::declval<Key>())); | |||
}; | |||
template<typename Indices, typename Key, template<size_t> class KeyAtIndex> | |||
struct find_index_impl | |||
{ using type = decltype(find_if(Indices { }, find_pred<KeyAtIndex, Key> { })); }; | |||
} | |||
template<typename Map, typename Key> | |||
struct find_indices | |||
{ | |||
using hash = typename decltype(hash(std::declval<Key>()))::type; | |||
using type = decltype(__impl::find_indices_impl<hash>(std::declval<Map>())); | |||
}; | |||
template<template<size_t> class KeyAtIndex, size_t N, typename Indices = std::make_index_sequence<N>> | |||
struct make_hash_table; | |||
template<template<size_t> class KeyAtIndex, size_t N, size_t... I> | |||
struct make_hash_table<KeyAtIndex, N, std::index_sequence<I...>> | |||
{ | |||
using type = __impl::hash_table< | |||
__impl::bucket<typename decltype(hash(std::declval<KeyAtIndex<I>>()))::type, I>... | |||
>; | |||
}; | |||
} | |||
} | |||
} |
@@ -1,36 +0,0 @@ | |||
#pragma once | |||
#include <utility> | |||
#include <cpputils/mp/core/conditionals.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/operations/compare/equal.h> | |||
#include <cpputils/mp/operations/compare/not_equal.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace intern { | |||
template<typename T> | |||
struct operators_comparable | |||
{ static constexpr bool value = false; }; | |||
} | |||
namespace operators | |||
{ | |||
template<typename X, typename Y, typename = enable_if_c< | |||
intern::operators_comparable<tag_of<X>>::value && | |||
intern::operators_comparable<tag_of<Y>>::value>> | |||
constexpr auto operator == (X&& x, Y&& y) | |||
{ return equal(std::forward<X>(x), std::forward<Y>(y)); } | |||
template<typename X, typename Y, typename = enable_if_c< | |||
intern::operators_comparable<tag_of<X>>::value && | |||
intern::operators_comparable<tag_of<Y>>::value>> | |||
constexpr auto operator != (X&& x, Y&& y) | |||
{ return not_equal(std::forward<X>(x), std::forward<Y>(y)); } | |||
} | |||
} | |||
} |
@@ -1,50 +0,0 @@ | |||
#pragma once | |||
#include <utility> | |||
#include <cpputils/mp/core/conditionals.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/operations/compare/less.h> | |||
#include <cpputils/mp/operations/compare/less_equal.h> | |||
#include <cpputils/mp/operations/compare/greater.h> | |||
#include <cpputils/mp/operations/compare/greater_equal.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace intern { | |||
template<typename T> | |||
struct operators_orderable | |||
{ static constexpr bool value = false; }; | |||
} | |||
namespace operators | |||
{ | |||
template<typename X, typename Y, typename = enable_if_c< | |||
intern::operators_orderable<tag_of<X>>::value && | |||
intern::operators_orderable<tag_of<Y>>::value>> | |||
constexpr auto operator < (X&& x, Y&& y) | |||
{ return less(std::forward<X>(x), std::forward<Y>(y)); } | |||
template<typename X, typename Y, typename = enable_if_c< | |||
intern::operators_orderable<tag_of<X>>::value && | |||
intern::operators_orderable<tag_of<Y>>::value>> | |||
constexpr auto operator <= (X&& x, Y&& y) | |||
{ return less_equal(std::forward<X>(x), std::forward<Y>(y)); } | |||
template<typename X, typename Y, typename = enable_if_c< | |||
intern::operators_orderable<tag_of<X>>::value && | |||
intern::operators_orderable<tag_of<Y>>::value>> | |||
constexpr auto operator > (X&& x, Y&& y) | |||
{ return greater(std::forward<X>(x), std::forward<Y>(y)); } | |||
template<typename X, typename Y, typename = enable_if_c< | |||
intern::operators_orderable<tag_of<X>>::value && | |||
intern::operators_orderable<tag_of<Y>>::value>> | |||
constexpr auto operator >= (X&& x, Y&& y) | |||
{ return greater_equal(std::forward<X>(x), std::forward<Y>(y)); } | |||
} | |||
} | |||
} |
@@ -1,8 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/misc/default.h> | |||
#include <cpputils/mp/misc/is_a.h> | |||
#include <cpputils/mp/misc/make.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/to.h> |
@@ -1,33 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/core/const.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl /* forward declaration */ | |||
{ | |||
template<typename T, typename = void> | |||
struct is_default_impl; | |||
} | |||
template<typename T> | |||
using is_default = __impl::is_default_impl<T>; | |||
namespace __impl /* implementation */ | |||
{ | |||
struct default_ { }; | |||
template<typename T, typename> | |||
struct is_default_impl : | |||
public c_false_t | |||
{ }; | |||
template<typename T> | |||
struct is_default_impl<T, decltype((void)static_cast<default_>(std::declval<T>()))> : | |||
public c_true_t | |||
{ }; | |||
} | |||
} | |||
} |
@@ -1,38 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl /* forward declaration */ | |||
{ | |||
template<typename Tag, typename ...T> | |||
struct is_a_impl; | |||
} | |||
template<typename Tag, typename... T> | |||
constexpr __impl::is_a_impl<Tag, T...> is_a { }; | |||
template<typename Tag, typename... T> | |||
constexpr __impl::is_a_impl<Tag, T...> is_an { }; | |||
namespace __impl /* implementation */ | |||
{ | |||
template<typename Tag, typename T> | |||
struct is_a_impl<Tag, T> : | |||
public is_same<Tag, tag_of<T>> | |||
{ }; | |||
template<typename Tag> | |||
struct is_a_impl<Tag> | |||
{ | |||
template<typename T> | |||
constexpr auto operator()(const T&) const noexcept | |||
{ return is_a<Tag, T>; } | |||
}; | |||
} | |||
} | |||
} |
@@ -1,55 +0,0 @@ | |||
#pragma once | |||
#include <utility> | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/default.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl /* forward declaration */ | |||
{ | |||
template<typename Tag> | |||
struct make_t; | |||
} | |||
template<typename Tag> | |||
constexpr __impl::make_t<Tag> make { }; | |||
namespace __impl /* implementation */ | |||
{ | |||
template<typename T, typename = void> | |||
struct make_impl : | |||
public make_impl<T, when<true>> | |||
{ }; | |||
template<typename T, bool condition> | |||
struct make_impl<T, when<condition>> : | |||
public default_ | |||
{ | |||
template<typename... X> | |||
static constexpr auto make_helper(int, X&&... x) | |||
-> decltype(T(std::forward<X>(x)...)) | |||
{ return T(std::forward<X>(x)...); } | |||
template<typename... X> | |||
static constexpr auto make_helper(long, X&&... x) | |||
{ static_assert((sizeof...(X), false), "there exists no constructor for the given data type"); } | |||
template <typename... X> | |||
static constexpr auto apply(X&& ...x) | |||
{ return make_helper(int{}, std::forward<X>(x)...); } | |||
}; | |||
template<typename T> | |||
struct make_t | |||
{ | |||
template<typename... X> | |||
constexpr auto operator()(X&&... x) const noexcept | |||
{ return make_impl<T>::apply(std::forward<X>(x)...); } | |||
}; | |||
} | |||
} | |||
} |
@@ -1,35 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/core/modifier.h> | |||
#include <cpputils/mp/misc/when.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl /* forward declaration */ | |||
{ | |||
template<typename T, typename = void> | |||
struct tag_of_impl; | |||
} | |||
template<typename T> | |||
using tag_of = typename __impl::tag_of_impl<clean_type<T>>::type; | |||
namespace __impl /* implementation */ | |||
{ | |||
template<typename T, typename> | |||
struct tag_of_impl : | |||
public tag_of_impl<T, when<true>> | |||
{ }; | |||
template<typename T, bool condition> | |||
struct tag_of_impl<T, when<condition>> | |||
{ using type = T; }; | |||
template<typename T> | |||
struct tag_of_impl<T, when_valid<typename clean_type<T>::tag>> | |||
{ using type = typename clean_type<T>::tag; }; | |||
} | |||
} | |||
} |
@@ -1,176 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/core/conditionals.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl /* forward declaration */ | |||
{ | |||
template<typename To> | |||
struct to_t; | |||
template <typename From, typename To, typename = void> | |||
struct is_mp_convertible_impl; | |||
template <typename From, typename To, typename = void> | |||
struct is_embedded_impl; | |||
} | |||
template<typename To> | |||
constexpr __impl::to_t<To> to { }; | |||
template <typename From, typename To> | |||
using is_mp_convertible = __impl::is_mp_convertible_impl<From, To>; | |||
template <typename From, typename To> | |||
using is_embedded = __impl::is_embedded_impl<From, To>; | |||
namespace __impl /* implementation */ | |||
{ | |||
struct no_conversion { }; | |||
template <bool = true> | |||
struct embedding { }; | |||
/* to_impl */ | |||
template <typename To, typename From, typename = void> | |||
struct to_impl; | |||
template <typename To, typename From, typename> | |||
struct to_impl : | |||
public to_impl<To, From, when<true>> | |||
{ }; | |||
template <typename To, typename From, bool condition> | |||
struct to_impl<To, From, when<condition>> : | |||
public no_conversion | |||
{ | |||
template <typename X> | |||
static constexpr auto apply(const X&) | |||
{ static_assert(wrong<to_impl<To, From>, X> { }, "no conversion is available between the provided types"); } | |||
}; | |||
template <typename To, typename From> | |||
struct to_impl<To, From, when_valid<decltype(static_cast<To>(std::declval<From>()))>> | |||
{ | |||
template <typename X> | |||
static constexpr To apply(X&& x) | |||
{ return static_cast<To>(std::forward<X>(x)); } | |||
}; | |||
template <typename To> | |||
struct to_impl<To, To> : | |||
public embedding<> | |||
{ | |||
template <typename X> | |||
static constexpr X apply(X&& x) | |||
{ return std::forward<X&&>(x); } | |||
}; | |||
template <typename T> | |||
struct to_impl<T*, decltype(nullptr)> : | |||
public embedding<> | |||
{ | |||
static constexpr T* apply(decltype(nullptr)) | |||
{ return nullptr; } | |||
}; | |||
/* to_t */ | |||
template <typename To> | |||
struct to_t | |||
{ | |||
template <typename X> | |||
constexpr auto operator()(X&& x) const | |||
{ | |||
using From = tag_of<X>; | |||
return to_impl<To, From>::apply(std::forward<X>(x)); | |||
} | |||
}; | |||
#define DEFINE_EMBEDDING_IMPL(TO, FROM) \ | |||
template <> \ | |||
struct to_impl<TO, FROM> : \ | |||
public embedding<> \ | |||
{ \ | |||
static constexpr TO apply(FROM x) \ | |||
{ return static_cast<TO>(x); } \ | |||
} | |||
DEFINE_EMBEDDING_IMPL(long double, double); | |||
DEFINE_EMBEDDING_IMPL(long double, float); | |||
DEFINE_EMBEDDING_IMPL(double , float); | |||
DEFINE_EMBEDDING_IMPL(signed long long, signed long); | |||
DEFINE_EMBEDDING_IMPL(signed long long, signed int); | |||
DEFINE_EMBEDDING_IMPL(signed long long, signed short); | |||
DEFINE_EMBEDDING_IMPL(signed long long, signed char); | |||
DEFINE_EMBEDDING_IMPL(signed long , signed int); | |||
DEFINE_EMBEDDING_IMPL(signed long , signed short); | |||
DEFINE_EMBEDDING_IMPL(signed long , signed char); | |||
DEFINE_EMBEDDING_IMPL(signed int , signed short); | |||
DEFINE_EMBEDDING_IMPL(signed int , signed char); | |||
DEFINE_EMBEDDING_IMPL(signed short , signed char); | |||
DEFINE_EMBEDDING_IMPL(unsigned long long, unsigned long); | |||
DEFINE_EMBEDDING_IMPL(unsigned long long, unsigned int); | |||
DEFINE_EMBEDDING_IMPL(unsigned long long, unsigned short); | |||
DEFINE_EMBEDDING_IMPL(unsigned long long, unsigned char); | |||
DEFINE_EMBEDDING_IMPL(unsigned long , unsigned int); | |||
DEFINE_EMBEDDING_IMPL(unsigned long , unsigned short); | |||
DEFINE_EMBEDDING_IMPL(unsigned long , unsigned char); | |||
DEFINE_EMBEDDING_IMPL(unsigned int , unsigned short); | |||
DEFINE_EMBEDDING_IMPL(unsigned int , unsigned char); | |||
DEFINE_EMBEDDING_IMPL(unsigned short , unsigned char); | |||
#undef DEFINE_EMBEDDING_IMPL | |||
template<class T> | |||
using copy_char_signedness = if_t< | |||
std::is_signed<char>, | |||
typename std::make_signed<T>::type, | |||
typename std::make_unsigned<T>::type>; | |||
#define DEFINE_CHAR_EMBEDDING_IMPL(TO) \ | |||
template <> \ | |||
struct to_impl<copy_char_signedness<TO>, char> \ | |||
: public embedding<> \ | |||
{ \ | |||
static constexpr copy_char_signedness<TO> apply(char x) \ | |||
{ return static_cast<TO>(x); } \ | |||
} | |||
DEFINE_CHAR_EMBEDDING_IMPL(long long); | |||
DEFINE_CHAR_EMBEDDING_IMPL(long); | |||
DEFINE_CHAR_EMBEDDING_IMPL(int); | |||
DEFINE_CHAR_EMBEDDING_IMPL(short); | |||
#undef DEFINE_CHAR_EMBEDDING_IMPL | |||
/* is_mp_convertible_impl */ | |||
template <typename From, typename To, typename> | |||
struct is_mp_convertible_impl : | |||
public std::true_type | |||
{ }; | |||
template <typename From, typename To> | |||
struct is_mp_convertible_impl<From, To, decltype((void) static_cast<no_conversion>(std::declval<to_impl<To, From>>()))> : | |||
public std::false_type | |||
{ }; | |||
/* is_embedded_impl */ | |||
template <typename From, typename To, typename> | |||
struct is_embedded_impl : | |||
public std::false_type | |||
{ }; | |||
template <typename From, typename To> | |||
struct is_embedded_impl<From, To, decltype((void) static_cast<embedding<true>>(std::declval<to_impl<To, From>>()))> : | |||
public std::true_type | |||
{ }; | |||
} | |||
} | |||
} |
@@ -1,32 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/core/checker.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl /* forward declaration */ | |||
{ | |||
template<typename...> | |||
struct wrong_impl; | |||
} | |||
template<bool condition> | |||
struct when; | |||
template<typename... T> | |||
using when_valid = when<is_valid<T...>::value>; | |||
template<typename... T> | |||
using wrong = __impl::wrong_impl<T...>; | |||
namespace __impl /* implementation */ | |||
{ | |||
template<typename...> | |||
struct wrong_impl : | |||
public c_false_t | |||
{ }; | |||
} | |||
} | |||
} |
@@ -1,15 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/operations/at.h> | |||
#include <cpputils/mp/operations/compare.h> | |||
#include <cpputils/mp/operations/eval_if.h> | |||
#include <cpputils/mp/operations/eval.h> | |||
#include <cpputils/mp/operations/first.h> | |||
#include <cpputils/mp/operations/hash.h> | |||
#include <cpputils/mp/operations/if.h> | |||
#include <cpputils/mp/operations/length.h> | |||
#include <cpputils/mp/operations/logical.h> | |||
#include <cpputils/mp/operations/second.h> | |||
#include <cpputils/mp/operations/transform.h> | |||
#include <cpputils/mp/operations/unpack.h> | |||
#include <cpputils/mp/operations/value.h> |
@@ -1,52 +0,0 @@ | |||
#pragma once | |||
#include <utility> | |||
#include <cpputils/mp/core/const.h> | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/default.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl | |||
{ | |||
struct at_t | |||
{ | |||
template<typename Xs, typename N> | |||
constexpr auto operator()(Xs&& xs, const N& n) const; | |||
}; | |||
} | |||
constexpr __impl::at_t at { }; | |||
template<size_t N, typename Xs> | |||
constexpr auto at_c(Xs&& xs) | |||
{ return at(std::forward<Xs>(xs), c_size_t<N> { }); } | |||
namespace __impl | |||
{ | |||
template <typename T, typename = void> | |||
struct at_impl | |||
: at_impl<T, when<true>> | |||
{ }; | |||
template <typename T, bool condition> | |||
struct at_impl<T, when<condition>> | |||
: default_ | |||
{ | |||
template <typename ...Args> | |||
static constexpr auto apply(Args&& ...) = delete; | |||
}; | |||
template<typename Xs, typename N> | |||
constexpr auto at_t::operator()(Xs&& xs, const N& n) const | |||
{ | |||
using tag_type = tag_of<Xs>; | |||
using at_impl_type = at_impl<tag_type>; | |||
return at_impl_type::apply(std::forward<Xs>(xs), n); | |||
} | |||
} | |||
} | |||
} |
@@ -1,4 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/operations/compare/equal.h> | |||
#include <cpputils/mp/operations/compare/not_equal.h> |
@@ -1,73 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/core/const.h> | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/default.h> | |||
#include <cpputils/mp/intern/has_value.h> | |||
#include <cpputils/mp/intern/comparable_equal.h> | |||
#include <cpputils/mp/operations/if.h> | |||
#include <cpputils/mp/operations/value.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl | |||
{ | |||
struct equal_t | |||
{ | |||
template<typename L, typename R> | |||
constexpr auto operator()(const L& l, const R& r) const; | |||
}; | |||
} | |||
constexpr __impl::equal_t equal { }; | |||
namespace __impl | |||
{ | |||
template <typename L, typename R, typename = void> | |||
struct equal_impl | |||
: equal_impl<L, R, when<true>> | |||
{ }; | |||
template <typename L, typename R, bool condition> | |||
struct equal_impl<L, R, when<condition>> | |||
: default_ | |||
{ | |||
template <typename ...Args> | |||
static constexpr auto apply(Args&& ...) | |||
{ return c_false; } | |||
}; | |||
template <typename T, typename U> | |||
struct equal_impl<T, U, when<intern::comparable_equal<T, U>::value>> | |||
{ | |||
template <typename X, typename Y> | |||
static constexpr auto apply(X&& x, Y&& y) | |||
{ return static_cast<X&&>(x) == static_cast<Y&&>(y); } | |||
}; | |||
template <typename C> | |||
struct equal_impl<C, C, when<intern::has_value<C>::value>> | |||
{ | |||
template <typename X, typename Y> | |||
static constexpr auto apply(const X&, const Y&) | |||
{ | |||
constexpr auto eq = equal(value<X>(), value<Y>()); | |||
constexpr bool truth_value = if_ (eq, true, false); | |||
return c_bool_t<truth_value> { }; | |||
} | |||
}; | |||
template<typename L, typename R> | |||
constexpr auto equal_t::operator()(const L& l, const R& r) const | |||
{ | |||
using l_tag_type = tag_of<L>; | |||
using r_tag_type = tag_of<R>; | |||
using equal_type = equal_impl<l_tag_type, r_tag_type>; | |||
return equal_type::apply(l, r); | |||
} | |||
} | |||
} | |||
} |
@@ -1,51 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/core/const.h> | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/default.h> | |||
#include <cpputils/mp/operations/logical/not.h> | |||
#include <cpputils/mp/operations/compare/less.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl | |||
{ | |||
struct greater_t | |||
{ | |||
template<typename L, typename R> | |||
constexpr auto operator()(const L& l, const R& r) const; | |||
}; | |||
} | |||
constexpr __impl::greater_t greater { }; | |||
namespace __impl | |||
{ | |||
template <typename L, typename R, typename = void> | |||
struct greater_impl | |||
: greater_impl<L, R, when<true>> | |||
{ }; | |||
template <typename T, typename U, bool condition> | |||
struct greater_impl<T, U, when<condition>> | |||
: default_ | |||
{ | |||
template <typename X, typename Y> | |||
static constexpr auto apply(X&& x, Y&& y) | |||
{ return less(static_cast<Y&&>(y), static_cast<X&&>(x)); } | |||
}; | |||
template<typename L, typename R> | |||
constexpr auto greater_t::operator()(const L& l, const R& r) const | |||
{ | |||
using l_tag_type = tag_of<L>; | |||
using r_tag_type = tag_of<R>; | |||
using greater_impl_type = greater_impl<l_tag_type, r_tag_type>; | |||
return greater_impl_type::apply(l, r); | |||
} | |||
} | |||
} | |||
} |
@@ -1,51 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/core/const.h> | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/default.h> | |||
#include <cpputils/mp/operations/logical/not.h> | |||
#include <cpputils/mp/operations/compare/less.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl | |||
{ | |||
struct greater_equal_t | |||
{ | |||
template<typename L, typename R> | |||
constexpr auto operator()(const L& l, const R& r) const; | |||
}; | |||
} | |||
constexpr __impl::greater_equal_t greater_equal { }; | |||
namespace __impl | |||
{ | |||
template <typename L, typename R, typename = void> | |||
struct greater_equal_impl | |||
: greater_equal_impl<L, R, when<true>> | |||
{ }; | |||
template <typename T, typename U, bool condition> | |||
struct greater_equal_impl<T, U, when<condition>> | |||
: default_ | |||
{ | |||
template <typename X, typename Y> | |||
static constexpr auto apply(X&& x, Y&& y) | |||
{ return not_(less(static_cast<X&&>(x), static_cast<Y&&>(y))); } | |||
}; | |||
template<typename L, typename R> | |||
constexpr auto greater_equal_t::operator()(const L& l, const R& r) const | |||
{ | |||
using l_tag_type = tag_of<L>; | |||
using r_tag_type = tag_of<R>; | |||
using greater_equal_impl_type = greater_equal_impl<l_tag_type, r_tag_type>; | |||
return greater_equal_impl_type::apply(l, r); | |||
} | |||
} | |||
} | |||
} |
@@ -1,73 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/core/const.h> | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/default.h> | |||
#include <cpputils/mp/intern/has_value.h> | |||
#include <cpputils/mp/intern/comparable_less.h> | |||
#include <cpputils/mp/operations/if.h> | |||
#include <cpputils/mp/operations/value.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl | |||
{ | |||
struct less_t | |||
{ | |||
template<typename L, typename R> | |||
constexpr auto operator()(const L& l, const R& r) const; | |||
}; | |||
} | |||
constexpr __impl::less_t less { }; | |||
namespace __impl | |||
{ | |||
template <typename L, typename R, typename = void> | |||
struct less_impl | |||
: less_impl<L, R, when<true>> | |||
{ }; | |||
template <typename L, typename R, bool condition> | |||
struct less_impl<L, R, when<condition>> | |||
: default_ | |||
{ | |||
template <typename ...Args> | |||
static constexpr auto apply(Args&& ...) | |||
{ return c_false; } | |||
}; | |||
template <typename T, typename U> | |||
struct less_impl<T, U, when<intern::comparable_less<T, U>::value>> | |||
{ | |||
template <typename X, typename Y> | |||
static constexpr auto apply(X&& x, Y&& y) | |||
{ return static_cast<X&&>(x) < static_cast<Y&&>(y); } | |||
}; | |||
template <typename C> | |||
struct less_impl<C, C, when<intern::has_value<C>::value>> | |||
{ | |||
template <typename X, typename Y> | |||
static constexpr auto apply(const X&, const Y&) | |||
{ | |||
constexpr auto eq = less(value<X>(), value<Y>()); | |||
constexpr bool truth_value = if_ (eq, true, false); | |||
return c_bool_t<truth_value> { }; | |||
} | |||
}; | |||
template<typename L, typename R> | |||
constexpr auto less_t::operator()(const L& l, const R& r) const | |||
{ | |||
using l_tag_type = tag_of<L>; | |||
using r_tag_type = tag_of<R>; | |||
using less_type = less_impl<l_tag_type, r_tag_type>; | |||
return less_type::apply(l, r); | |||
} | |||
} | |||
} | |||
} |
@@ -1,51 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/core/const.h> | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/default.h> | |||
#include <cpputils/mp/operations/logical/not.h> | |||
#include <cpputils/mp/operations/compare/less.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl | |||
{ | |||
struct less_equal_t | |||
{ | |||
template<typename L, typename R> | |||
constexpr auto operator()(const L& l, const R& r) const; | |||
}; | |||
} | |||
constexpr __impl::less_equal_t less_equal { }; | |||
namespace __impl | |||
{ | |||
template <typename L, typename R, typename = void> | |||
struct less_equal_impl | |||
: less_equal_impl<L, R, when<true>> | |||
{ }; | |||
template <typename T, typename U, bool condition> | |||
struct less_equal_impl<T, U, when<condition>> | |||
: default_ | |||
{ | |||
template <typename X, typename Y> | |||
static constexpr auto apply(X&& x, Y&& y) | |||
{ return not_(less(static_cast<Y&&>(y), static_cast<X&&>(x))); } | |||
}; | |||
template<typename L, typename R> | |||
constexpr auto less_equal_t::operator()(const L& l, const R& r) const | |||
{ | |||
using l_tag_type = tag_of<L>; | |||
using r_tag_type = tag_of<R>; | |||
using less_equal_impl_type = less_equal_impl<l_tag_type, r_tag_type>; | |||
return less_equal_impl_type::apply(l, r); | |||
} | |||
} | |||
} | |||
} |
@@ -1,51 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/core/const.h> | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/default.h> | |||
#include <cpputils/mp/operations/logical/not.h> | |||
#include <cpputils/mp/operations/compare/not_equal.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl | |||
{ | |||
struct not_equal_t | |||
{ | |||
template<typename L, typename R> | |||
constexpr auto operator()(const L& l, const R& r) const; | |||
}; | |||
} | |||
constexpr __impl::not_equal_t not_equal { }; | |||
namespace __impl | |||
{ | |||
template <typename L, typename R, typename = void> | |||
struct not_equal_impl | |||
: not_equal_impl<L, R, when<true>> | |||
{ }; | |||
template <typename L, typename R, bool condition> | |||
struct not_equal_impl<L, R, when<condition>> | |||
: default_ | |||
{ | |||
template <typename X, typename Y> | |||
static constexpr auto apply(X&& x, Y&& y) | |||
{ return not(equal(std::forward<X>(x), std::forward<Y>(y))); } | |||
}; | |||
template<typename L, typename R> | |||
constexpr auto not_equal_t::operator()(const L& l, const R& r) const | |||
{ | |||
using l_tag_type = tag_of<L>; | |||
using r_tag_type = tag_of<R>; | |||
using not_equal_type = not_equal_impl<l_tag_type, r_tag_type>; | |||
return not_equal_type::apply(l, r); | |||
} | |||
} | |||
} | |||
} |
@@ -1,59 +0,0 @@ | |||
#pragma once | |||
#include <utility> | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/default.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl | |||
{ | |||
struct eval_t | |||
{ | |||
template <typename Expr> | |||
constexpr auto operator()(Expr&& expr) const; | |||
}; | |||
} | |||
constexpr __impl::eval_t eval { }; | |||
namespace __impl | |||
{ | |||
template <typename T, typename = void> | |||
struct eval_impl | |||
: eval_impl<T, when<true>> | |||
{ }; | |||
template <typename T, bool condition> | |||
struct eval_impl<T, when<condition>> | |||
: default_ | |||
{ | |||
template <typename Expr> | |||
static constexpr auto eval_helper(Expr&& expr, int) | |||
{ return static_cast<Expr&&>(expr)(); } | |||
template <typename Expr> | |||
static constexpr auto eval_helper(Expr&&, ...) | |||
{ | |||
static_assert(wrong<Expr> { }, | |||
"eval(expr) requires the expression to be a a nullary Callable"); | |||
} | |||
template <typename Expr> | |||
static constexpr decltype(auto) apply(Expr&& expr) | |||
{ return eval_helper(static_cast<Expr&&>(expr), int { }); } | |||
}; | |||
template <typename Expr> | |||
constexpr auto eval_t::operator()(Expr&& expr) const | |||
{ | |||
using tag_type = tag_of<Expr>; | |||
using eval_impl_type = eval_impl<tag_type>; | |||
return eval_impl_type::apply(std::forward<Expr>(expr));; | |||
} | |||
} | |||
} | |||
} |
@@ -1,80 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/default.h> | |||
#include <cpputils/mp/intern/has_value.h> | |||
#include <cpputils/mp/operations/if.fwd.h> | |||
#include <cpputils/mp/operations/eval.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl | |||
{ | |||
struct eval_if_t | |||
{ | |||
template <typename Cond, typename Then, typename Else> | |||
constexpr auto operator()(Cond&& c, Then&& t, Else&& e) const; | |||
}; | |||
} | |||
constexpr __impl::eval_if_t eval_if { }; | |||
namespace __impl | |||
{ | |||
template <typename T, typename = void> | |||
struct eval_if_impl | |||
: eval_if_impl<T, when<true>> | |||
{ }; | |||
template <typename T, bool condition> | |||
struct eval_if_impl<T, when<condition>> | |||
: default_ | |||
{ | |||
template <typename ...Args> | |||
static constexpr auto apply(Args&& ...) = delete; | |||
}; | |||
template <typename T> | |||
struct eval_if_impl<T, when<is_arithmetic<T>::value>> | |||
{ | |||
template <typename Cond, typename Then, typename Else> | |||
static constexpr auto apply(const Cond& cond, Then&& t, Else&& e) | |||
{ | |||
return cond ? eval(std::forward<Then>(t)) | |||
: eval(std::forward<Else>(e)); | |||
} | |||
}; | |||
template <typename T> | |||
struct eval_if_impl<T, when<intern::has_value<T>::value>> | |||
{ | |||
template<typename Then, typename Else> | |||
static constexpr auto eval_if_helper(c_true_t, Then&& t, Else&& e) | |||
{ return eval(std::forward<Then>(t)); } | |||
template<typename Then, typename Else> | |||
static constexpr auto eval_if_helper(c_false_t, Then&& t, Else&& e) | |||
{ return eval(std::forward<Else>(e)); } | |||
template <typename Cond, typename Then, typename Else> | |||
static constexpr auto apply(const Cond&, Then&& t, Else&& e) | |||
{ | |||
constexpr auto cond = value<Cond>(); | |||
constexpr bool truth_value = if_(cond, true, false); | |||
return eval_if_helper(c_bool_t<truth_value> { }, std::forward<Then>(t), std::forward<Else>(e)); | |||
} | |||
}; | |||
template <typename Cond, typename Then, typename Else> | |||
constexpr auto eval_if_t::operator()(Cond&& c, Then&& t, Else&& e) const | |||
{ | |||
using tag_type = tag_of<Cond>; | |||
using eval_if_type = eval_if_impl<tag_type>; | |||
return eval_if_type::apply(std::forward<Cond>(c), std::forward<Then>(t), std::forward<Else>(e)); | |||
} | |||
} | |||
} | |||
} |
@@ -1,46 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/default.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl | |||
{ | |||
struct first_t | |||
{ | |||
template<typename T> | |||
constexpr auto operator()(T&& t) const; | |||
}; | |||
} | |||
constexpr __impl::first_t first { }; | |||
namespace __impl | |||
{ | |||
template <typename T, typename = void> | |||
struct first_impl | |||
: first_impl<T, when<true>> | |||
{ }; | |||
template <typename T, bool condition> | |||
struct first_impl<T, when<condition>> | |||
: default_ | |||
{ | |||
template <typename ...Args> | |||
static constexpr auto apply(Args&& ...) = delete; | |||
}; | |||
template<typename T> | |||
constexpr auto first_t::operator()(T&& t) const | |||
{ | |||
using tag_type = tag_of<T>; | |||
using first_type = first_impl<tag_type>; | |||
return first_type::apply(std::forward<T>(t)); | |||
} | |||
} | |||
} | |||
} |
@@ -1,28 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/default.h> | |||
#include <cpputils/mp/core/const.h> | |||
#include <cpputils/mp/core/modifier.h> | |||
#include <cpputils/mp/container/type.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl /* forward declaration */ | |||
{ | |||
struct hash_t | |||
{ | |||
template<typename X> | |||
constexpr auto operator()(const X& x) const; | |||
}; | |||
template <typename T, typename = void> | |||
struct hash_impl; | |||
} | |||
constexpr __impl::hash_t hash { }; | |||
} | |||
} |
@@ -1,104 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/default.h> | |||
#include <cpputils/mp/core/const.h> | |||
#include <cpputils/mp/core/modifier.h> | |||
#include <cpputils/mp/core/conditionals.h> | |||
#include <cpputils/mp/container/type.h> | |||
#include <cpputils/mp/operations/hash.fwd.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl /* implementation */ | |||
{ | |||
template <typename T, typename = void> | |||
struct hash_integral_helper; | |||
template <typename Member, typename T> | |||
struct hash_integral_helper<Member T::*> | |||
{ | |||
template <typename X> | |||
static constexpr auto apply(X const&) | |||
{ return type_c<integral_constant<Member T::*, X::value>>; } | |||
}; | |||
template <typename T> | |||
struct hash_integral_helper<T, enable_if<is_signed<T>>> | |||
{ | |||
template <typename X> | |||
static constexpr auto apply(X const&) | |||
{ | |||
constexpr signed long long x = X::value; | |||
return type_c<integral_constant<signed long long, x>>; | |||
} | |||
}; | |||
template <typename T> | |||
struct hash_integral_helper<T, enable_if<is_unsigned<T>>> | |||
{ | |||
template <typename X> | |||
static constexpr auto apply(X const&) | |||
{ | |||
constexpr unsigned long long x = X::value; | |||
return type_c<integral_constant<unsigned long long, x>>; | |||
} | |||
}; | |||
template <> | |||
struct hash_integral_helper<bool> | |||
{ | |||
template <typename X> | |||
static constexpr auto apply(X const&) | |||
{ return type_c<c_bool_t<X::value>>; } | |||
}; | |||
template <> | |||
struct hash_integral_helper<char> | |||
{ | |||
template <typename X> | |||
static constexpr auto apply(X const&) | |||
{ | |||
using T = if_c<is_signed<char>::value, signed long long, unsigned long long>; | |||
constexpr T x = X::value; | |||
return type_c<integral_constant<T, x>>; | |||
} | |||
}; | |||
template <typename T, typename> | |||
struct hash_impl | |||
: hash_impl<T, when<true>> | |||
{ }; | |||
template <typename Tag, bool condition> | |||
struct hash_impl<Tag, when<condition>> | |||
: default_ | |||
{ | |||
template <typename X> | |||
static constexpr auto apply(X const&) = delete; | |||
}; | |||
template <typename T> | |||
struct hash_impl<tag_integral_constant<T>, when<true>> | |||
{ | |||
template<typename X> | |||
static constexpr auto apply(const X& x) | |||
{ | |||
using type = remove_cv<decltype(X::value)>; | |||
return hash_integral_helper<type>::apply(x); | |||
} | |||
}; | |||
template<typename X> | |||
constexpr auto hash_t::operator()(const X& x) const | |||
{ | |||
using tag_type = tag_of<X>; | |||
using hash_impl_type = hash_impl<tag_type>; | |||
return hash_impl_type::apply(x); | |||
} | |||
} | |||
} | |||
} |
@@ -1,18 +0,0 @@ | |||
#pragma once | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl | |||
{ | |||
struct if_t | |||
{ | |||
template <typename Cond, typename Then, typename Else> | |||
constexpr auto operator()(Cond&& c, Then&& t, Else&& e) const; | |||
}; | |||
} | |||
constexpr __impl::if_t if_ { }; | |||
} | |||
} |
@@ -1,52 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/operations/if.fwd.h> | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/default.h> | |||
#include <cpputils/mp/operations/eval_if.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl | |||
{ | |||
template <typename T> | |||
struct hold { | |||
T value; | |||
constexpr T&& operator()() && | |||
{ return static_cast<T&&>(value); } | |||
}; | |||
template <typename L, typename = void> | |||
struct if_impl | |||
: if_impl<L, when<true>> | |||
{ }; | |||
template <typename L, bool condition> | |||
struct if_impl<L, when<condition>> | |||
: default_ | |||
{ | |||
template <typename Cond, typename Then, typename Else> | |||
static constexpr auto apply(Cond&& c, Then&& t, Else&& e) | |||
{ | |||
return eval_if( | |||
std::forward<Cond>(c), | |||
hold<Then&&> { static_cast<Then&&>(t) }, | |||
hold<Else&&> { static_cast<Else&&>(e) } | |||
); | |||
} | |||
}; | |||
template <typename Cond, typename Then, typename Else> | |||
constexpr auto if_t::operator()(Cond&& c, Then&& t, Else&& e) const | |||
{ | |||
using tag_type = tag_of<Cond>; | |||
using if_type = if_impl<tag_type>; | |||
return if_type::apply(std::forward<Cond>(c), std::forward<Then>(t), std::forward<Else>(e)); | |||
} | |||
} | |||
} | |||
} |
@@ -1,56 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/core/const.h> | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/default.h> | |||
#include <cpputils/mp/operations/unpack.fwd.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl | |||
{ | |||
struct length_t | |||
{ | |||
template<typename Xs> | |||
constexpr auto operator()(const Xs& xs) const; | |||
}; | |||
} | |||
constexpr __impl::length_t length { }; | |||
namespace __impl | |||
{ | |||
struct length_argn | |||
{ | |||
template<typename... Xn> | |||
constexpr c_size_t<sizeof...(Xn)> operator()(const Xn& ...) const | |||
{ return { }; } | |||
}; | |||
template <typename T, typename = void> | |||
struct length_impl | |||
: length_impl<T, when<true>> | |||
{ }; | |||
template<typename T, bool condition> | |||
struct length_impl<T, when<condition>> | |||
: default_ | |||
{ | |||
template<typename Xs> | |||
static constexpr auto apply(const Xs& xs) | |||
{ return unpack(xs, length_argn { }); } | |||
}; | |||
template<typename Xs> | |||
constexpr auto length_t::operator()(const Xs& xs) const | |||
{ | |||
using tag_type = tag_of<Xs>; | |||
using length_impl_type = length_impl<tag_type>; | |||
return length_impl_type::apply(xs); | |||
} | |||
} | |||
} | |||
} |
@@ -1,4 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/operations/logical/not.h> | |||
#include <cpputils/mp/operations/logical/and.h> |
@@ -1,63 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/core/const.h> | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/default.h> | |||
#include <cpputils/mp/operations/if.h> | |||
#include <cpputils/mp/intern/fold_left.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl | |||
{ | |||
struct and_t | |||
{ | |||
template<typename X, typename Y> | |||
constexpr auto operator()(X&& x, Y&& y) const; | |||
template<typename X, typename... Y> | |||
constexpr auto operator()(X&& x, Y&&... y) const; | |||
}; | |||
} | |||
constexpr __impl::and_t and_ { }; | |||
namespace __impl | |||
{ | |||
template <typename T, typename = void> | |||
struct and_impl | |||
: and_impl<T, when<true>> | |||
{ }; | |||
template <typename T, bool condition> | |||
struct and_impl<T, when<condition>> | |||
: default_ | |||
{ | |||
template <typename X, typename Y> | |||
static constexpr auto apply(X&& x, Y&& y) | |||
{ return if_(x, static_cast<Y&&>(y), x); } | |||
}; | |||
template <typename X, typename Y> | |||
constexpr auto and_t::operator()(X&& x, Y&& y) const | |||
{ | |||
using tag_type = tag_of<X>; | |||
using and_impl_type = and_impl<tag_type>; | |||
return and_impl_type::apply(std::forward<X>(x), std::forward<Y>(y)); | |||
}; | |||
template <typename X, typename ...Y> | |||
constexpr auto and_t::operator()(X&& x, Y&& ...y) const | |||
{ | |||
return intern::fold_left( | |||
*this, | |||
static_cast<X&&>(x), | |||
static_cast<Y&&>(y)... | |||
); | |||
} | |||
} | |||
} | |||
} |
@@ -1,55 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/core/const.h> | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/default.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl | |||
{ | |||
struct not_t | |||
{ | |||
template<typename X> | |||
constexpr auto operator()(X&& x) const; | |||
}; | |||
} | |||
constexpr __impl::not_t not_ { }; | |||
namespace __impl | |||
{ | |||
template <typename T, typename = void> | |||
struct not_impl | |||
: not_impl<T, when<true>> | |||
{ }; | |||
template <typename T, bool condition> | |||
struct not_impl<T, when<condition>> | |||
: default_ | |||
{ | |||
template <typename ...Args> | |||
static constexpr auto apply(Args&& ...) = delete; | |||
}; | |||
template <typename T> | |||
struct not_impl<T, when<is_arithmetic<T>::value>> | |||
{ | |||
template <typename X> | |||
static constexpr auto apply(const X& x) | |||
{ return x ? false : true; } | |||
}; | |||
template <typename X> | |||
constexpr auto not_t::operator()(X&& x) const | |||
{ | |||
using tag_type = tag_of<X>; | |||
using not_impl_type = not_impl<tag_type>; | |||
return not_impl_type::apply(std::forward<X>(x)); | |||
}; | |||
} | |||
} | |||
} |
@@ -1,63 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/core/const.h> | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/default.h> | |||
#include <cpputils/mp/operations/if.h> | |||
#include <cpputils/mp/intern/fold_left.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl | |||
{ | |||
struct or_t | |||
{ | |||
template<typename X, typename Y> | |||
constexpr auto operator()(X&& x, Y&& y) const; | |||
template<typename X, typename... Y> | |||
constexpr auto operator()(X&& x, Y&&... y) const; | |||
}; | |||
} | |||
constexpr __impl::or_t or_ { }; | |||
namespace __impl | |||
{ | |||
template <typename T, typename = void> | |||
struct or_impl | |||
: or_impl<T, when<true>> | |||
{ }; | |||
template <typename T, bool condition> | |||
struct or_impl<T, when<condition>> | |||
: default_ | |||
{ | |||
template <typename X, typename Y> | |||
static constexpr auto apply(X&& x, Y&& y) | |||
{ return if_(x, x, static_cast<Y&&>(y)); } | |||
}; | |||
template <typename X, typename Y> | |||
constexpr auto or_t::operator()(X&& x, Y&& y) const | |||
{ | |||
using tag_type = tag_of<X>; | |||
using or_impl_type = or_impl<tag_type>; | |||
return or_impl_type::apply(std::forward<X>(x), std::forward<Y>(y)); | |||
}; | |||
template <typename X, typename ...Y> | |||
constexpr auto or_t::operator()(X&& x, Y&& ...y) const | |||
{ | |||
return intern::fold_left( | |||
*this, | |||
static_cast<X&&>(x), | |||
static_cast<Y&&>(y)... | |||
); | |||
} | |||
} | |||
} | |||
} |
@@ -1,46 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/default.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl | |||
{ | |||
struct second_t | |||
{ | |||
template<typename T> | |||
constexpr auto operator()(T&& t) const; | |||
}; | |||
} | |||
constexpr __impl::second_t second { }; | |||
namespace __impl | |||
{ | |||
template <typename T, typename = void> | |||
struct second_impl | |||
: second_impl<T, when<true>> | |||
{ }; | |||
template <typename T, bool condition> | |||
struct second_impl<T, when<condition>> | |||
: default_ | |||
{ | |||
template <typename ...Args> | |||
static constexpr auto apply(Args&& ...) = delete; | |||
}; | |||
template<typename T> | |||
constexpr auto second_t::operator()(T&& t) const | |||
{ | |||
using tag = tag_of<T>; | |||
using second = second_impl<tag>; | |||
return second::apply(std::forward<T>(t)); | |||
} | |||
} | |||
} | |||
} |
@@ -1,68 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/make.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/default.h> | |||
#include <cpputils/mp/operations/unpack.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl | |||
{ | |||
struct transform_t | |||
{ | |||
template<typename Xs, typename F> | |||
constexpr auto operator()(Xs&& xs, F&& f) const; | |||
}; | |||
} | |||
constexpr __impl::transform_t transform { }; | |||
namespace __impl | |||
{ | |||
template<typename Xs, typename = void> | |||
struct transform_impl | |||
: transform_impl<Xs, when<true>> | |||
{ }; | |||
template<typename T, bool condition> | |||
struct transform_impl<T, when<condition>> | |||
: default_ | |||
{ | |||
template<typename Xs, typename F> | |||
static constexpr auto apply(Xs&& xs, F&& f) = delete; | |||
}; | |||
template<typename T> | |||
struct transform_impl<T, when<!is_default<unpack_impl<tag_of<T>>>::value>> | |||
{ | |||
using tag_type = tag_of<T>; | |||
template<typename F> | |||
struct transformer | |||
{ | |||
F f; | |||
template<typename... Xn> | |||
constexpr auto operator()(Xn&&... xn) const | |||
{ return make<tag_type>((*f)(std::forward<Xn>(xn))...); } | |||
}; | |||
template<typename Xs, typename F> | |||
static constexpr auto apply(Xs&& xs, F&& f) | |||
{ return unpack(std::forward<Xs>(xs), transformer<decltype(&f)> { &f }); } | |||
}; | |||
template<typename Xs, typename F> | |||
constexpr auto transform_t::operator()(Xs&& xs, F&& f) const | |||
{ | |||
using tag_type = tag_of<Xs>; | |||
using transform_impl_type = transform_impl<tag_type>; | |||
return transform_impl_type::apply(std::forward<Xs>(xs), std::forward<F>(f)); | |||
} | |||
} | |||
} | |||
} |
@@ -1,18 +0,0 @@ | |||
#pragma once | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl | |||
{ | |||
struct unpack_t | |||
{ | |||
template<typename Xs, typename F> | |||
constexpr auto operator()(Xs&& xs, F&& f) const; | |||
}; | |||
} | |||
constexpr __impl::unpack_t unpack { }; | |||
} | |||
} |
@@ -1,61 +0,0 @@ | |||
#pragma once | |||
#include <utility> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/default.h> | |||
#include <cpputils/mp/operations/at.h> | |||
#include <cpputils/mp/operations/length.h> | |||
#include <cpputils/mp/operations/unpack.fwd.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl | |||
{ | |||
template<typename T, typename = void> | |||
struct unpack_impl | |||
: unpack_impl<T, when<true>> | |||
{ }; | |||
template<typename T> | |||
struct unpack_impl<T, when< | |||
!is_default<length_impl<tag_of<T>>>::value && | |||
!is_default<at_impl <tag_of<T>>>::value>> | |||
{ | |||
template<typename Xs, typename F, size_t... I> | |||
static constexpr auto unpack_helper(Xs&& xs, F&& f, std::index_sequence<I...>) | |||
{ return std::forward<F>(f)(at_c<I>(std::forward<Xs>(xs))...); } | |||
template<typename Xs, typename F> | |||
static constexpr auto apply(Xs&& xs, F&& f) | |||
{ | |||
constexpr size_t N = decltype(length(xs))::value; | |||
return unpack_helper(std::forward<Xs>(xs), std::forward<F>(f), std::make_index_sequence<N> { }); | |||
} | |||
}; | |||
template<typename T, size_t N> | |||
struct unpack_impl<T[N]> | |||
{ | |||
template<typename Xs, typename F, size_t... I> | |||
static constexpr auto unpack_helper(Xs&& xs, F&& f, std::index_sequence<I...>) | |||
{ return std::forward<F>(f)(std::forward<Xs>(xs)[I]...); } | |||
template<typename Xs, typename F> | |||
static constexpr auto apply(Xs&& xs, F&& f) | |||
{ return unpack_helper(std::forward<Xs>(xs), std::forward<F>(f), std::make_index_sequence<N> { }); } | |||
}; | |||
// TODO: Pair, Struct | |||
template<typename Xs, typename F> | |||
constexpr auto unpack_t::operator()(Xs&& xs, F&& f) const | |||
{ | |||
using tag_type = tag_of<Xs>; | |||
using unpack_impl_type = unpack_impl<tag_type>; | |||
return unpack_impl_type::apply(std::forward<Xs>(xs), std::forward<F>(f)); | |||
} | |||
} | |||
} | |||
} |
@@ -1,54 +0,0 @@ | |||
#pragma once | |||
#include <cpputils/mp/misc/when.h> | |||
#include <cpputils/mp/misc/tag_of.h> | |||
#include <cpputils/mp/misc/default.h> | |||
namespace utl { | |||
namespace mp { | |||
namespace __impl | |||
{ | |||
template<typename T, typename = void> | |||
struct value_impl; | |||
} | |||
template <typename T> | |||
constexpr auto value() | |||
{ | |||
using t_clean_type = clean_type<T>; | |||
using tag_type = tag_of<T>; | |||
using value_impl_type = __impl::value_impl<tag_type>; | |||
return value_impl_type::template apply<t_clean_type>(); | |||
} | |||
template <typename T> | |||
constexpr decltype(auto) value(T const&) | |||
{ return value<T>(); } | |||
namespace __impl | |||
{ | |||
template <typename T, typename> | |||
struct value_impl | |||
: value_impl<T, when<true>> | |||
{ }; | |||
template <typename T, bool condition> | |||
struct value_impl<T, when<condition>> | |||
: default_ | |||
{ | |||
template <typename ...Args> | |||
static constexpr auto apply(Args&& ...args) = delete; | |||
}; | |||
template <typename T> | |||
struct value_impl<tag_integral_constant<T>> | |||
{ | |||
template <typename C> | |||
static constexpr auto apply() | |||
{ return C::value; } | |||
}; | |||
} | |||
} | |||
} |
@@ -1,41 +0,0 @@ | |||
#include <cpputils/mp/core/const.h> | |||
#include <cpputils/mp/container/basic_tuple.h> | |||
using namespace ::utl::mp; | |||
namespace test_mp_container_basic_tuple | |||
{ | |||
struct op_unpack | |||
{ | |||
constexpr auto operator()(const c_bool_t<false>&, const c_size_t<5>&) | |||
{ return true; } | |||
}; | |||
template<typename T> | |||
struct Wrapper { }; | |||
struct op_transform | |||
{ | |||
template<typename T> | |||
constexpr auto operator()(T&& t) | |||
{ return Wrapper<clean_type<T>> { }; } | |||
}; | |||
constexpr auto my_tuple = make_basic_tuple(c_bool_t<false> { }, c_size_t<5> { }); | |||
constexpr c_size_t<0> index0; | |||
constexpr c_size_t<1> index1; | |||
static_assert(unpack(my_tuple, op_unpack { }), ""); | |||
static_assert(my_tuple.unpack(op_unpack { }), ""); | |||
static_assert(decltype(at(my_tuple, index0))::value == false, ""); | |||
static_assert(decltype(at(my_tuple, index1))::value == 5, ""); | |||
static_assert(decltype(my_tuple.at(index0))::value == false, ""); | |||
static_assert(decltype(my_tuple.at(index1))::value == 5, ""); | |||
constexpr auto transformed = my_tuple.transform(op_transform { }); | |||
using transformed_type = clean_type<decltype(transformed)>; | |||
using transformed_expected = basic_tuple<Wrapper<c_bool_t<false>>, Wrapper<c_size_t<5>>>; | |||
static_assert(is_same<transformed_type, transformed_expected>::value, ""); | |||
} |
@@ -1,61 +0,0 @@ | |||
#include <cpputils/mp/container/pair.h> | |||
#include <cpputils/mp/operations/compare/equal.h> | |||
#include <cpputils/mp/operations/compare/not_equal.h> | |||
#include <cpputils/mp/operations/compare/less.h> | |||
#include <cpputils/mp/operations/compare/less_equal.h> | |||
#include <cpputils/mp/operations/compare/greater.h> | |||
#include <cpputils/mp/operations/compare/greater_equal.h> | |||
using namespace ::utl::mp; | |||
using namespace ::utl::mp::operators; | |||
namespace test_mp_container_pair | |||
{ | |||
constexpr auto my_pair = make_pair(1, 'x'); | |||
static_assert(first(my_pair) == 1, ""); | |||
static_assert(second(my_pair) == 'x', ""); | |||
static_assert(my_pair.first() == 1, ""); | |||
static_assert(my_pair.second() == 'x', ""); | |||
static_assert(equal(make_pair(1, 'x'), make_pair(1, 'x')), ""); | |||
static_assert( make_pair(1, 'x') == make_pair(1, 'x'), ""); | |||
static_assert(not_equal(make_pair(1, 'x'), make_pair(2, 'x')), ""); | |||
static_assert( make_pair(1, 'x') != make_pair(2, 'x'), ""); | |||
static_assert(less(make_pair(1, 'x'), make_pair(1, 'y')), ""); | |||
static_assert(less(make_pair(1, 'x'), make_pair(2, 'x')), ""); | |||
static_assert(less(make_pair(1, 'x'), make_pair(2, 'a')), ""); | |||
static_assert(make_pair(1, 'x') < make_pair(1, 'y'), ""); | |||
static_assert(make_pair(1, 'x') < make_pair(2, 'x'), ""); | |||
static_assert(make_pair(1, 'x') < make_pair(2, 'a'), ""); | |||
static_assert(less_equal(make_pair(1, 'x'), make_pair(1, 'x')), ""); | |||
static_assert(less_equal(make_pair(1, 'x'), make_pair(1, 'y')), ""); | |||
static_assert(less_equal(make_pair(1, 'x'), make_pair(2, 'x')), ""); | |||
static_assert(less_equal(make_pair(1, 'x'), make_pair(2, 'a')), ""); | |||
static_assert(make_pair(1, 'x') <= make_pair(1, 'x'), ""); | |||
static_assert(make_pair(1, 'x') <= make_pair(1, 'y'), ""); | |||
static_assert(make_pair(1, 'x') <= make_pair(2, 'x'), ""); | |||
static_assert(make_pair(1, 'x') <= make_pair(2, 'a'), ""); | |||
static_assert(greater(make_pair(1, 'y'), make_pair(1, 'x')), ""); | |||
static_assert(greater(make_pair(2, 'x'), make_pair(1, 'x')), ""); | |||
static_assert(greater(make_pair(2, 'a'), make_pair(1, 'x')), ""); | |||
static_assert(make_pair(1, 'y') > make_pair(1, 'x'), ""); | |||
static_assert(make_pair(2, 'x') > make_pair(1, 'x'), ""); | |||
static_assert(make_pair(2, 'a') > make_pair(1, 'x'), ""); | |||
static_assert(greater_equal(make_pair(1, 'x'), make_pair(1, 'x')), ""); | |||
static_assert(greater_equal(make_pair(1, 'y'), make_pair(1, 'x')), ""); | |||
static_assert(greater_equal(make_pair(2, 'x'), make_pair(1, 'x')), ""); | |||
static_assert(greater_equal(make_pair(2, 'a'), make_pair(1, 'x')), ""); | |||
static_assert(make_pair(1, 'x') >= make_pair(1, 'x'), ""); | |||
static_assert(make_pair(1, 'y') >= make_pair(1, 'x'), ""); | |||
static_assert(make_pair(2, 'x') >= make_pair(1, 'x'), ""); | |||
static_assert(make_pair(2, 'a') >= make_pair(1, 'x'), ""); | |||
} |
@@ -1,8 +0,0 @@ | |||
#include <cpputils/mp/intern/comparable_equal.h> | |||
using namespace ::utl::mp::intern; | |||
namespace test_mp_intern_comparable_equal | |||
{ | |||
static_assert(comparable_equal<bool, bool>::value, ""); | |||
} |
@@ -1,9 +0,0 @@ | |||
#include <gtest/gtest.h> | |||
#include <cpputils/mp/intern/ebo.h> | |||
using namespace ::utl::mp::intern; | |||
struct Key { }; | |||
using ebo_type = ebo<Key, int>; | |||
constexpr ebo_type myEbo(7); | |||
static_assert(myEbo.get() == 7, "ebo.get"); |
@@ -1,10 +0,0 @@ | |||
#include <cpputils/mp/intern/has_value.h> | |||
using namespace ::utl::mp; | |||
using namespace ::utl::mp::intern; | |||
namespace test_mp_intern_has_value | |||
{ | |||
static_assert( has_value<c_true_t>::value, ""); | |||
static_assert(!has_value<bool>::value, ""); | |||
} |
@@ -1,14 +0,0 @@ | |||
#include <cpputils/mp/misc/default.h> | |||
namespace test_mp_util_default | |||
{ | |||
struct is_default_true : public ::utl::mp::__impl::default_ { }; | |||
struct is_default_false { }; | |||
} | |||
using namespace ::utl::mp; | |||
using namespace ::test_mp_util_default; | |||
static_assert( is_default<is_default_true>::value, ""); | |||
static_assert(!is_default<is_default_false>::value, ""); | |||
static_assert(!is_default<bool>::value, ""); |
@@ -1,18 +0,0 @@ | |||
#include <cstdint> | |||
#include <cpputils/mp/core/const.h> | |||
#include <cpputils/mp/misc/is_a.h> | |||
namespace test_mp_util_is_a | |||
{ | |||
struct tagged_int { using tag = int; }; | |||
struct tagged_float { using tag = float; }; | |||
struct tagged_not { }; | |||
} | |||
using namespace ::utl::mp; | |||
using namespace ::test_mp_util_is_a; | |||
static_assert( is_a<int, tagged_int>, "is_a"); | |||
static_assert(!is_a<int, tagged_float>, "is_a"); | |||
static_assert( is_a<tag_integral_constant<int>>(integral_constant<int, 1> { }), "is_a"); | |||
static_assert(!is_a<tag_integral_constant<int>>(integral_constant<uint8_t, 1> { }), "is_a"); |
@@ -1,9 +0,0 @@ | |||
#include <gtest/gtest.h> | |||
#include <cpputils/mp/misc/make.h> | |||
using namespace ::utl::mp; | |||
TEST(mp_util_test, make) | |||
{ | |||
EXPECT_EQ(std::string("fuu"), make<std::string>("fuu")); | |||
} |
@@ -1,27 +0,0 @@ | |||
#include <cpputils/mp/misc/tag_of.h> | |||
namespace test_mp_util_tag_of | |||
{ | |||
struct tagged_int { using tag = int; }; | |||
struct tagged_float { using tag = float; }; | |||
struct tagged_not { }; | |||
} | |||
using namespace ::utl::mp; | |||
using namespace ::test_mp_util_tag_of; | |||
using tagged_0_expected = int; | |||
using tagged_0_actual = tag_of<tagged_int>; | |||
static_assert(is_same<tagged_0_expected, tagged_0_actual>::value, ""); | |||
using tagged_1_expected = float; | |||
using tagged_1_actual = tag_of<tagged_float>; | |||
static_assert(is_same<tagged_1_expected, tagged_1_actual>::value, ""); | |||
using not_tagged_expected = tagged_not; | |||
using not_tagged_actual = tag_of<tagged_not>; | |||
static_assert(is_same<not_tagged_expected, not_tagged_actual>::value, ""); | |||
using bool_expected = bool; | |||
using bool_actual = tag_of<bool>; | |||
static_assert(is_same<bool_expected, bool_actual>::value, ""); |
@@ -1,39 +0,0 @@ | |||
#include <gtest/gtest.h> | |||
#include <cpputils/mp/misc/to.h> | |||
using namespace ::utl::mp; | |||
static_assert(is_convertible<int32_t, int8_t>::value, "is_convertible"); | |||
static_assert(is_convertible<uint32_t, int8_t>::value, "is_convertible"); | |||
static_assert(!is_convertible<std::string, int8_t>::value, "is_convertible"); | |||
static_assert(is_embedded<double, long double>::value, "is_embdedded"); | |||
static_assert(is_embedded<float, long double>::value, "is_embdedded"); | |||
static_assert(is_embedded<float, double >::value, "is_embdedded"); | |||
static_assert(is_embedded<signed long, signed long long>::value, "is_embedded"); | |||
static_assert(is_embedded<signed int, signed long long>::value, "is_embedded"); | |||
static_assert(is_embedded<signed short, signed long long>::value, "is_embedded"); | |||
static_assert(is_embedded<signed char, signed long long>::value, "is_embedded"); | |||
static_assert(is_embedded<signed int, signed long >::value, "is_embedded"); | |||
static_assert(is_embedded<signed short, signed long >::value, "is_embedded"); | |||
static_assert(is_embedded<signed char, signed long >::value, "is_embedded"); | |||
static_assert(is_embedded<signed short, signed int >::value, "is_embedded"); | |||
static_assert(is_embedded<signed char, signed int >::value, "is_embedded"); | |||
static_assert(is_embedded<signed char, signed short >::value, "is_embedded"); | |||
static_assert(is_embedded<unsigned long, unsigned long long>::value, "is_embedded"); | |||
static_assert(is_embedded<unsigned int, unsigned long long>::value, "is_embedded"); | |||
static_assert(is_embedded<unsigned short, unsigned long long>::value, "is_embedded"); | |||
static_assert(is_embedded<unsigned char, unsigned long long>::value, "is_embedded"); | |||
static_assert(is_embedded<unsigned int, unsigned long >::value, "is_embedded"); | |||
static_assert(is_embedded<unsigned short, unsigned long >::value, "is_embedded"); | |||
static_assert(is_embedded<unsigned char, unsigned long >::value, "is_embedded"); | |||
static_assert(is_embedded<unsigned short, unsigned int >::value, "is_embedded"); | |||
static_assert(is_embedded<unsigned char, unsigned int >::value, "is_embedded"); | |||
static_assert(is_embedded<unsigned char, unsigned short >::value, "is_embedded"); | |||
TEST(test_mp_util_to, make) | |||
{ | |||
EXPECT_EQ(to<int>(static_cast<uint8_t>(8)), 8); | |||
} |
@@ -1,9 +0,0 @@ | |||
#include <cpputils/mp/operations/compare/equal.h> | |||
using namespace ::utl::mp; | |||
namespace test_mp_operations_compare_equal | |||
{ | |||
static_assert(equal(1, 1), ""); | |||
static_assert(!equal(1, 2), ""); | |||
} |
@@ -1,9 +0,0 @@ | |||
#include <cpputils/mp/operations/compare/less.h> | |||
using namespace ::utl::mp; | |||
namespace test_mp_operations_compare_equal | |||
{ | |||
static_assert(less(1, 2), ""); | |||
static_assert(!less(2, 1), ""); | |||
} |
@@ -1,9 +0,0 @@ | |||
#include <cpputils/mp/operations/logical/and.h> | |||
using namespace ::utl::mp; | |||
namespace test_mp_operations_logical_and | |||
{ | |||
static_assert( and_(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), ""); | |||
static_assert(!and_(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), ""); | |||
} |
@@ -1,9 +0,0 @@ | |||
#include <cpputils/mp/operations/logical/or.h> | |||
using namespace ::utl::mp; | |||
namespace test_mp_operations_logical_or | |||
{ | |||
static_assert(!or_(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), ""); | |||
static_assert( or_(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), ""); | |||
} |
@@ -1,9 +0,0 @@ | |||
#include <cpputils/mp/operations/value.h> | |||
using namespace ::utl::mp; | |||
namespace test_mp_operations_value | |||
{ | |||
constexpr integral_constant<int, 6> my_const{ }; | |||
static_assert(value(my_const) == 6, ""); | |||
} |