-
Notifications
You must be signed in to change notification settings - Fork 141
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixing decltype problems on Visual 2013
- Loading branch information
1 parent
f94eb54
commit 0871200
Showing
2 changed files
with
147 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -65,31 +65,60 @@ struct is_forward_iterable<std::list<T> > : public mpl::true_ {}; | |
|
||
namespace ut_detail { | ||
|
||
template<typename T> | ||
struct is_present : public mpl::true_ {}; | ||
|
||
struct is_forward_iterable_impl { | ||
template<typename T> | ||
static typename std::enable_if< | ||
is_present<typename T::const_iterator>::value && | ||
is_present<typename T::value_type>::value && | ||
is_present<decltype(boost::declval<T>().size())>::value && | ||
is_present<decltype(boost::declval<T>().begin())>::value && | ||
!is_same<typename remove_cv<typename T::value_type>::type,char>::value && | ||
!is_same<typename remove_cv<typename T::value_type>::type,wchar_t>::value | ||
, mpl::true_>::type | ||
test(int); | ||
|
||
template<typename> | ||
static std::false_type test(...); | ||
}; | ||
|
||
template<typename T> | ||
struct is_present : public mpl::true_ {}; | ||
|
||
|
||
// some compiler do not implement properly decltype non expression involving members (eg. VS2013) | ||
// a workaround is to use -> decltype syntax. | ||
template <class T> | ||
struct has_member_size { | ||
private: | ||
struct nil_t; | ||
template<typename T> static auto test(T*) -> decltype( boost::declval<T>().size() ); | ||
template<typename> static nil_t test(...); | ||
|
||
public: | ||
static bool const value = !std::is_same< decltype(test<T>(nullptr)), nil_t>::value; | ||
}; | ||
|
||
template <class T> | ||
struct has_member_begin { | ||
private: | ||
struct nil_t; | ||
template<typename T> static auto test(T*) -> decltype( boost::declval<T>().begin() ); | ||
template<typename> static nil_t test(...); | ||
public: | ||
static bool const value = !std::is_same< decltype(test<T>(nullptr)), nil_t>::value; | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
raffienficiaud
Author
Member
|
||
}; | ||
|
||
|
||
template <class T, class enabled = void> | ||
struct is_forward_iterable_impl : std::false_type | ||
{}; | ||
|
||
template <class T> | ||
struct is_forward_iterable_impl< | ||
T, | ||
typename std::enable_if< | ||
is_present<typename T::const_iterator>::value && | ||
is_present<typename T::value_type>::value && | ||
has_member_size<T>::value && | ||
has_member_begin<T>::value && | ||
!is_same<typename remove_cv<typename T::value_type>::type,char>::value && | ||
!is_same<typename remove_cv<typename T::value_type>::type,wchar_t>::value | ||
>::type | ||
> : std::true_type | ||
{}; | ||
|
||
|
||
} // namespace ut_detail | ||
|
||
template<typename T> | ||
struct is_forward_iterable { | ||
typedef decltype(ut_detail::is_forward_iterable_impl::test<typename std::remove_reference<T>::type>(0)) type; | ||
enum { value = type::value }; | ||
struct is_forward_iterable { | ||
typedef mpl::bool_<ut_detail::is_forward_iterable_impl<T>::value> type; | ||
enum { value = ut_detail::is_forward_iterable_impl<T>::value }; | ||
}; | ||
|
||
#endif | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The use of nullptr breaks the tests on older compilers (e.g. GCC <4.6). The above code should probably be used only if none of the macros below was defined.