move to C++17

This commit is contained in:
2019-05-13 01:06:33 +07:00
parent 2d57364cc5
commit bf05aa54ca
4 changed files with 19 additions and 268 deletions

View File

@@ -1,7 +1,6 @@
version: "{build}"
shallow_clone: true
image:
- Visual Studio 2015
- Visual Studio 2017
- Visual Studio 2019 Preview
platform:

View File

@@ -1,4 +1,4 @@
# 3.8 version is required for `cxx_std_14`
# 3.8 version is required for `cxx_std_17`
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
if(NOT DEFINED PROJECT_NAME)
@@ -9,7 +9,7 @@ project(kari.hpp)
add_library(${PROJECT_NAME} INTERFACE)
target_include_directories(${PROJECT_NAME} INTERFACE headers)
target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_14)
target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_17)
if(BUILD_AS_STANDALONE)
option(BUILD_WITH_UNTESTS "Build with unit tests" ON)

View File

@@ -1,6 +1,6 @@
# kari.hpp [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Experimental%20library%20for%20currying%20in%20C%2B%2B14&url=https://github.com/BlackMATov/kari.hpp&via=BMEngine&hashtags=cpp,currying,cpp14,cpp17,functionalprogramming)
# kari.hpp [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Experimental%20library%20for%20currying%20in%20C%2B%2B17&url=https://github.com/BlackMATov/kari.hpp&via=BMEngine&hashtags=cpp,currying,cpp14,cpp17,functionalprogramming)
> Experimental library for currying in C++14
> Experimental library for currying in C++17
[![travis][badge.travis]][travis]
[![appveyor][badge.appveyor]][appveyor]
@@ -12,14 +12,14 @@
[badge.travis]: https://img.shields.io/travis/BlackMATov/kari.hpp/master.svg?logo=travis
[badge.appveyor]: https://img.shields.io/appveyor/ci/BlackMATov/kari-hpp/master.svg?logo=appveyor
[badge.codecov]: https://img.shields.io/codecov/c/github/BlackMATov/kari.hpp/master.svg?logo=codecov
[badge.language]: https://img.shields.io/badge/language-C%2B%2B14-red.svg
[badge.language]: https://img.shields.io/badge/language-C%2B%2B17-yellow.svg
[badge.license]: https://img.shields.io/badge/license-MIT-blue.svg
[badge.paypal]: https://img.shields.io/badge/donate-PayPal-orange.svg?logo=paypal&colorA=00457C
[travis]: https://travis-ci.org/BlackMATov/kari.hpp
[appveyor]: https://ci.appveyor.com/project/BlackMATov/kari-hpp
[codecov]: https://codecov.io/gh/BlackMATov/kari.hpp
[language]: https://en.wikipedia.org/wiki/C%2B%2B14
[language]: https://en.wikipedia.org/wiki/C%2B%2B17
[license]: https://github.com/BlackMATov/kari.hpp/blob/master/LICENSE.md
[paypal]: https://www.paypal.me/matov
@@ -131,7 +131,7 @@ namespace kari {
struct is_curried;
template < typename F >
constexpr bool is_curried_v = is_curried<F>::value;
inline constexpr bool is_curried_v = is_curried<F>::value;
template < std::size_t N, typename F, typename... Args >
struct curry_t {

View File

@@ -12,254 +12,6 @@
#include <functional>
#include <type_traits>
// -----------------------------------------------------------------------------
//
// https://github.com/BlackMATov/invoke.hpp
//
// -----------------------------------------------------------------------------
#define INVOKE_HPP_NOEXCEPT_RETURN(...) \
noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; }
#define INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(...) \
noexcept(noexcept(__VA_ARGS__)) -> decltype (__VA_ARGS__) { return __VA_ARGS__; }
//
// void_t
//
namespace invoke_hpp
{
namespace impl
{
template < typename... Args >
struct make_void {
using type = void;
};
}
template < typename... Args >
using void_t = typename impl::make_void<Args...>::type;
}
//
// is_reference_wrapper
//
namespace invoke_hpp
{
namespace impl
{
template < typename T >
struct is_reference_wrapper_impl
: std::false_type {};
template < typename U >
struct is_reference_wrapper_impl<std::reference_wrapper<U>>
: std::true_type {};
}
template < typename T >
struct is_reference_wrapper
: impl::is_reference_wrapper_impl<std::remove_cv_t<T>> {};
}
//
// invoke
//
namespace invoke_hpp
{
namespace impl
{
//
// invoke_member_object_impl
//
template
<
typename Base, typename F, typename Derived,
typename std::enable_if_t<std::is_base_of<Base, std::decay_t<Derived>>::value, int> = 0
>
constexpr auto invoke_member_object_impl(F Base::* f, Derived&& ref)
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
std::forward<Derived>(ref).*f)
template
<
typename Base, typename F, typename RefWrap,
typename std::enable_if_t<is_reference_wrapper<std::decay_t<RefWrap>>::value, int> = 0
>
constexpr auto invoke_member_object_impl(F Base::* f, RefWrap&& ref)
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
ref.get().*f)
template
<
typename Base, typename F, typename Pointer,
typename std::enable_if_t<
!std::is_base_of<Base, std::decay_t<Pointer>>::value &&
!is_reference_wrapper<std::decay_t<Pointer>>::value
, int> = 0
>
constexpr auto invoke_member_object_impl(F Base::* f, Pointer&& ptr)
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
(*std::forward<Pointer>(ptr)).*f)
//
// invoke_member_function_impl
//
template
<
typename Base, typename F, typename Derived, typename... Args,
typename std::enable_if_t<std::is_base_of<Base, std::decay_t<Derived>>::value, int> = 0
>
constexpr auto invoke_member_function_impl(F Base::* f, Derived&& ref, Args&&... args)
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
(std::forward<Derived>(ref).*f)(std::forward<Args>(args)...))
template
<
typename Base, typename F, typename RefWrap, typename... Args,
typename std::enable_if_t<is_reference_wrapper<std::decay_t<RefWrap>>::value, int> = 0
>
constexpr auto invoke_member_function_impl(F Base::* f, RefWrap&& ref, Args&&... args)
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
(ref.get().*f)(std::forward<Args>(args)...))
template
<
typename Base, typename F, typename Pointer, typename... Args,
typename std::enable_if_t<
!std::is_base_of<Base, std::decay_t<Pointer>>::value &&
!is_reference_wrapper<std::decay_t<Pointer>>::value
, int> = 0
>
constexpr auto invoke_member_function_impl(F Base::* f, Pointer&& ptr, Args&&... args)
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
((*std::forward<Pointer>(ptr)).*f)(std::forward<Args>(args)...))
}
template
<
typename F, typename... Args,
typename std::enable_if_t<!std::is_member_pointer<std::decay_t<F>>::value, int> = 0
>
constexpr auto invoke(F&& f, Args&&... args)
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
std::forward<F>(f)(std::forward<Args>(args)...))
template
<
typename F, typename T,
typename std::enable_if_t<std::is_member_object_pointer<std::decay_t<F>>::value, int> = 0
>
constexpr auto invoke(F&& f, T&& t)
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
impl::invoke_member_object_impl(std::forward<F>(f), std::forward<T>(t)))
template
<
typename F, typename... Args,
typename std::enable_if_t<std::is_member_function_pointer<std::decay_t<F>>::value, int> = 0
>
constexpr auto invoke(F&& f, Args&&... args)
INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN(
impl::invoke_member_function_impl(std::forward<F>(f), std::forward<Args>(args)...))
}
//
// invoke_result
//
namespace invoke_hpp
{
namespace impl
{
struct invoke_result_impl_tag {};
template < typename Void, typename F, typename... Args >
struct invoke_result_impl {};
template < typename F, typename... Args >
struct invoke_result_impl<void_t<invoke_result_impl_tag, decltype(invoke_hpp::invoke(std::declval<F>(), std::declval<Args>()...))>, F, Args...> {
using type = decltype(invoke_hpp::invoke(std::declval<F>(), std::declval<Args>()...));
};
}
template < typename F, typename... Args >
struct invoke_result
: impl::invoke_result_impl<void, F, Args...> {};
template < typename F, typename... Args >
using invoke_result_t = typename invoke_result<F, Args...>::type;
}
//
// is_invocable
//
namespace invoke_hpp
{
namespace impl
{
struct is_invocable_r_impl_tag {};
template < typename Void, typename R, typename F, typename... Args >
struct is_invocable_r_impl
: std::false_type {};
template < typename R, typename F, typename... Args >
struct is_invocable_r_impl<void_t<is_invocable_r_impl_tag, invoke_result_t<F, Args...>>, R, F, Args...>
: std::conditional_t<
std::is_void<R>::value,
std::true_type,
std::is_convertible<invoke_result_t<F, Args...>, R>> {};
}
template < typename R, typename F, typename... Args >
struct is_invocable_r
: impl::is_invocable_r_impl<void, R, F, Args...> {};
template < typename F, typename... Args >
using is_invocable = is_invocable_r<void, F, Args...>;
}
//
// apply
//
namespace invoke_hpp
{
namespace impl
{
template < typename F, typename Tuple, std::size_t... I >
constexpr decltype(auto) apply_impl(F&& f, Tuple&& args, std::index_sequence<I...>)
INVOKE_HPP_NOEXCEPT_RETURN(
invoke_hpp::invoke(
std::forward<F>(f),
std::get<I>(std::forward<Tuple>(args))...))
}
template < typename F, typename Tuple >
constexpr decltype(auto) apply(F&& f, Tuple&& args)
INVOKE_HPP_NOEXCEPT_RETURN(
impl::apply_impl(
std::forward<F>(f),
std::forward<Tuple>(args),
std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>()))
}
#undef INVOKE_HPP_NOEXCEPT_RETURN
#undef INVOKE_HPP_NOEXCEPT_DECLTYPE_RETURN
// -----------------------------------------------------------------------------
//
// https://github.com/BlackMATov/kari.hpp
//
// -----------------------------------------------------------------------------
#define KARI_HPP_NOEXCEPT_RETURN(...) \
noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; }
@@ -278,19 +30,19 @@ namespace kari
std::size_t N, typename F, typename... Args,
typename std::enable_if_t<
(N == 0) &&
invoke_hpp::is_invocable<std::decay_t<F>, Args...>::value
std::is_invocable_v<std::decay_t<F>, Args...>
, int> = 0
>
constexpr auto make_curry(F&& f, std::tuple<Args...>&& args)
KARI_HPP_NOEXCEPT_RETURN(
invoke_hpp::apply(std::forward<F>(f), std::move(args)))
std::apply(std::forward<F>(f), std::move(args)))
template
<
std::size_t N, typename F, typename... Args,
typename std::enable_if_t<
(N > 0) ||
!invoke_hpp::is_invocable<std::decay_t<F>, Args...>::value
!std::is_invocable_v<std::decay_t<F>, Args...>
, int> = 0
>
constexpr auto make_curry(F&& f, std::tuple<Args...>&& args)
@@ -408,7 +160,7 @@ namespace kari
: detail::is_curried_impl<std::remove_cv_t<F>> {};
template < typename F >
constexpr bool is_curried_v = is_curried<F>::value;
inline constexpr bool is_curried_v = is_curried<F>::value;
//
// curry
@@ -512,7 +264,7 @@ namespace kari
KARI_HPP_NOEXCEPT_DECLTYPE_RETURN(
std::forward<A>(a))
};
constexpr auto fid = curry(fid_t{});
inline constexpr auto fid = curry(fid_t{});
//
// fconst
@@ -524,7 +276,7 @@ namespace kari
KARI_HPP_NOEXCEPT_DECLTYPE_RETURN(
std::forward<A>(a))
};
constexpr auto fconst = curry(fconst_t{});
inline constexpr auto fconst = curry(fconst_t{});
//
// fflip
@@ -539,7 +291,7 @@ namespace kari
std::forward<B>(b),
std::forward<A>(a)))
};
constexpr auto fflip = curry(fflip_t{});
inline constexpr auto fflip = curry(fflip_t{});
//
// fpipe
@@ -555,7 +307,7 @@ namespace kari
std::forward<G>(g),
std::forward<A>(a))))
};
constexpr auto fpipe = curry(fpipe_t{});
inline constexpr auto fpipe = curry(fpipe_t{});
//
// fcompose
@@ -571,7 +323,7 @@ namespace kari
std::forward<F>(f),
std::forward<A>(a))))
};
constexpr auto fcompose = curry(fcompose_t{});
inline constexpr auto fcompose = curry(fcompose_t{});
//
// fpipe operators
@@ -651,7 +403,7 @@ namespace kari
namespace underscore
{
struct us_t {};
constexpr us_t _{};
inline constexpr us_t _{};
//
// is_underscore, is_underscore_v
@@ -659,10 +411,10 @@ namespace kari
template < typename T >
struct is_underscore
: std::integral_constant<bool, std::is_same<us_t, std::remove_cv_t<T>>::value> {};
: std::bool_constant<std::is_same_v<us_t, std::remove_cv_t<T>>> {};
template < typename T >
constexpr bool is_underscore_v = is_underscore<T>::value;
inline constexpr bool is_underscore_v = is_underscore<T>::value;
//
// unary operators