Update variant to 91ba0301a672ea0a3131390d44d304c5493de84a, specifically this commit: 39a631394e, which fixes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68073 under GCC 5.2.1.

Fixes  #1758
This commit is contained in:
Daniel Patterson 2015-11-03 21:56:26 -08:00
parent bb49e03435
commit a62c10321c
8 changed files with 155 additions and 97 deletions

View File

@ -1,3 +1,5 @@
.DS_Store
out
profiling
profiling
build
deps

View File

@ -1,4 +1,4 @@
local BOOST_DIR = "/opt/boost" ;
local BOOST_DIR = "/usr/local" ;
#using clang : : ;

View File

@ -7,21 +7,11 @@ configuration:
- Debug
- Release
os: Visual Studio 2015
install:
- SET PATH=c:\python27;%PATH%
- SET PATH=C:\Program Files (x86)\MSBuild\12.0\bin\;%PATH%
- git clone --quiet --depth 1 https://chromium.googlesource.com/external/gyp.git deps/gyp
# note windows requires --generator-output to be absolute
- python deps/gyp/gyp_main.py variant.gyp --depth=. -f msvs -G msvs_version=2013
- set MSBUILD_PLATFORM=%platform%
- if "%MSBUILD_PLATFORM%" == "x86" set MSBUILD_PLATFORM=Win32
- msbuild variant.sln /nologo /p:Configuration=%configuration%;Platform=%MSBUILD_PLATFORM%
- .\"%configuration%"\tests.exe
- CALL scripts\build-appveyor.bat
build: OFF
test: OFF
test_script: OFF
deploy: OFF
build: off
test: off
deploy: off

View File

@ -3,7 +3,7 @@
["OS=='win'", {
"target_defaults": {
"default_configuration": "Release_x64",
"msbuild_toolset":"CTP_Nov2013",
"msbuild_toolset":"v140",
"msvs_settings": {
"VCCLCompilerTool": {
"ExceptionHandling": 1, # /EHsc

View File

@ -0,0 +1,32 @@
@ECHO OFF
SETLOCAL
SET PATH=c:\python27;%PATH%
ECHO activating VS command prompt
IF /I "%PLATFORM"=="x64" (
CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64
) ELSE (
CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86
)
IF NOT EXIST deps\gyp git clone --depth 1 https://chromium.googlesource.com/external/gyp.git deps/gyp
CALL deps\gyp\gyp.bat variant.gyp --depth=. ^
-f msvs ^
-G msvs_version=2015 ^
--generator-output=build
SET MSBUILD_PLATFORM=%platform%
IF /I "%MSBUILD_PLATFORM%" == "x86" SET MSBUILD_PLATFORM=Win32
msbuild ^
build\variant.sln ^
/nologo ^
/toolsversion:14.0 ^
/p:PlatformToolset=v140 ^
/p:Configuration=%configuration% ^
/p:Platform=%MSBUILD_PLATFORM%
build\"%configuration%"\tests.exe

View File

@ -0,0 +1,7 @@
@ECHO OFF
SETLOCAL
SET platform=x64
SET configuration=Release
CALL scripts\build-appveyor.bat

View File

@ -7,7 +7,9 @@
#include <boost/timer/timer.hpp>
#include "variant.hpp"
#define TEXT "Testing various variant implementations with a longish string ........................................."
#define TEXT_SHORT "Test"
#define TEXT_LONG "Testing various variant implementations with a longish string ........................................."
#define NUM_SAMPLES 3
//#define BOOST_VARIANT_MINIMIZE_SIZE
using namespace mapbox;
@ -52,9 +54,9 @@ struct dummy : boost::static_visitor<>
: v_(v) {}
template <typename T>
void operator() (T const& val) const
void operator() (T && val) const
{
v_ = val;
v_ = std::move(val);
}
V & v_;
};
@ -66,9 +68,9 @@ struct dummy2 : util::static_visitor<>
: v_(v) {}
template <typename T>
void operator() (T const& val) const
void operator() (T && val) const
{
v_.template set<T>(val);
v_ = std::move(val);
}
V & v_;
};
@ -79,7 +81,8 @@ void run_boost_test(std::size_t runs)
h.data.reserve(runs);
for (std::size_t i=0; i< runs; ++i)
{
h.append_move(std::string(TEXT));
h.append_move(std::string(TEXT_SHORT));
h.append_move(std::string(TEXT_LONG));
h.append_move(123);
h.append_move(3.14159);
}
@ -98,7 +101,8 @@ void run_variant_test(std::size_t runs)
h.data.reserve(runs);
for (std::size_t i=0; i< runs; ++i)
{
h.append_move(std::string(TEXT));
h.append_move(std::string(TEXT_SHORT));
h.append_move(std::string(TEXT_LONG));
h.append_move(123);
h.append_move(3.14159);
}
@ -125,77 +129,50 @@ int main (int argc, char** argv)
const std::size_t NUM_RUNS = static_cast<std::size_t>(std::stol(argv[1]));
#ifdef SINGLE_THREADED
for (std::size_t j = 0; j < NUM_SAMPLES; ++j)
{
std::cerr << "custom variant: ";
boost::timer::auto_cpu_timer t;
run_variant_test(NUM_RUNS);
}
{
std::cerr << "boost variant: ";
boost::timer::auto_cpu_timer t;
run_boost_test(NUM_RUNS);
}
{
std::cerr << "custom variant: ";
boost::timer::auto_cpu_timer t;
run_variant_test(NUM_RUNS);
}
{
std::cerr << "boost variant: ";
boost::timer::auto_cpu_timer t;
run_boost_test(NUM_RUNS);
{
std::cerr << "custom variant: ";
boost::timer::auto_cpu_timer t;
run_variant_test(NUM_RUNS);
}
{
std::cerr << "boost variant: ";
boost::timer::auto_cpu_timer t;
run_boost_test(NUM_RUNS);
}
}
#else
for (std::size_t j = 0; j < NUM_SAMPLES; ++j)
{
typedef std::vector<std::unique_ptr<std::thread>> thread_group;
typedef thread_group::value_type value_type;
thread_group tg;
std::cerr << "custom variant: ";
boost::timer::auto_cpu_timer timer;
for (std::size_t i=0; i<THREADS; ++i)
{
tg.emplace_back(new std::thread(run_variant_test, NUM_RUNS));
typedef std::vector<std::unique_ptr<std::thread>> thread_group;
typedef thread_group::value_type value_type;
thread_group tg;
std::cerr << "custom variant: ";
boost::timer::auto_cpu_timer timer;
for (std::size_t i=0; i<THREADS; ++i)
{
tg.emplace_back(new std::thread(run_variant_test, NUM_RUNS));
}
std::for_each(tg.begin(), tg.end(), [](value_type & t) {if (t->joinable()) t->join();});
}
std::for_each(tg.begin(), tg.end(), [](value_type & t) {if (t->joinable()) t->join();});
}
{
typedef std::vector<std::unique_ptr<std::thread>> thread_group;
typedef thread_group::value_type value_type;
thread_group tg;
std::cerr << "boost variant: ";
boost::timer::auto_cpu_timer timer;
for (std::size_t i=0; i<THREADS; ++i)
{
tg.emplace_back(new std::thread(run_boost_test, NUM_RUNS));
typedef std::vector<std::unique_ptr<std::thread>> thread_group;
typedef thread_group::value_type value_type;
thread_group tg;
std::cerr << "boost variant: ";
boost::timer::auto_cpu_timer timer;
for (std::size_t i=0; i<THREADS; ++i)
{
tg.emplace_back(new std::thread(run_boost_test, NUM_RUNS));
}
std::for_each(tg.begin(), tg.end(), [](value_type & t) {if (t->joinable()) t->join();});
}
std::for_each(tg.begin(), tg.end(), [](value_type & t) {if (t->joinable()) t->join();});
}
{
typedef std::vector<std::unique_ptr<std::thread>> thread_group;
typedef thread_group::value_type value_type;
thread_group tg;
std::cerr << "custom variant: ";
boost::timer::auto_cpu_timer timer;
for (std::size_t i=0; i<THREADS; ++i)
{
tg.emplace_back(new std::thread(run_variant_test, NUM_RUNS));
}
std::for_each(tg.begin(), tg.end(), [](value_type & t) {if (t->joinable()) t->join();});
}
{
typedef std::vector<std::unique_ptr<std::thread>> thread_group;
typedef thread_group::value_type value_type;
thread_group tg;
std::cerr << "boost variant: ";
boost::timer::auto_cpu_timer timer;
for (std::size_t i=0; i<THREADS; ++i)
{
tg.emplace_back(new std::thread(run_boost_test, NUM_RUNS));
}
std::for_each(tg.begin(), tg.end(), [](value_type & t) {if (t->joinable()) t->join();});
}
#endif

View File

@ -90,6 +90,21 @@ struct value_traits
(direct_index == invalid_value) ? convertible_type<T, Types...>::index : direct_index;
};
// check if T is in Types...
template <typename T, typename...Types>
struct has_type;
template <typename T, typename First, typename... Types>
struct has_type<T, First, Types...>
{
static constexpr bool value = std::is_same<T, First>::value
|| has_type<T, Types...>::value;
};
template <typename T>
struct has_type<T> : std::false_type {};
//
template <typename T, typename...Types>
struct is_valid_type;
@ -214,6 +229,20 @@ struct variant_helper<T, Types...>
variant_helper<Types...>::copy(old_id, old_value, new_value);
}
}
VARIANT_INLINE static void direct_swap(const std::size_t id, void * lhs, void * rhs)
{
using std::swap; //enable ADL
if (id == sizeof...(Types))
{
// both lhs and rhs hold T
swap(*reinterpret_cast<T*>(lhs), *reinterpret_cast<T*>(rhs));
}
else
{
variant_helper<Types...>::direct_swap(id, lhs, rhs);
}
}
};
template<> struct variant_helper<>
@ -221,6 +250,7 @@ template<> struct variant_helper<>
VARIANT_INLINE static void destroy(const std::size_t, void *) {}
VARIANT_INLINE static void move(const std::size_t, void *, void *) {}
VARIANT_INLINE static void copy(const std::size_t, const void *, void *) {}
VARIANT_INLINE static void direct_swap(const std::size_t, void *, void *) {}
};
namespace detail {
@ -561,16 +591,33 @@ public:
helper_type::move(old.type_index, &old.data, &data);
}
friend void swap(variant<Types...> & first, variant<Types...> & second)
private:
VARIANT_INLINE void copy_assign(variant<Types...> const& rhs)
{
using std::swap; //enable ADL
swap(first.type_index, second.type_index);
swap(first.data, second.data);
helper_type::destroy(type_index, &data);
type_index = detail::invalid_value;
helper_type::copy(rhs.type_index, &rhs.data, &data);
type_index = rhs.type_index;
}
VARIANT_INLINE variant<Types...>& operator=(variant<Types...> other)
VARIANT_INLINE void move_assign(variant<Types...> && rhs)
{
swap(*this, other);
helper_type::destroy(type_index, &data);
type_index = detail::invalid_value;
helper_type::move(rhs.type_index, &rhs.data, &data);
type_index = rhs.type_index;
}
public:
VARIANT_INLINE variant<Types...>& operator=(variant<Types...> && other)
{
move_assign(std::move(other));
return *this;
}
VARIANT_INLINE variant<Types...>& operator=(variant<Types...> const& other)
{
copy_assign(other);
return *this;
}
@ -580,7 +627,7 @@ public:
VARIANT_INLINE variant<Types...>& operator=(T && rhs) noexcept
{
variant<Types...> temp(std::forward<T>(rhs));
swap(*this, temp);
move_assign(std::move(temp));
return *this;
}
@ -589,13 +636,14 @@ public:
VARIANT_INLINE variant<Types...>& operator=(T const& rhs)
{
variant<Types...> temp(rhs);
swap(*this, temp);
copy_assign(temp);
return *this;
}
template<typename T>
VARIANT_INLINE bool is() const
{
static_assert(detail::has_type<T, Types...>::value, "invalid type in T in `is<T>()` for this variant");
return (type_index == detail::direct_type<T, Types...>::index);
}
@ -613,7 +661,9 @@ public:
}
// get<T>()
template<typename T, typename std::enable_if<(detail::direct_type<T, Types...>::index != detail::invalid_value)>::type* = nullptr>
template<typename T, typename std::enable_if<
(detail::direct_type<T, Types...>::index != detail::invalid_value)
>::type* = nullptr>
VARIANT_INLINE T& get()
{
if (type_index == detail::direct_type<T, Types...>::index)