1
0
forked from boostorg/move

- Reworked some traits to refactor code

- is_trivially_copy_xxxxable updated to add is_pod
- Updated is_pod adding scalar and void as some compilers' __is_pod intrinsic doesn't work with scalars
- Added test for type_traits. Only a few tested, more to come.
This commit is contained in:
Ion Gaztañaga
2015-04-26 23:29:27 +02:00
parent 32f4d91cec
commit 69598a3d3f
5 changed files with 299 additions and 41 deletions

View File

@@ -219,7 +219,10 @@
#endif
#ifdef BOOST_MOVE_IS_POD
#define BOOST_MOVE_IS_POD_IMPL(T) BOOST_MOVE_IS_POD(T)
//in some compilers the intrinsic is limited to class types so add scalar and void
#define BOOST_MOVE_IS_POD_IMPL(T) (::boost::move_detail::is_scalar<T>::value ||\
::boost::move_detail::is_void<T>::value ||\
BOOST_MOVE_IS_POD(T))
#else
#define BOOST_MOVE_IS_POD_IMPL(T) \
(::boost::move_detail::is_scalar<T>::value || ::boost::move_detail::is_void<T>::value)
@@ -702,16 +705,31 @@ template <class T>
struct is_empty
{ static const bool value = BOOST_MOVE_IS_EMPTY_IMPL(T); };
template<class T>
struct has_boost_move_no_copy_constructor_or_assign_type
{
template <class U>
static yes_type test(typename U::boost_move_no_copy_constructor_or_assign*);
template <class U>
static no_type test(...);
static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
};
//////////////////////////////////////
// is_copy_constructible
//////////////////////////////////////
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_NO_CXX11_DECLTYPE) \
&& !defined(BOOST_INTEL_CXX_VERSION) && \
!(defined(BOOST_MSVC) && _MSC_VER == 1800)
#define BOOST_MOVE_TT_CXX11_IS_COPY_CONSTRUCTIBLE
#endif
template<class T>
struct is_copy_constructible
{
typedef char yes_type;
struct no_type { char dummy[2]; };
template<class U> static typename add_reference<U>::type source();
// Intel compiler has problems with SFINAE for copy constructors and deleted functions:
//
// error: function *function_name* cannot be referenced -- it is a deleted function
@@ -719,8 +737,8 @@ struct is_copy_constructible
// ^
// MSVC 12.0 (Visual 2013) has problems when the copy constructor has been deleted. See:
// https://connect.microsoft.com/VisualStudio/feedback/details/800328/std-is-copy-constructible-is-broken
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_INTEL_CXX_VERSION) &&\
!(defined(BOOST_MSVC) && _MSC_VER == 1800)
#if defined(BOOST_MOVE_TT_CXX11_IS_COPY_CONSTRUCTIBLE)
template<class U> static typename add_reference<U>::type source();
static no_type test(...);
#ifdef BOOST_NO_CXX11_DECLTYPE
template <class U>
@@ -729,15 +747,13 @@ struct is_copy_constructible
template <class U>
static yes_type test(U&, decltype(U(source<U>()))* = 0);
#endif
static const bool value = sizeof(test(source<T>())) == sizeof(yes_type);
#else
template <class U>
static no_type test(U&, typename U::boost_move_no_copy_constructor_or_assign* = 0);
static yes_type test(...);
static const bool value = !has_boost_move_no_copy_constructor_or_assign_type<T>::value;
#endif
static const bool value = sizeof(test(source<T>())) == sizeof(yes_type);
};
//////////////////////////////////////
// is_copy_assignable
//////////////////////////////////////
@@ -768,13 +784,7 @@ struct is_copy_assignable
static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
#else
static typename add_reference<T>::type produce();
template <class T1>
static no_type test(T1&, typename T1::boost_move_no_copy_constructor_or_assign* = 0);
static yes_type test(...);
static const bool value = sizeof(test(produce())) == sizeof(yes_type);
static const bool value = !has_boost_move_no_copy_constructor_or_assign_type<T>::value;
#endif
};
@@ -800,8 +810,9 @@ struct is_trivially_copy_constructible
{
//In several compilers BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE return true even with
//deleted copy constructors so make sure the type is copy constructible.
static const bool value = ::boost::move_detail::is_copy_constructible<T>::value &&
BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T);
static const bool value = ::boost::move_detail::is_pod<T>::value ||
( ::boost::move_detail::is_copy_constructible<T>::value &&
BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) );
};
//////////////////////////////////////
@@ -819,8 +830,9 @@ struct is_trivially_copy_assignable
{
//In several compilers BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE return true even with
//deleted copy constructors so make sure the type is copy constructible.
static const bool value = ::boost::move_detail::is_copy_assignable<T>::value &&
BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T);
static const bool value = ::boost::move_detail::is_pod<T>::value ||
( ::boost::move_detail::is_copy_assignable<T>::value &&
BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T) );
};
//////////////////////////////////////

View File

@@ -107,6 +107,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "adl_move_swap", "adl_move_s
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "type_traits", "type_traits.vcproj", "{D7C28A23-8621-FE05-BF87-3C7B6176BD02}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
@@ -223,6 +227,10 @@ Global
{CD2617A8-79EB-6172-2CE4-26617AA3AC93}.Debug.Build.0 = Debug|Win32
{CD2617A8-79EB-6172-2CE4-26617AA3AC93}.Release.ActiveCfg = Release|Win32
{CD2617A8-79EB-6172-2CE4-26617AA3AC93}.Release.Build.0 = Release|Win32
{D7C28A23-8621-FE05-BF87-3C7B6176BD02}.Debug.ActiveCfg = Debug|Win32
{D7C28A23-8621-FE05-BF87-3C7B6176BD02}.Debug.Build.0 = Debug|Win32
{D7C28A23-8621-FE05-BF87-3C7B6176BD02}.Release.ActiveCfg = Release|Win32
{D7C28A23-8621-FE05-BF87-3C7B6176BD02}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionItems) = postSolution
..\..\..\..\boost\move\adl_move_swap.hpp = ..\..\..\..\boost\move\adl_move_swap.hpp

View File

@@ -0,0 +1,135 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="type_traits"
ProjectGUID="{D7C28A23-8621-FE05-BF87-3C7B6176BD02}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/type_traits"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
DisableLanguageExtensions="FALSE"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/unique_ptr_types_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/type_traits.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/type_traits"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/type_traits.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{43465AE1-5F7A-33E6-5A6C-3202CE43A275}">
<File
RelativePath="..\..\test\type_traits.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

98
test/type_traits.cpp Normal file
View File

@@ -0,0 +1,98 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2015-2015.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/move for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#include <boost/move/detail/type_traits.hpp>
#include <boost/move/core.hpp>
#include <boost/static_assert.hpp>
#include <boost/core/lightweight_test.hpp>
//
// pod_struct
//
#if defined(BOOST_MOVE_IS_POD)
struct pod_struct
{
int i;
float f;
};
#endif
//
// deleted_copy_and_assign_type
//
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
struct deleted_copy_and_assign_type
{
deleted_copy_and_assign_type(const deleted_copy_and_assign_type&) = delete;
deleted_copy_and_assign_type & operator=(const deleted_copy_and_assign_type&) = delete;
};
#endif //defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
//
// boost_move_type
//
class boost_move_type
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(boost_move_type)
public:
boost_move_type(BOOST_RV_REF(boost_move_type)){}
boost_move_type & operator=(BOOST_RV_REF(boost_move_type)){ return *this; }
};
namespace is_pod_test
{
void test()
{
BOOST_STATIC_ASSERT((boost::move_detail::is_pod<int>::value));
#if defined(BOOST_MOVE_IS_POD)
BOOST_STATIC_ASSERT((boost::move_detail::is_pod<pod_struct>::value));
#endif
}
} //namespace is_pod_test
namespace trivially_memcopyable_test {
void test()
{
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_constructible<deleted_copy_and_assign_type>::value));
BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_assignable<deleted_copy_and_assign_type>::value));
#endif //#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
//boost_move_type
BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_constructible<boost_move_type>::value));
BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_assignable<boost_move_type>::value));
BOOST_STATIC_ASSERT(!(boost::move_detail::is_copy_constructible<boost_move_type>::value));
BOOST_STATIC_ASSERT(!(boost::move_detail::is_copy_assignable<boost_move_type>::value));
//POD
BOOST_STATIC_ASSERT((boost::move_detail::is_trivially_copy_constructible<int>::value));
BOOST_STATIC_ASSERT((boost::move_detail::is_trivially_copy_assignable<int>::value));
BOOST_STATIC_ASSERT((boost::move_detail::is_copy_constructible<int>::value));
BOOST_STATIC_ASSERT((boost::move_detail::is_copy_assignable<int>::value));
#if defined(BOOST_MOVE_IS_POD)
BOOST_STATIC_ASSERT((boost::move_detail::is_trivially_copy_constructible<pod_struct>::value));
BOOST_STATIC_ASSERT((boost::move_detail::is_trivially_copy_assignable<pod_struct>::value));
BOOST_STATIC_ASSERT((boost::move_detail::is_copy_constructible<pod_struct>::value));
BOOST_STATIC_ASSERT((boost::move_detail::is_copy_assignable<pod_struct>::value));
#endif
}
} //namespace trivially_memcopyable_test {
int main()
{
trivially_memcopyable_test::test();
is_pod_test::test();
boost::report_errors();
}

View File

@@ -149,12 +149,30 @@ void test()
} //namespace unique_ptr_element_type {
////////////////////////////////
// main
// unique_ptr_construct_assign_traits
////////////////////////////////
#if __cplusplus >= 201103L
#include <memory>
#endif
namespace unique_ptr_construct_assign_traits {
void test()
{
typedef bml::unique_ptr<int> unique_ptr_t;
//Even if BOOST_MOVE_TT_CXX11_IS_COPY_CONSTRUCTIBLE is not defined
//boost::unique_ptr shall work with boost::movelib traits
BOOST_STATIC_ASSERT(!(boost::move_detail::is_copy_constructible<unique_ptr_t>::value));
//Even if BOOST_MOVE_TT_CXX11_IS_COPY_ASSIGNABLE is not defined
//boost::unique_ptr shall work with boost::movelib traits
BOOST_STATIC_ASSERT(!(boost::move_detail::is_copy_assignable<unique_ptr_t>::value));
//Important traits for containers like boost::vector
BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_constructible<unique_ptr_t>::value));
BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_assignable<unique_ptr_t>::value));
}
} //namespace unique_ptr_construct_assign_traits {
////////////////////////////////
// main
////////////////////////////////
int main()
{
@@ -162,23 +180,10 @@ int main()
unique_ptr_pointer_type::test();
unique_ptr_deleter_type::test();
unique_ptr_element_type::test();
typedef bml::unique_ptr<int> unique_ptr_t;
BOOST_STATIC_ASSERT(!(boost::move_detail::is_copy_constructible<unique_ptr_t>::value));
BOOST_STATIC_ASSERT(!(boost::move_detail::is_copy_assignable<unique_ptr_t>::value));
BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_constructible<unique_ptr_t>::value));
BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_assignable<unique_ptr_t>::value));
#if __cplusplus >= 201103L
typedef std::unique_ptr<int> std_unique_ptr_t;
BOOST_STATIC_ASSERT(!(boost::move_detail::is_copy_constructible<std_unique_ptr_t>::value));
BOOST_STATIC_ASSERT(!(boost::move_detail::is_copy_assignable<std_unique_ptr_t>::value));
BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_constructible<std_unique_ptr_t>::value));
BOOST_STATIC_ASSERT(!(boost::move_detail::is_trivially_copy_assignable<std_unique_ptr_t>::value));
#endif
unique_ptr_construct_assign_traits::test();
//Test results
return boost::report_errors();
}
#include "unique_ptr_test_utils_end.hpp"