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 .DS_Store
out out
profiling profiling
build
deps

View File

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

View File

@ -7,21 +7,11 @@ configuration:
- Debug - Debug
- Release - Release
os: Visual Studio 2015
install: install:
- SET PATH=c:\python27;%PATH% - CALL scripts\build-appveyor.bat
- 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
build: OFF build: off
test: off
test: OFF deploy: off
test_script: OFF
deploy: OFF

View File

@ -3,7 +3,7 @@
["OS=='win'", { ["OS=='win'", {
"target_defaults": { "target_defaults": {
"default_configuration": "Release_x64", "default_configuration": "Release_x64",
"msbuild_toolset":"CTP_Nov2013", "msbuild_toolset":"v140",
"msvs_settings": { "msvs_settings": {
"VCCLCompilerTool": { "VCCLCompilerTool": {
"ExceptionHandling": 1, # /EHsc "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 <boost/timer/timer.hpp>
#include "variant.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 //#define BOOST_VARIANT_MINIMIZE_SIZE
using namespace mapbox; using namespace mapbox;
@ -52,9 +54,9 @@ struct dummy : boost::static_visitor<>
: v_(v) {} : v_(v) {}
template <typename T> template <typename T>
void operator() (T const& val) const void operator() (T && val) const
{ {
v_ = val; v_ = std::move(val);
} }
V & v_; V & v_;
}; };
@ -66,9 +68,9 @@ struct dummy2 : util::static_visitor<>
: v_(v) {} : v_(v) {}
template <typename T> 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_; V & v_;
}; };
@ -79,7 +81,8 @@ void run_boost_test(std::size_t runs)
h.data.reserve(runs); h.data.reserve(runs);
for (std::size_t i=0; i< runs; ++i) 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(123);
h.append_move(3.14159); h.append_move(3.14159);
} }
@ -98,7 +101,8 @@ void run_variant_test(std::size_t runs)
h.data.reserve(runs); h.data.reserve(runs);
for (std::size_t i=0; i< runs; ++i) 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(123);
h.append_move(3.14159); h.append_move(3.14159);
} }
@ -125,6 +129,10 @@ int main (int argc, char** argv)
const std::size_t NUM_RUNS = static_cast<std::size_t>(std::stol(argv[1])); const std::size_t NUM_RUNS = static_cast<std::size_t>(std::stol(argv[1]));
#ifdef SINGLE_THREADED #ifdef SINGLE_THREADED
for (std::size_t j = 0; j < NUM_SAMPLES; ++j)
{
{ {
std::cerr << "custom variant: "; std::cerr << "custom variant: ";
boost::timer::auto_cpu_timer t; boost::timer::auto_cpu_timer t;
@ -135,17 +143,11 @@ int main (int argc, char** argv)
boost::timer::auto_cpu_timer t; boost::timer::auto_cpu_timer t;
run_boost_test(NUM_RUNS); 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 #else
for (std::size_t j = 0; j < NUM_SAMPLES; ++j)
{
{ {
typedef std::vector<std::unique_ptr<std::thread>> thread_group; typedef std::vector<std::unique_ptr<std::thread>> thread_group;
typedef thread_group::value_type value_type; typedef thread_group::value_type value_type;
@ -171,31 +173,6 @@ int main (int argc, char** argv)
} }
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 #endif

View File

@ -90,6 +90,21 @@ struct value_traits
(direct_index == invalid_value) ? convertible_type<T, Types...>::index : direct_index; (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> template <typename T, typename...Types>
struct is_valid_type; struct is_valid_type;
@ -214,6 +229,20 @@ struct variant_helper<T, Types...>
variant_helper<Types...>::copy(old_id, old_value, new_value); 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<> 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 destroy(const std::size_t, void *) {}
VARIANT_INLINE static void move(const std::size_t, void *, 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 copy(const std::size_t, const void *, void *) {}
VARIANT_INLINE static void direct_swap(const std::size_t, void *, void *) {}
}; };
namespace detail { namespace detail {
@ -561,16 +591,33 @@ public:
helper_type::move(old.type_index, &old.data, &data); 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 helper_type::destroy(type_index, &data);
swap(first.type_index, second.type_index); type_index = detail::invalid_value;
swap(first.data, second.data); 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; return *this;
} }
@ -580,7 +627,7 @@ public:
VARIANT_INLINE variant<Types...>& operator=(T && rhs) noexcept VARIANT_INLINE variant<Types...>& operator=(T && rhs) noexcept
{ {
variant<Types...> temp(std::forward<T>(rhs)); variant<Types...> temp(std::forward<T>(rhs));
swap(*this, temp); move_assign(std::move(temp));
return *this; return *this;
} }
@ -589,13 +636,14 @@ public:
VARIANT_INLINE variant<Types...>& operator=(T const& rhs) VARIANT_INLINE variant<Types...>& operator=(T const& rhs)
{ {
variant<Types...> temp(rhs); variant<Types...> temp(rhs);
swap(*this, temp); copy_assign(temp);
return *this; return *this;
} }
template<typename T> template<typename T>
VARIANT_INLINE bool is() const 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); return (type_index == detail::direct_type<T, Types...>::index);
} }
@ -613,7 +661,9 @@ public:
} }
// get<T>() // 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() VARIANT_INLINE T& get()
{ {
if (type_index == detail::direct_type<T, Types...>::index) if (type_index == detail::direct_type<T, Types...>::index)