diff --git a/third_party/variant/.gitignore b/third_party/variant/.gitignore index 5620e5dd1..984cc2fe8 100644 --- a/third_party/variant/.gitignore +++ b/third_party/variant/.gitignore @@ -1,3 +1,5 @@ .DS_Store out -profiling \ No newline at end of file +profiling +build +deps diff --git a/third_party/variant/Jamroot b/third_party/variant/Jamroot index aead87091..aa2137537 100644 --- a/third_party/variant/Jamroot +++ b/third_party/variant/Jamroot @@ -1,4 +1,4 @@ -local BOOST_DIR = "/opt/boost" ; +local BOOST_DIR = "/usr/local" ; #using clang : : ; diff --git a/third_party/variant/appveyor.yml b/third_party/variant/appveyor.yml index 9d7c59984..050ad25dd 100644 --- a/third_party/variant/appveyor.yml +++ b/third_party/variant/appveyor.yml @@ -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 diff --git a/third_party/variant/common.gypi b/third_party/variant/common.gypi index 67e333b7e..d4f09f880 100644 --- a/third_party/variant/common.gypi +++ b/third_party/variant/common.gypi @@ -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 diff --git a/third_party/variant/scripts/build-appveyor.bat b/third_party/variant/scripts/build-appveyor.bat new file mode 100644 index 000000000..9b9d7c8db --- /dev/null +++ b/third_party/variant/scripts/build-appveyor.bat @@ -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 diff --git a/third_party/variant/scripts/build-local.bat b/third_party/variant/scripts/build-local.bat new file mode 100644 index 000000000..34a2e6112 --- /dev/null +++ b/third_party/variant/scripts/build-local.bat @@ -0,0 +1,7 @@ +@ECHO OFF +SETLOCAL + +SET platform=x64 +SET configuration=Release + +CALL scripts\build-appveyor.bat \ No newline at end of file diff --git a/third_party/variant/test/bench_variant.cpp b/third_party/variant/test/bench_variant.cpp index f27124593..474e3c36c 100644 --- a/third_party/variant/test/bench_variant.cpp +++ b/third_party/variant/test/bench_variant.cpp @@ -7,7 +7,9 @@ #include #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 - 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 - void operator() (T const& val) const + void operator() (T && val) const { - v_.template set(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::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> 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> 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; ijoinable()) t->join();}); } - std::for_each(tg.begin(), tg.end(), [](value_type & t) {if (t->joinable()) t->join();}); - } - { - typedef std::vector> 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> 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; ijoinable()) t->join();}); } - std::for_each(tg.begin(), tg.end(), [](value_type & t) {if (t->joinable()) t->join();}); - } - - { - typedef std::vector> 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; ijoinable()) t->join();}); - } - - { - typedef std::vector> 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; ijoinable()) t->join();}); } #endif diff --git a/third_party/variant/variant.hpp b/third_party/variant/variant.hpp index 837b162df..90aacae00 100644 --- a/third_party/variant/variant.hpp +++ b/third_party/variant/variant.hpp @@ -90,6 +90,21 @@ struct value_traits (direct_index == invalid_value) ? convertible_type::index : direct_index; }; +// check if T is in Types... +template +struct has_type; + +template +struct has_type +{ + static constexpr bool value = std::is_same::value + || has_type::value; +}; + +template +struct has_type : std::false_type {}; +// + template struct is_valid_type; @@ -214,6 +229,20 @@ struct variant_helper variant_helper::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(lhs), *reinterpret_cast(rhs)); + } + else + { + variant_helper::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 & first, variant & second) +private: + VARIANT_INLINE void copy_assign(variant 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& operator=(variant other) + VARIANT_INLINE void move_assign(variant && 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& operator=(variant && other) + { + move_assign(std::move(other)); + return *this; + } + + VARIANT_INLINE variant& operator=(variant const& other) + { + copy_assign(other); return *this; } @@ -580,7 +627,7 @@ public: VARIANT_INLINE variant& operator=(T && rhs) noexcept { variant temp(std::forward(rhs)); - swap(*this, temp); + move_assign(std::move(temp)); return *this; } @@ -589,13 +636,14 @@ public: VARIANT_INLINE variant& operator=(T const& rhs) { variant temp(rhs); - swap(*this, temp); + copy_assign(temp); return *this; } template VARIANT_INLINE bool is() const { + static_assert(detail::has_type::value, "invalid type in T in `is()` for this variant"); return (type_index == detail::direct_type::index); } @@ -613,7 +661,9 @@ public: } // get() - template::index != detail::invalid_value)>::type* = nullptr> + template::index != detail::invalid_value) + >::type* = nullptr> VARIANT_INLINE T& get() { if (type_index == detail::direct_type::index)