Skip to content

Instantly share code, notes, and snippets.

@gintenlabo
Last active December 16, 2015 04:39
Show Gist options
  • Select an option

  • Save gintenlabo/5378697 to your computer and use it in GitHub Desktop.

Select an option

Save gintenlabo/5378697 to your computer and use it in GitHub Desktop.
decay_copy は標準に必要だと思うんだ
#include <type_traits>
#include <utility>
// checking whether U{std::declval<T>()} is well-formed,
// where U is typename std::decay<T>::type
template<class T>
struct is_decay_copyable
: std::is_constructible<typename std::decay<T>::type, T>::type {};
// typename decay_if_possible<T>::type is defined as typename std::decay<T>::type,
// if and only if is_decay_copyable<T>::value is true
template<class T>
struct decay_if_possible
: std::enable_if<is_decay_copyable<T>::value, typename std::decay<T>::type> {};
// checking whether U{std::declval<T>()} is well-formed and it throws,
// where U is typename std::decay<T>::type
template<class T, class = void>
struct is_nt_decay_copyable_impl_
: std::false_type {};
template<class T>
struct is_nt_decay_copyable_impl_<T,
typename std::enable_if<is_decay_copyable<T>::value>::type
>
: std::is_nothrow_constructible<typename std::decay<T>::type, T>::type {};
template<class T>
struct is_nothrow_decay_copyable
: is_nt_decay_copyable_impl_<T>::type {};
// same as
// auto t = std::forward<T>(x); return t;
template<class T>
inline constexpr auto decay_copy(T && x)
noexcept( is_nothrow_decay_copyable<T>::value )
-> typename decay_if_possible<T>::type
{
return std::forward<T>(x);
}
// check decay-copyable
struct noncopyable {
noncopyable() = default;
noncopyable(noncopyable const&) = delete;
void operator=(noncopyable const&) = delete;
};
static_assert( !is_decay_copyable<noncopyable&&>::value, "" );
#include <memory>
static_assert( !is_decay_copyable<std::unique_ptr<int>& >::value, "" );
static_assert( is_decay_copyable<std::unique_ptr<int>&&>::value, "" );
// check return type
static_assert( std::is_same<decltype(decay_copy(0)), int>::value, "" );
static_assert( std::is_same<decltype(decay_copy("string literal")), char const*>::value, "" );
void f();
static_assert( std::is_same<decltype(decay_copy(f)), void(*)()>::value, "" );
// check noexcept
static_assert( noexcept(decay_copy(1)), "" );
static_assert( noexcept(decay_copy("string literal")), "" );
static_assert( noexcept(decay_copy(f)), "" );
#include <vector>
static_assert( noexcept(decay_copy(std::declval<std::vector<int> >())), "" );
static_assert( !noexcept(decay_copy(std::declval<std::vector<int>&>())), "" );
int main()
{
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment