diff --git a/CMakeLists.txt b/CMakeLists.txt index 5135bdf..8ea009b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,24 +37,22 @@ callable_traits_append_flag(callable_traits_HAS_QUNUSED_ARGUMENTS -Qunu callable_traits_append_flag(callable_traits_HAS_WNO_UNUSED_LOCAL_TYPEDEFS -Wno-unused-local-typedefs) callable_traits_append_flag(callable_traits_HAS_WWRITE_STRINGS -Wwrite-strings) -if(${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC") +if(MSVC AND NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") #disable warning about symbol truncation. Doesn't matter, affected types are not linked callable_traits_append_flag(callable_traits_HAS_WD4503 -wd4503) callable_traits_append_flag(callable_traits_HAS_W3 -W3) else() - - #if not using clang-cl - if(NOT MSVC) - callable_traits_append_flag(callable_traits_HAS_FTEMPLATE_BACKTRACE_LIMIT -ftemplate-backtrace-limit=0) - callable_traits_append_flag(callable_traits_HAS_PEDANTIC -pedantic) - callable_traits_append_flag(callable_traits_HAS_STDCXX1Y -std=c++1y) - endif() - callable_traits_append_flag(callable_traits_HAS_W -W) callable_traits_append_flag(callable_traits_HAS_WALL -Wall) callable_traits_append_flag(callable_traits_HAS_WEXTRA -Wextra) endif() +if(NOT MSVC) + callable_traits_append_flag(callable_traits_HAS_FTEMPLATE_BACKTRACE_LIMIT -ftemplate-backtrace-limit=0) + callable_traits_append_flag(callable_traits_HAS_PEDANTIC -pedantic) + callable_traits_append_flag(callable_traits_HAS_STDCXX1Y -std=c++1y) +endif() + #find_package(Boost) #if (Boost_FOUND) # include_directories(${Boost_INCLUDE_DIRS}) diff --git a/example/bind_1.cpp b/example/bind_1.cpp index 78a08a5..1e012db 100644 --- a/example/bind_1.cpp +++ b/example/bind_1.cpp @@ -23,6 +23,8 @@ because ScaryMonster is the narrowest of all _1 parameters. */ #include #include #include +#include +#include struct Vampire {}; struct Robot {}; diff --git a/example/bind_2.cpp b/example/bind_2.cpp index 93628ff..635d110 100644 --- a/example/bind_2.cpp +++ b/example/bind_2.cpp @@ -18,6 +18,8 @@ int main(){ return 0; }; #include #include #include +#include +#include struct Vampire {}; struct Robot {}; diff --git a/include/callable_traits/config.hpp b/include/callable_traits/config.hpp index 17f1f0c..8b2b9c5 100644 --- a/include/callable_traits/config.hpp +++ b/include/callable_traits/config.hpp @@ -10,22 +10,41 @@ Distributed under the Boost Software License, Version 1.0. #ifndef CALLABLE_TRAITS_CONFIG_HPP #define CALLABLE_TRAITS_CONFIG_HPP +#define CALLABLE_TRAITS_IX_SEQ(...) ::std::index_sequence< __VA_ARGS__ > +#define CALLABLE_TRAITS_MAKE_IX_SEQ(...) ::std::make_index_sequence< __VA_ARGS__ > +#define CALLABLE_TRAITS_DISJUNCTION(...) ::std::disjunction< __VA_ARGS__ > +#define CALLABLE_TRAITS_CONJUNCTION(...) ::std::conjunction< __VA_ARGS__ > + +#ifndef __cpp_lib_logical_traits +#include +#include +#endif //__cpp_lib_logical_traits + +#ifndef __cpp_lib_integer_sequence +#include +#endif // __cpp_lib_integer_sequence + #define CALLABLE_TRAITS_EMPTY_ #define CALLABLE_TRAITS_EMPTY CALLABLE_TRAITS_EMPTY_ - #define CALLABLE_TRAITS_DEFAULT_VARARGS_CC + + #ifdef _MSC_VER - #ifndef __clang__ +#ifndef __clang__ - #undef CALLABLE_TRAITS_DEFAULT_VARARGS_CC - #define CALLABLE_TRAITS_DEFAULT_VARARGS_CC __cdecl - #define CALLABLE_TRAITS_PMF_VARGARGS_CDECL_DEFAULT - #define CALLABLE_TRAITS_CONSTEXPR_CHECKS_DISABLED - #define CALLABLE_TRAITS_MSVC +#undef CALLABLE_TRAITS_DEFAULT_VARARGS_CC +#define CALLABLE_TRAITS_DEFAULT_VARARGS_CC __cdecl +#define CALLABLE_TRAITS_PMF_VARGARGS_CDECL_DEFAULT +#define CALLABLE_TRAITS_CONSTEXPR_CHECKS_DISABLED +#define CALLABLE_TRAITS_MSVC - #endif //ifndef __clang__ +#if _MSC_FULL_VER == 190023918 +#include +#endif //#if _MSC_FULL_VER == 190023918 + +#endif //ifndef __clang__ #endif //_MSC_VER diff --git a/include/callable_traits/detail/arity.hpp b/include/callable_traits/detail/arity.hpp index 2f95d3e..9122574 100644 --- a/include/callable_traits/detail/arity.hpp +++ b/include/callable_traits/detail/arity.hpp @@ -13,6 +13,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include +#include #include #include @@ -27,7 +28,7 @@ namespace callable_traits { }; template - struct max_args> { + struct max_args { static constexpr bool value = true; static constexpr int arg_count = is_invokable &>::value ? 1 : ( @@ -36,12 +37,12 @@ namespace callable_traits { }; template - struct max_args> { + struct max_args { - using result_type = disjunction< + using result_type = CALLABLE_TRAITS_DISJUNCTION( is_invokable&...>, - max_args > - >; + max_args + ); static constexpr bool value = result_type::value; static constexpr int arg_count = result_type::arg_count; @@ -59,18 +60,18 @@ namespace callable_traits { }; template - struct min_args> { + struct min_args { using next = typename std::conditional< sizeof...(I)+1 <= Max, - std::make_index_sequence, + CALLABLE_TRAITS_MAKE_IX_SEQ(sizeof...(I)+1), sentinel >::type; - using result_type = disjunction< + using result_type = CALLABLE_TRAITS_DISJUNCTION( is_invokable&...>, min_args - >; + ); static constexpr bool value = result_type::value; static constexpr int arg_count = result_type::arg_count; @@ -79,10 +80,10 @@ namespace callable_traits { template struct min_args { - using result_type = disjunction< + using result_type = CALLABLE_TRAITS_DISJUNCTION( is_invokable, - min_args> - >; + min_args + ); static constexpr int arg_count = result_type::arg_count; static constexpr bool value = result_type::value; @@ -123,7 +124,7 @@ namespace callable_traits { >::value; static constexpr int tentative_max_arity = max_args< - T, std::make_index_sequence + T, CALLABLE_TRAITS_MAKE_IX_SEQ(SearchLimit) >::arg_count; static constexpr int value = diff --git a/include/callable_traits/detail/can_invoke_constexpr_impl.hpp b/include/callable_traits/detail/can_invoke_constexpr_impl.hpp index e2ef5ca..cf60130 100644 --- a/include/callable_traits/detail/can_invoke_constexpr_impl.hpp +++ b/include/callable_traits/detail/can_invoke_constexpr_impl.hpp @@ -80,9 +80,9 @@ namespace callable_traits { }; template - using are_all_constexpr_constructible = conjunction< + using are_all_constexpr_constructible = CALLABLE_TRAITS_CONJUNCTION( is_constexpr_constructible... - >; + ); template>::value, int>::type = 0> diff --git a/include/callable_traits/detail/is_constexpr_impl.hpp b/include/callable_traits/detail/is_constexpr_impl.hpp index 898b653..cb503e7 100644 --- a/include/callable_traits/detail/is_constexpr_impl.hpp +++ b/include/callable_traits/detail/is_constexpr_impl.hpp @@ -41,7 +41,7 @@ namespace callable_traits { }; template - struct is_constexpr_t> { + struct is_constexpr_t { // An arbitrary expression as the left-hand argument to a non-overloaded // comma operator expression that is passed as a template value argument @@ -75,7 +75,7 @@ namespace callable_traits { }; template - struct is_constexpr_t, std::index_sequence> { + struct is_constexpr_t, CALLABLE_TRAITS_IX_SEQ(I...)> { // When `Pmf` is `int(foo::*)() const &&`, invoke_type is `foo const &&` using invoke_type = typename pmf::invoke_type; @@ -93,7 +93,7 @@ namespace callable_traits { // Since constexpr data members must be static, you cannot create PMDs to them template - struct is_constexpr_t, std::index_sequence> { + struct is_constexpr_t, CALLABLE_TRAITS_IX_SEQ(I...)> { auto operator()(...) const -> substitution_failure; }; @@ -108,7 +108,7 @@ namespace callable_traits { is_constexpr_impl(T&& t, std::true_type){ using traits = traits; using min_args = min_arity_t; - using seq = std::make_index_sequence; + using seq = CALLABLE_TRAITS_MAKE_IX_SEQ(min_args::value < 0 ? 0 : min_args::value); using test = is_constexpr_t; using result = decltype(test{}(::std::forward(t))); using failure = substitution_failure; diff --git a/include/callable_traits/detail/placeholder.hpp b/include/callable_traits/detail/placeholder.hpp index 5a32fb8..cad6b95 100644 --- a/include/callable_traits/detail/placeholder.hpp +++ b/include/callable_traits/detail/placeholder.hpp @@ -52,7 +52,7 @@ namespace callable_traits { template struct argument_routing {}; template - struct argument_routing, Tuple> { + struct argument_routing { using type = std::tuple< ph_route< @@ -102,7 +102,7 @@ namespace callable_traits { using routed_placeholders = typename placeholder_routes_detail< typename argument_routing< Expression, - std::make_index_sequence, + CALLABLE_TRAITS_MAKE_IX_SEQ(sizeof...(Args)), std::tuple >::type >::type; diff --git a/include/callable_traits/detail/polyfills/conjunction.hpp b/include/callable_traits/detail/polyfills/conjunction.hpp new file mode 100644 index 0000000..9b6b9b5 --- /dev/null +++ b/include/callable_traits/detail/polyfills/conjunction.hpp @@ -0,0 +1,41 @@ +/*! +Copyright Barrett Adair 2015 + +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +*/ + +#ifndef CALLABLE_TRAITS_DETAIL_POLYFILLS_CONJUNCTION_HPP +#define CALLABLE_TRAITS_DETAIL_POLYFILLS_CONJUNCTION_HPP + +#undef CALLABLE_TRAITS_CONJUNCTION +#define CALLABLE_TRAITS_CONJUNCTION(...) \ +::callable_traits::detail::polyfills::conjunction<__VA_ARGS__> + +#include + +namespace callable_traits { + + namespace detail { + + namespace polyfills { + + //polyfill for C++17 std::conjunction + template + struct conjunction + : std::true_type {}; + + template + struct conjunction + : T {}; + + template + struct conjunction + : std::conditional>::type {}; + + } + } +} + +#endif diff --git a/include/callable_traits/detail/polyfills/disjunction.hpp b/include/callable_traits/detail/polyfills/disjunction.hpp new file mode 100644 index 0000000..160bd07 --- /dev/null +++ b/include/callable_traits/detail/polyfills/disjunction.hpp @@ -0,0 +1,41 @@ +/*! +Copyright Barrett Adair 2015 + +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +*/ + +#ifndef CALLABLE_TRAITS_DETAIL_POLYFILLS_DISJUNCTION_HPP +#define CALLABLE_TRAITS_DETAIL_POLYFILLS_DISJUNCTION_HPP + +#undef CALLABLE_TRAITS_DISJUNCTION +#define CALLABLE_TRAITS_DISJUNCTION(...) \ +::callable_traits::detail::polyfills::disjunction<__VA_ARGS__> + +#include + +namespace callable_traits { + + namespace detail { + + namespace polyfills { + + //polyfill for C++17 std::disjunction + template + struct disjunction + : std::false_type {}; + + template + struct disjunction + : T {}; + + template + struct disjunction + : std::conditional>::type {}; + + } + } +} + +#endif diff --git a/include/callable_traits/detail/polyfills/make_index_sequence.hpp b/include/callable_traits/detail/polyfills/make_index_sequence.hpp new file mode 100644 index 0000000..089d40f --- /dev/null +++ b/include/callable_traits/detail/polyfills/make_index_sequence.hpp @@ -0,0 +1,61 @@ +/*! +Copyright Barrett Adair 2016 + +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) +*/ + +#ifndef CALLABLE_TRAITS_DETAIL_POLYFILLS_MAKE_INDEX_SEQUENCE_HPP +#define CALLABLE_TRAITS_DETAIL_POLYFILLS_MAKE_INDEX_SEQUENCE_HPP + +#undef CALLABLE_TRAITS_IX_SEQ +#define CALLABLE_TRAITS_IX_SEQ(...) ::callable_traits::detail::polyfills::index_sequence<__VA_ARGS__> + +#undef CALLABLE_TRAITS_MAKE_IX_SEQ +#define CALLABLE_TRAITS_MAKE_IX_SEQ(...) ::callable_traits::detail::polyfills::make_index_sequence<__VA_ARGS__> + +// http://stackoverflow.com/questions/17424477/implementation-c14-make-integer-sequence + +namespace callable_traits { + + namespace detail { + + namespace polyfills { + + template + struct index_sequence { + using type = index_sequence; + }; + + template + struct concat; + + template + struct concat, index_sequence> + : index_sequence {}; + + template + struct make_index_sequence_t; + + template + struct make_index_sequence_t + : concat< + typename make_index_sequence_t::type, + typename make_index_sequence_t::type >::type {}; + + template<> + struct make_index_sequence_t<0> + : index_sequence<> {}; + + template<> + struct make_index_sequence_t<1> + : index_sequence<0> {}; + + template + using make_index_sequence = + typename make_index_sequence_t::type; + } + } +} + +#endif diff --git a/include/callable_traits/detail/test_invoke.hpp b/include/callable_traits/detail/test_invoke.hpp index 2e4a305..92c2aa1 100644 --- a/include/callable_traits/detail/test_invoke.hpp +++ b/include/callable_traits/detail/test_invoke.hpp @@ -10,6 +10,8 @@ Distributed under the Boost Software License, Version 1.0. #ifndef CALLABLE_TRAITS_DETAIL_TEST_INVOKE_HPP #define CALLABLE_TRAITS_DETAIL_TEST_INVOKE_HPP +#include +#include #include #include #include diff --git a/include/callable_traits/detail/traits.hpp b/include/callable_traits/detail/traits.hpp index c5e4a47..da22596 100644 --- a/include/callable_traits/detail/traits.hpp +++ b/include/callable_traits/detail/traits.hpp @@ -31,14 +31,14 @@ namespace callable_traits { >::type; template> - using traits = typename disjunction< + using traits = typename CALLABLE_TRAITS_DISJUNCTION( bind_expression_traits, function_object, function>, pmf, pmd>, function_object - >::traits; + )::traits; } } diff --git a/include/callable_traits/detail/tuple_group_by.hpp b/include/callable_traits/detail/tuple_group_by.hpp index aae0500..db8f117 100644 --- a/include/callable_traits/detail/tuple_group_by.hpp +++ b/include/callable_traits/detail/tuple_group_by.hpp @@ -84,7 +84,7 @@ namespace callable_traits { struct group_by_impl; template class Pred, std::size_t... I> - struct group_by_impl> { + struct group_by_impl { using type = std::tuple< typename group_by_filter< @@ -110,7 +110,7 @@ namespace callable_traits { tuple_sort, group_by_values, Pred, - std::make_index_sequence::value> + CALLABLE_TRAITS_MAKE_IX_SEQ(std::tuple_size::value) >::type; }; diff --git a/include/callable_traits/detail/tuple_sort.hpp b/include/callable_traits/detail/tuple_sort.hpp index 9034be5..ed2a058 100644 --- a/include/callable_traits/detail/tuple_sort.hpp +++ b/include/callable_traits/detail/tuple_sort.hpp @@ -11,7 +11,7 @@ Distributed under the Boost Software License, Version 1.0. #define CALLABLE_TRAITS_DETAIL_TUPLE_SORT_HPP - +#include #include #include @@ -20,7 +20,7 @@ namespace callable_traits { namespace detail { - using empty_seq = std::index_sequence<>; + using empty_seq = CALLABLE_TRAITS_IX_SEQ(CALLABLE_TRAITS_EMPTY); template @@ -30,11 +30,11 @@ namespace callable_traits { // recursively. template - struct insert, + struct insert { using type = typename insert< Pred, Insert, Pred::template apply::value, - std::index_sequence, + CALLABLE_TRAITS_IX_SEQ(Left..., Right1), Right2, Right... >::type; }; @@ -42,14 +42,14 @@ namespace callable_traits { // We did not find the insertion point, but there is only one element // left. We insert at the end of the list, and we're done. template - struct insert, Last> { - using type = std::index_sequence; + struct insert { + using type = CALLABLE_TRAITS_IX_SEQ(Left..., Last, Insert); }; // We found the insertion point, we're done. template - struct insert, Right...> { - using type = std::index_sequence; + struct insert { + using type = CALLABLE_TRAITS_IX_SEQ(Left..., Insert, Right...); }; template @@ -57,7 +57,7 @@ namespace callable_traits { template - struct insertion_sort, T, Ts...> { + struct insertion_sort { static constexpr bool pred_result = Pred::template apply::value; using insert_result = typename insert< Pred, T, pred_result, empty_seq, Result1, Results... @@ -68,7 +68,7 @@ namespace callable_traits { template struct insertion_sort { using type = typename insertion_sort< - Pred, std::index_sequence, Ts... + Pred, CALLABLE_TRAITS_IX_SEQ(T), Ts... >::type; }; @@ -81,19 +81,19 @@ namespace callable_traits { struct sort_indices; template - struct sort_indices> { + struct sort_indices { using type = typename insertion_sort::type; }; template struct sort_impl { static constexpr std::size_t len = std::tuple_size::value; - using indices = typename sort_indices>::type; + using indices = typename sort_indices::type; using type = typename sort_impl::type; }; template - struct sort_impl> { + struct sort_impl { using type = std::tuple...>; }; diff --git a/include/callable_traits/detail/utility.hpp b/include/callable_traits/detail/utility.hpp index 938c6b0..8cba2a8 100644 --- a/include/callable_traits/detail/utility.hpp +++ b/include/callable_traits/detail/utility.hpp @@ -56,43 +56,14 @@ struct invalid_type { invalid_type() = delete; }; template using weak_at = typename util_detail::weak_at_t::type; - // a faster version of std::decay_t template using shallow_decay = typename std::remove_cv< typename std::remove_reference::type >::type; - - //polyfill for C++17 std::conjunction - template - struct conjunction - : std::true_type {}; - - template - struct conjunction - : T {}; - - template - struct conjunction - : std::conditional>::type { }; - - - //polyfill for C++17 std::disjunction - template - struct disjunction - : std::false_type {}; - - template - struct disjunction - : T {}; - - template - struct disjunction - : std::conditional>::type { }; - - //polyfill for C++17 negation + //TODO rename and move to polyfills folder template using negate = std::integral_constant; @@ -273,10 +244,10 @@ struct invalid_type { invalid_type() = delete; }; } template - using fail_if_invalid = typename disjunction< + using fail_if_invalid = typename CALLABLE_TRAITS_DISJUNCTION( util_detail::type_value::value>, FailType - >::type; + )::type; template using fallback_if_invalid = typename std::conditional< diff --git a/qtcreator/include/include.pro b/qtcreator/include/include.pro index 92cd535..05c71b6 100644 --- a/qtcreator/include/include.pro +++ b/qtcreator/include/include.pro @@ -3,3 +3,4 @@ CONFIG -= qt HEADERS += ../../include/callable_traits/*.hpp HEADERS += ../../include/callable_traits/detail/*.hpp HEADERS += ../../include/callable_traits/detail/fwd/*.hpp +HEADERS += ../../include/callable_traits/detail/polyfills/*.hpp diff --git a/qtcreator/main/main.cpp b/qtcreator/main/main.cpp index 7e15752..81636e8 100644 --- a/qtcreator/main/main.cpp +++ b/qtcreator/main/main.cpp @@ -1,19 +1,69 @@ -/*<- -Copyright Barrett Adair 2016 -Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE.md or copy at http ://boost.org/LICENSE_1_0.txt) -->*/ +/*! +Copyright (c) 2016 Barrett Adair -//[ push_args_back -#include +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) +*/ + +#include +#include + +#ifdef CALLABLE_TRAITS_MSVC +//feature is unsupported in MSVC +int main(){ return 0; }; +#else + +#ifndef CT_ASSERT +#define CT_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) +#endif //CT_ASSERT + +struct foo1 { + int operator()() const { + return 0; + } +}; + +struct foo2 { + constexpr int operator()(int) const { + return 1; + } + constexpr int operator()() const { + return 1; + } +}; + +struct foo3 { + constexpr int bar(int) const { + return 1; + } +}; + +constexpr int bar(const int&) { + return 1; +} + +using foo4 = std::integral_constant; + +using foo1_pmf = std::integral_constant; +using foo3_pmf = std::integral_constant; namespace ct = callable_traits; -int main() { +CT_ASSERT(!ct::can_invoke_constexpr(foo1{})); +CT_ASSERT(!ct::can_invoke_constexpr(foo1{}, 0)); - using f = void(int, char); - using test = ct::push_args_back; - using expect = void(int, char, long, void*); - static_assert(std::is_same::value, ""); -} -//] +CT_ASSERT( ct::can_invoke_constexpr(foo2{})); +CT_ASSERT( ct::can_invoke_constexpr(foo2{}, 0)); + +CT_ASSERT(!ct::can_invoke_constexpr(foo4{})); +CT_ASSERT( ct::can_invoke_constexpr(foo4{}, 0)); + +CT_ASSERT(!ct::can_invoke_constexpr(foo1_pmf{}, foo1{})); +CT_ASSERT(!ct::can_invoke_constexpr(foo1_pmf{}, foo1{}, 0)); + +CT_ASSERT(!ct::can_invoke_constexpr(foo3_pmf{}, foo3{})); +CT_ASSERT( ct::can_invoke_constexpr(foo3_pmf{}, foo3{}, 0)); + +int main() {} + +#endif diff --git a/test/bind_1.cpp b/test/bind_1.cpp index f4f6fcc..145938b 100644 --- a/test/bind_1.cpp +++ b/test/bind_1.cpp @@ -70,7 +70,7 @@ auto ordered_letters(A a, B b, C c, D d, E e, F f, G g) { template constexpr decltype(auto) -apply_helper(F&& f, Tuple&& t, std::index_sequence) { +apply_helper(F&& f, Tuple&& t, CALLABLE_TRAITS_IX_SEQ(I...)) { return std::forward(f)(std::get(std::forward(t))...); } @@ -80,9 +80,9 @@ apply(F&& f, Tuple&& t) { return apply_helper( std::forward(f), std::forward(t), - std::make_index_sequence< - std::tuple_size>::value - >{} + CALLABLE_TRAITS_MAKE_IX_SEQ( + std::tuple_size>::value + ){} ); } diff --git a/test/bind_2.cpp b/test/bind_2.cpp index 8d59f9c..35be10f 100644 --- a/test/bind_2.cpp +++ b/test/bind_2.cpp @@ -72,7 +72,7 @@ auto BEEF_returns_B(B, E, E, F) { template constexpr decltype(auto) -apply_helper(F&& f, Tuple&& t, std::index_sequence) { +apply_helper(F&& f, Tuple&& t, CALLABLE_TRAITS_IX_SEQ(I...)) { return std::forward(f)(std::get(std::forward(t))...); } @@ -83,9 +83,9 @@ apply(F&& f, Tuple&& t) { return apply_helper( std::forward(f), std::forward(t), - std::make_index_sequence< - std::tuple_size::type>::value - >{} + CALLABLE_TRAITS_MAKE_IX_SEQ( + std::tuple_size>::value + ){} ); } diff --git a/test/detail/flatten_bind_expressions.cpp b/test/detail/flatten_bind_expressions.cpp index cdd05a5..7249521 100644 --- a/test/detail/flatten_bind_expressions.cpp +++ b/test/detail/flatten_bind_expressions.cpp @@ -15,6 +15,11 @@ Distributed under the Boost Software License, Version 1.0. #include #include +#ifdef CALLABLE_TRAITS_MSVC +//feature is unsupported in MSVC +int main(){ return 0; }; +#else + #ifndef CT_ASSERT #define CT_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) #endif //CT_ASSERT @@ -71,3 +76,5 @@ int main() { return 0; } + +#endif