Remove variant
This commit is contained in:
parent
17babb22e2
commit
be2cc7aed9
5
third_party/variant/.gitignore
vendored
5
third_party/variant/.gitignore
vendored
@ -1,5 +0,0 @@
|
||||
.DS_Store
|
||||
out
|
||||
profiling
|
||||
build
|
||||
deps
|
22
third_party/variant/.travis.yml
vendored
22
third_party/variant/.travis.yml
vendored
@ -1,22 +0,0 @@
|
||||
language: cpp
|
||||
|
||||
# http://docs.travis-ci.com/user/multi-os/
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
|
||||
before_install:
|
||||
- true
|
||||
|
||||
install:
|
||||
- true
|
||||
|
||||
before_script:
|
||||
- true
|
||||
|
||||
script:
|
||||
- source "scripts/${TRAVIS_OS_NAME}.sh"
|
75
third_party/variant/Jamroot
vendored
75
third_party/variant/Jamroot
vendored
@ -1,75 +0,0 @@
|
||||
local BOOST_DIR = "/usr/local" ;
|
||||
|
||||
#using clang : : ;
|
||||
|
||||
lib system : : <name>boost_system <search>$(BOOST_DIR)/lib ;
|
||||
lib timer : chrono : <name>boost_timer <search>$(BOOST_DIR)/lib ;
|
||||
lib chrono : system : <name>boost_chrono <search>$(BOOST_DIR)/lib ;
|
||||
|
||||
exe variant-test
|
||||
:
|
||||
test/bench_variant.cpp
|
||||
.//system
|
||||
.//timer
|
||||
.//chrono
|
||||
:
|
||||
<include>$(BOOST_DIR)/include
|
||||
<include>./
|
||||
<cxxflags>-std=c++11
|
||||
#<define>SINGLE_THREADED
|
||||
<variant>release:<cxxflags>-march=native
|
||||
;
|
||||
|
||||
|
||||
exe binary-visitor-test
|
||||
:
|
||||
test/binary_visitor_test.cpp
|
||||
.//system
|
||||
.//timer
|
||||
.//chrono
|
||||
:
|
||||
<include>$(BOOST_DIR)/include
|
||||
<include>./
|
||||
<cxxflags>-std=c++11
|
||||
<variant>release:<cxxflags>-march=native
|
||||
;
|
||||
|
||||
exe recursive-wrapper-test
|
||||
:
|
||||
test/recursive_wrapper_test.cpp
|
||||
.//system
|
||||
.//timer
|
||||
.//chrono
|
||||
:
|
||||
<include>$(BOOST_DIR)/include
|
||||
<include>./
|
||||
<cxxflags>-std=c++11
|
||||
<variant>release:<cxxflags>-march=native
|
||||
;
|
||||
|
||||
exe unique-ptr-test
|
||||
:
|
||||
test/unique_ptr_test.cpp
|
||||
.//system
|
||||
.//timer
|
||||
.//chrono
|
||||
:
|
||||
<include>$(BOOST_DIR)/include
|
||||
<include>./
|
||||
<cxxflags>-std=c++11
|
||||
<variant>release:<cxxflags>-march=native
|
||||
;
|
||||
|
||||
|
||||
exe reference_wrapper_test
|
||||
:
|
||||
test/reference_wrapper_test.cpp
|
||||
.//system
|
||||
.//timer
|
||||
.//chrono
|
||||
:
|
||||
<include>$(BOOST_DIR)/include
|
||||
<include>./
|
||||
<cxxflags>-std=c++11
|
||||
<variant>release:<cxxflags>-march=native
|
||||
;
|
25
third_party/variant/LICENSE
vendored
25
third_party/variant/LICENSE
vendored
@ -1,25 +0,0 @@
|
||||
Copyright (c) MapBox
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
- Neither the name "MapBox" nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
100
third_party/variant/Makefile
vendored
100
third_party/variant/Makefile
vendored
@ -1,100 +0,0 @@
|
||||
CXX := $(CXX)
|
||||
BOOST_LIBS = -lboost_timer -lboost_system -lboost_chrono
|
||||
RELEASE_FLAGS = -O3 -DNDEBUG -finline-functions -march=native -DSINGLE_THREADED
|
||||
DEBUG_FLAGS = -O0 -g -DDEBUG -fno-inline-functions
|
||||
COMMON_FLAGS = -Wall -Wsign-compare -Wsign-conversion -Wshadow -Wunused-parameter -pedantic -fvisibility-inlines-hidden -std=c++11
|
||||
CXXFLAGS := $(CXXFLAGS)
|
||||
LDFLAGS := $(LDFLAGS)
|
||||
|
||||
OS:=$(shell uname -s)
|
||||
ifeq ($(OS),Darwin)
|
||||
CXXFLAGS += -stdlib=libc++
|
||||
LDFLAGS += -stdlib=libc++ -F/ -framework CoreFoundation
|
||||
else
|
||||
BOOST_LIBS += -lrt
|
||||
endif
|
||||
|
||||
ifeq (sizes,$(firstword $(MAKECMDGOALS)))
|
||||
RUN_ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
|
||||
$(eval $(RUN_ARGS):;@:)
|
||||
ifndef RUN_ARGS
|
||||
$(error sizes target requires you pass full path to boost variant.hpp)
|
||||
endif
|
||||
.PHONY: $(RUN_ARGS)
|
||||
endif
|
||||
|
||||
all: out/bench-variant out/unique_ptr_test out/unique_ptr_test out/recursive_wrapper_test out/binary_visitor_test
|
||||
|
||||
./deps/gyp:
|
||||
git clone --depth 1 https://chromium.googlesource.com/external/gyp.git ./deps/gyp
|
||||
|
||||
gyp: ./deps/gyp
|
||||
deps/gyp/gyp --depth=. -Goutput_dir=./ --generator-output=./out -f make
|
||||
make V=1 -C ./out tests
|
||||
./out/Release/tests
|
||||
|
||||
out/bench-variant-debug: Makefile test/bench_variant.cpp variant.hpp
|
||||
mkdir -p ./out
|
||||
$(CXX) -o out/bench-variant-debug test/bench_variant.cpp -I./ $(DEBUG_FLAGS) $(COMMON_FLAGS) $(CXXFLAGS) $(LDFLAGS) $(BOOST_LIBS)
|
||||
|
||||
out/bench-variant: Makefile test/bench_variant.cpp variant.hpp
|
||||
mkdir -p ./out
|
||||
$(CXX) -o out/bench-variant test/bench_variant.cpp -I./ $(RELEASE_FLAGS) $(COMMON_FLAGS) $(CXXFLAGS) $(LDFLAGS) $(BOOST_LIBS)
|
||||
|
||||
out/unique_ptr_test: Makefile test/unique_ptr_test.cpp variant.hpp
|
||||
mkdir -p ./out
|
||||
$(CXX) -o out/unique_ptr_test test/unique_ptr_test.cpp -I./ $(RELEASE_FLAGS) $(COMMON_FLAGS) $(CXXFLAGS) $(LDFLAGS) $(BOOST_LIBS)
|
||||
|
||||
out/recursive_wrapper_test: Makefile test/recursive_wrapper_test.cpp variant.hpp
|
||||
mkdir -p ./out
|
||||
$(CXX) -o out/recursive_wrapper_test test/recursive_wrapper_test.cpp -I./ $(RELEASE_FLAGS) $(COMMON_FLAGS) $(CXXFLAGS) $(LDFLAGS) $(BOOST_LIBS)
|
||||
|
||||
out/binary_visitor_test: Makefile test/binary_visitor_test.cpp variant.hpp
|
||||
mkdir -p ./out
|
||||
$(CXX) -o out/binary_visitor_test test/binary_visitor_test.cpp -I./ $(RELEASE_FLAGS) $(COMMON_FLAGS) $(CXXFLAGS) $(LDFLAGS) $(BOOST_LIBS)
|
||||
|
||||
bench: out/bench-variant out/unique_ptr_test out/unique_ptr_test out/recursive_wrapper_test out/binary_visitor_test
|
||||
./out/bench-variant 100000
|
||||
./out/unique_ptr_test 100000
|
||||
./out/recursive_wrapper_test 100000
|
||||
./out/binary_visitor_test 100000
|
||||
|
||||
out/unit: Makefile test/unit.cpp test/optional_unit.cpp optional.hpp variant.hpp
|
||||
mkdir -p ./out
|
||||
$(CXX) -o out/unit test/unit.cpp -I./ $(RELEASE_FLAGS) $(COMMON_FLAGS) $(CXXFLAGS) $(LDFLAGS)
|
||||
$(CXX) -o out/optional_unit test/optional_unit.cpp -I./ $(RELEASE_FLAGS) $(COMMON_FLAGS) $(CXXFLAGS) $(LDFLAGS)
|
||||
|
||||
test: out/unit
|
||||
./out/unit
|
||||
./out/optional_unit
|
||||
|
||||
coverage:
|
||||
mkdir -p ./out
|
||||
$(CXX) -o out/cov-test --coverage test/unit.cpp -I./ $(DEBUG_FLAGS) $(COMMON_FLAGS) $(CXXFLAGS) $(LDFLAGS)
|
||||
|
||||
sizes: Makefile variant.hpp
|
||||
mkdir -p ./out
|
||||
@$(CXX) -o ./out/variant_hello_world.out variant.hpp $(RELEASE_FLAGS) $(COMMON_FLAGS) $(CXXFLAGS) && du -h ./out/variant_hello_world.out
|
||||
@$(CXX) -o ./out/boost_variant_hello_world.out $(RUN_ARGS) $(RELEASE_FLAGS) $(COMMON_FLAGS) $(CXXFLAGS) && du -h ./out/boost_variant_hello_world.out
|
||||
@$(CXX) -o ./out/variant_hello_world ./test/variant_hello_world.cpp -I./ $(RELEASE_FLAGS) $(COMMON_FLAGS) $(CXXFLAGS) && du -h ./out/variant_hello_world
|
||||
@$(CXX) -o ./out/boost_variant_hello_world ./test/boost_variant_hello_world.cpp -I./ $(RELEASE_FLAGS) $(COMMON_FLAGS) $(CXXFLAGS) && du -h ./out/boost_variant_hello_world
|
||||
|
||||
profile: out/bench-variant-debug
|
||||
mkdir -p profiling/
|
||||
rm -rf profiling/*
|
||||
iprofiler -timeprofiler -d profiling/ ./out/bench-variant-debug 500000
|
||||
|
||||
clean:
|
||||
rm -rf ./out
|
||||
rm -rf *.dSYM
|
||||
rm -f unit.gc*
|
||||
rm -f *gcov
|
||||
rm -f test/unit.gc*
|
||||
rm -f test/*gcov
|
||||
|
||||
pgo: out Makefile variant.hpp
|
||||
$(CXX) -o out/bench-variant test/bench_variant.cpp -I./ $(RELEASE_FLAGS) $(COMMON_FLAGS) $(CXXFLAGS) $(LDFLAGS) $(BOOST_LIBS) -pg -fprofile-generate
|
||||
./test-variant 500000 >/dev/null 2>/dev/null
|
||||
$(CXX) -o out/bench-variant test/bench_variant.cpp -I./ $(RELEASE_FLAGS) $(COMMON_FLAGS) $(CXXFLAGS) $(LDFLAGS) $(BOOST_LIBS) -fprofile-use
|
||||
|
||||
.PHONY: sizes test
|
67
third_party/variant/README.md
vendored
67
third_party/variant/README.md
vendored
@ -1,67 +0,0 @@
|
||||
# Mapbox Variant
|
||||
|
||||
An alternative to `boost::variant` for C++11.
|
||||
|
||||
[](https://travis-ci.org/mapbox/variant)
|
||||
[](https://ci.appveyor.com/project/Mapbox/variant)
|
||||
[](https://coveralls.io/r/mapbox/variant?branch=master)
|
||||
|
||||
# Why use Mapbox Variant?
|
||||
|
||||
Mapbox variant has the same speedy performance of `boost::variant` but is faster to compile, results in smaller binaries, and has no dependencies.
|
||||
|
||||
For example on OS X 10.9 with clang++ and libc++:
|
||||
|
||||
Test | Mapbox Variant | Boost Variant
|
||||
---- | -------------- | -------------
|
||||
Size of pre-compiled header (release / debug) | 2.8/2.8 MB | 12/15 MB
|
||||
Size of simple program linking variant (release / debug) | 8/24 K | 12/40 K
|
||||
Time to compile header | 185 ms | 675 ms
|
||||
|
||||
|
||||
# Depends
|
||||
|
||||
- Compiler supporting `-std=c++11`
|
||||
|
||||
Tested with
|
||||
|
||||
- g++-4.7
|
||||
- g++-4.8
|
||||
- clang++-3.4
|
||||
- clang++-3.5
|
||||
- Visual C++ Compiler November 2013 CTP
|
||||
- Visual C++ Compiler 2014 CTP 4
|
||||
|
||||
Note: get the "2013 Nov CTP" release at http://www.microsoft.com/en-us/download/details.aspx?id=41151 and the 2014 CTP at http://www.visualstudio.com/en-us/downloads/visual-studio-14-ctp-vs.aspx
|
||||
|
||||
# Usage
|
||||
|
||||
There is nothing to build, just include `variant.hpp` and `recursive_wrapper.hpp` in your project.
|
||||
|
||||
# Tests
|
||||
|
||||
The tests depend on:
|
||||
|
||||
- Boost headers (for benchmarking against `boost::variant`)
|
||||
- Boost built with `--with-timer` (used for benchmark timing)
|
||||
|
||||
On Unix systems set your boost includes and libs locations and run `make test`:
|
||||
|
||||
export LDFLAGS='-L/opt/boost/lib'
|
||||
export CXXFLAGS='-I/opt/boost/include'
|
||||
make test
|
||||
|
||||
On windows do:
|
||||
|
||||
vcbuild
|
||||
|
||||
## Benchmark
|
||||
|
||||
On Unix systems run the benchmark like:
|
||||
|
||||
make bench
|
||||
|
||||
## Check object sizes
|
||||
|
||||
make sizes /path/to/boost/variant.hpp
|
||||
|
17
third_party/variant/appveyor.yml
vendored
17
third_party/variant/appveyor.yml
vendored
@ -1,17 +0,0 @@
|
||||
|
||||
platform:
|
||||
- x64
|
||||
- x86
|
||||
|
||||
configuration:
|
||||
- Debug
|
||||
- Release
|
||||
|
||||
os: Visual Studio 2015
|
||||
|
||||
install:
|
||||
- CALL scripts\build-appveyor.bat
|
||||
|
||||
build: off
|
||||
test: off
|
||||
deploy: off
|
143
third_party/variant/common.gypi
vendored
143
third_party/variant/common.gypi
vendored
@ -1,143 +0,0 @@
|
||||
{
|
||||
"conditions": [
|
||||
["OS=='win'", {
|
||||
"target_defaults": {
|
||||
"default_configuration": "Release_x64",
|
||||
"msbuild_toolset":"v140",
|
||||
"msvs_settings": {
|
||||
"VCCLCompilerTool": {
|
||||
"ExceptionHandling": 1, # /EHsc
|
||||
"RuntimeTypeInfo": "true" # /GR
|
||||
}
|
||||
},
|
||||
"configurations": {
|
||||
"Debug_Win32": {
|
||||
"msvs_configuration_platform": "Win32",
|
||||
"defines": [ "DEBUG","_DEBUG"],
|
||||
"msvs_settings": {
|
||||
"VCCLCompilerTool": {
|
||||
"RuntimeLibrary": "1", # static debug /MTd
|
||||
"Optimization": 0, # /Od, no optimization
|
||||
"MinimalRebuild": "false",
|
||||
"OmitFramePointers": "false",
|
||||
"BasicRuntimeChecks": 3 # /RTC1
|
||||
}
|
||||
}
|
||||
},
|
||||
"Debug_x64": {
|
||||
"msvs_configuration_platform": "x64",
|
||||
"defines": [ "DEBUG","_DEBUG"],
|
||||
"msvs_settings": {
|
||||
"VCCLCompilerTool": {
|
||||
"RuntimeLibrary": "1", # static debug /MTd
|
||||
"Optimization": 0, # /Od, no optimization
|
||||
"MinimalRebuild": "false",
|
||||
"OmitFramePointers": "false",
|
||||
"BasicRuntimeChecks": 3 # /RTC1
|
||||
}
|
||||
}
|
||||
},
|
||||
"Release_Win32": {
|
||||
"msvs_configuration_platform": "Win32",
|
||||
"defines": [ "NDEBUG"],
|
||||
"msvs_settings": {
|
||||
"VCCLCompilerTool": {
|
||||
"RuntimeLibrary": 0, # static release
|
||||
"Optimization": 3, # /Ox, full optimization
|
||||
"FavorSizeOrSpeed": 1, # /Ot, favour speed over size
|
||||
"InlineFunctionExpansion": 2, # /Ob2, inline anything eligible
|
||||
"WholeProgramOptimization": "true", # /GL, whole program optimization, needed for LTCG
|
||||
"OmitFramePointers": "true",
|
||||
"EnableFunctionLevelLinking": "true",
|
||||
"EnableIntrinsicFunctions": "true",
|
||||
"AdditionalOptions": [
|
||||
"/MP", # compile across multiple CPUs
|
||||
],
|
||||
"DebugInformationFormat": "0"
|
||||
},
|
||||
"VCLibrarianTool": {
|
||||
"AdditionalOptions": [
|
||||
"/LTCG" # link time code generation
|
||||
],
|
||||
},
|
||||
"VCLinkerTool": {
|
||||
"LinkTimeCodeGeneration": 1, # link-time code generation
|
||||
"OptimizeReferences": 2, # /OPT:REF
|
||||
"EnableCOMDATFolding": 2, # /OPT:ICF
|
||||
"LinkIncremental": 1, # disable incremental linking
|
||||
"GenerateDebugInformation": "false"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Release_x64": {
|
||||
"msvs_configuration_platform": "x64",
|
||||
"defines": [ "NDEBUG"],
|
||||
"msvs_settings": {
|
||||
"VCCLCompilerTool": {
|
||||
"RuntimeLibrary": 0, # static release
|
||||
"Optimization": 3, # /Ox, full optimization
|
||||
"FavorSizeOrSpeed": 1, # /Ot, favour speed over size
|
||||
"InlineFunctionExpansion": 2, # /Ob2, inline anything eligible
|
||||
"WholeProgramOptimization": "true", # /GL, whole program optimization, needed for LTCG
|
||||
"OmitFramePointers": "true",
|
||||
"EnableFunctionLevelLinking": "true",
|
||||
"EnableIntrinsicFunctions": "true",
|
||||
"AdditionalOptions": [
|
||||
"/MP", # compile across multiple CPUs
|
||||
],
|
||||
"DebugInformationFormat": "0"
|
||||
},
|
||||
"VCLibrarianTool": {
|
||||
"AdditionalOptions": [
|
||||
"/LTCG" # link time code generation
|
||||
],
|
||||
},
|
||||
"VCLinkerTool": {
|
||||
"LinkTimeCodeGeneration": 1, # link-time code generation
|
||||
"OptimizeReferences": 2, # /OPT:REF
|
||||
"EnableCOMDATFolding": 2, # /OPT:ICF
|
||||
"LinkIncremental": 1, # disable incremental linking
|
||||
"GenerateDebugInformation": "false"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, {
|
||||
"target_defaults": {
|
||||
"default_configuration": "Release",
|
||||
"xcode_settings": {
|
||||
"CLANG_CXX_LIBRARY": "libc++",
|
||||
"CLANG_CXX_LANGUAGE_STANDARD":"c++11",
|
||||
"GCC_VERSION": "com.apple.compilers.llvm.clang.1_0",
|
||||
},
|
||||
"cflags_cc": ["-std=c++11"],
|
||||
"configurations": {
|
||||
"Debug": {
|
||||
"defines": [
|
||||
"DEBUG"
|
||||
],
|
||||
"xcode_settings": {
|
||||
"GCC_OPTIMIZATION_LEVEL": "0",
|
||||
"GCC_GENERATE_DEBUGGING_SYMBOLS": "YES",
|
||||
"OTHER_CPLUSPLUSFLAGS": [ "-Wall", "-Wextra", "-pedantic", "-g", "-O0" ]
|
||||
}
|
||||
},
|
||||
"Release": {
|
||||
"defines": [
|
||||
"NDEBUG"
|
||||
],
|
||||
"xcode_settings": {
|
||||
"GCC_OPTIMIZATION_LEVEL": "3",
|
||||
"GCC_GENERATE_DEBUGGING_SYMBOLS": "NO",
|
||||
"DEAD_CODE_STRIPPING": "YES",
|
||||
"GCC_INLINES_ARE_PRIVATE_EXTERN": "YES",
|
||||
"OTHER_CPLUSPLUSFLAGS": [ "-Wall", "-Wextra", "-pedantic", "-O3" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
]
|
||||
}
|
||||
|
69
third_party/variant/optional.hpp
vendored
69
third_party/variant/optional.hpp
vendored
@ -1,69 +0,0 @@
|
||||
#ifndef MAPBOX_UTIL_OPTIONAL_HPP
|
||||
#define MAPBOX_UTIL_OPTIONAL_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "variant.hpp"
|
||||
|
||||
namespace mapbox
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
|
||||
template <typename T> class optional
|
||||
{
|
||||
static_assert(!std::is_reference<T>::value, "optional doesn't support references");
|
||||
|
||||
struct none_type
|
||||
{
|
||||
};
|
||||
|
||||
variant<none_type, T> variant_;
|
||||
|
||||
public:
|
||||
optional() = default;
|
||||
|
||||
optional(optional const &rhs)
|
||||
{
|
||||
if (this != &rhs)
|
||||
{ // protect against invalid self-assignment
|
||||
variant_ = rhs.variant_;
|
||||
}
|
||||
}
|
||||
|
||||
optional(T const &v) { variant_ = v; }
|
||||
|
||||
explicit operator bool() const noexcept { return variant_.template is<T>(); }
|
||||
|
||||
T const &get() const { return variant_.template get<T>(); }
|
||||
T &get() { return variant_.template get<T>(); }
|
||||
|
||||
T const &operator*() const { return this->get(); }
|
||||
T operator*() { return this->get(); }
|
||||
|
||||
optional &operator=(T const &v)
|
||||
{
|
||||
variant_ = v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
optional &operator=(optional const &rhs)
|
||||
{
|
||||
if (this != &rhs)
|
||||
{
|
||||
variant_ = rhs.variant_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename... Args> void emplace(Args &&... args)
|
||||
{
|
||||
variant_ = T{std::forward<Args>(args)...};
|
||||
}
|
||||
|
||||
void reset() { variant_ = none_type{}; }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
127
third_party/variant/recursive_wrapper.hpp
vendored
127
third_party/variant/recursive_wrapper.hpp
vendored
@ -1,127 +0,0 @@
|
||||
#ifndef MAPBOX_UTIL_VARIANT_RECURSIVE_WRAPPER_HPP
|
||||
#define MAPBOX_UTIL_VARIANT_RECURSIVE_WRAPPER_HPP
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace mapbox { namespace util {
|
||||
|
||||
template <typename T>
|
||||
class recursive_wrapper
|
||||
{
|
||||
public:
|
||||
using type = T;
|
||||
private:
|
||||
|
||||
T* p_;
|
||||
|
||||
public:
|
||||
|
||||
~recursive_wrapper();
|
||||
recursive_wrapper();
|
||||
|
||||
recursive_wrapper(recursive_wrapper const& operand);
|
||||
recursive_wrapper(T const& operand);
|
||||
recursive_wrapper(recursive_wrapper&& operand);
|
||||
recursive_wrapper(T&& operand);
|
||||
|
||||
private:
|
||||
|
||||
void assign(const T& rhs);
|
||||
|
||||
public:
|
||||
|
||||
inline recursive_wrapper& operator=(recursive_wrapper const& rhs)
|
||||
{
|
||||
assign( rhs.get() );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline recursive_wrapper& operator=(T const& rhs)
|
||||
{
|
||||
assign( rhs );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void swap(recursive_wrapper& operand) noexcept
|
||||
{
|
||||
T* temp = operand.p_;
|
||||
operand.p_ = p_;
|
||||
p_ = temp;
|
||||
}
|
||||
|
||||
|
||||
recursive_wrapper& operator=(recursive_wrapper&& rhs) noexcept
|
||||
{
|
||||
swap(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
recursive_wrapper& operator=(T&& rhs)
|
||||
{
|
||||
get() = std::move(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
T& get() { return *get_pointer(); }
|
||||
const T& get() const { return *get_pointer(); }
|
||||
T* get_pointer() { return p_; }
|
||||
const T* get_pointer() const { return p_; }
|
||||
operator T const&() const { return this->get(); }
|
||||
operator T&() { return this->get(); }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
recursive_wrapper<T>::~recursive_wrapper()
|
||||
{
|
||||
delete p_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
recursive_wrapper<T>::recursive_wrapper()
|
||||
: p_(new T)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
recursive_wrapper<T>::recursive_wrapper(recursive_wrapper const& operand)
|
||||
: p_(new T( operand.get() ))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
recursive_wrapper<T>::recursive_wrapper(T const& operand)
|
||||
: p_(new T(operand))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
recursive_wrapper<T>::recursive_wrapper(recursive_wrapper&& operand)
|
||||
: p_(operand.p_)
|
||||
{
|
||||
operand.p_ = nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
recursive_wrapper<T>::recursive_wrapper(T&& operand)
|
||||
: p_(new T( std::move(operand) ))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void recursive_wrapper<T>::assign(const T& rhs)
|
||||
{
|
||||
this->get() = rhs;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void swap(recursive_wrapper<T>& lhs, recursive_wrapper<T>& rhs) noexcept
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPBOX_UTIL_VARIANT_RECURSIVE_WRAPPER_HPP
|
32
third_party/variant/scripts/build-appveyor.bat
vendored
32
third_party/variant/scripts/build-appveyor.bat
vendored
@ -1,32 +0,0 @@
|
||||
@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
|
7
third_party/variant/scripts/build-local.bat
vendored
7
third_party/variant/scripts/build-local.bat
vendored
@ -1,7 +0,0 @@
|
||||
@ECHO OFF
|
||||
SETLOCAL
|
||||
|
||||
SET platform=x64
|
||||
SET configuration=Release
|
||||
|
||||
CALL scripts\build-appveyor.bat
|
59
third_party/variant/scripts/linux.sh
vendored
59
third_party/variant/scripts/linux.sh
vendored
@ -1,59 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e -u
|
||||
set -o pipefail
|
||||
|
||||
# ppa for latest boost
|
||||
sudo add-apt-repository -y ppa:boost-latest/ppa
|
||||
# ppa for g++ 4.7 and 4.8
|
||||
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
sudo apt-get update -y
|
||||
|
||||
# install boost headers and g++ upgrades
|
||||
sudo apt-get -y -qq install boost1.55 gcc-4.8 g++-4.8 gcc-4.7 g++-4.7
|
||||
|
||||
if [[ "$CXX" == "clang++" ]]; then
|
||||
echo 'running tests against clang++'
|
||||
make test
|
||||
make bench
|
||||
make clean
|
||||
else
|
||||
# run tests against g++ 4.7
|
||||
export CXX="g++-4.7"; export CC="gcc-4.7"
|
||||
echo 'running tests against g++ 4.7'
|
||||
make test
|
||||
make bench
|
||||
make clean
|
||||
|
||||
# run tests against g++ 4.8
|
||||
export CXX="g++-4.8"; export CC="gcc-4.8"
|
||||
echo 'running tests against g++ 4.8'
|
||||
make test
|
||||
make bench
|
||||
make clean
|
||||
|
||||
fi
|
||||
|
||||
# compare object sizes against boost::variant
|
||||
echo 'comparing object sizes to boost::variant'
|
||||
make sizes /usr/include/boost/variant.hpp
|
||||
make clean
|
||||
|
||||
# test building with gyp
|
||||
echo 'testing build with gyp'
|
||||
make gyp
|
||||
|
||||
# run coverage when using clang++
|
||||
if [[ $CXX == "clang++" ]]; then
|
||||
make clean
|
||||
make coverage
|
||||
git status
|
||||
./out/cov-test
|
||||
cp unit*gc* test/
|
||||
sudo pip install cpp-coveralls
|
||||
coveralls -i variant.hpp -i recursive_wrapper.hpp --gcov-options '\-lp'
|
||||
fi
|
||||
|
||||
# set strictness back to normal
|
||||
# to avoid tripping up travis
|
||||
set +e +u
|
20
third_party/variant/scripts/osx.sh
vendored
20
third_party/variant/scripts/osx.sh
vendored
@ -1,20 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e -u
|
||||
set -o pipefail
|
||||
|
||||
# install boost headers
|
||||
brew unlink boost
|
||||
brew install boost
|
||||
|
||||
# run tests
|
||||
make test
|
||||
make bench
|
||||
make clean
|
||||
|
||||
# compare object sizes against boost::variant
|
||||
make sizes `brew --prefix`/include/boost/variant.hpp
|
||||
make clean
|
||||
|
||||
# test building with gyp
|
||||
make gyp
|
181
third_party/variant/test/bench_variant.cpp
vendored
181
third_party/variant/test/bench_variant.cpp
vendored
@ -1,181 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/timer/timer.hpp>
|
||||
#include "variant.hpp"
|
||||
|
||||
#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;
|
||||
|
||||
namespace test {
|
||||
|
||||
template <typename V>
|
||||
struct Holder
|
||||
{
|
||||
typedef V value_type;
|
||||
std::vector<value_type> data;
|
||||
|
||||
template <typename T>
|
||||
void append_move(T && obj)
|
||||
{
|
||||
data.emplace_back(std::forward<T>(obj));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void append(T const& obj)
|
||||
{
|
||||
data.push_back(obj);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
|
||||
struct print : util::static_visitor<>
|
||||
{
|
||||
template <typename T>
|
||||
void operator() (T const& val) const
|
||||
{
|
||||
std::cerr << val << ":" << typeid(T).name() << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename V>
|
||||
struct dummy : boost::static_visitor<>
|
||||
{
|
||||
dummy(V & v)
|
||||
: v_(v) {}
|
||||
|
||||
template <typename T>
|
||||
void operator() (T && val) const
|
||||
{
|
||||
v_ = std::move(val);
|
||||
}
|
||||
V & v_;
|
||||
};
|
||||
|
||||
template <typename V>
|
||||
struct dummy2 : util::static_visitor<>
|
||||
{
|
||||
dummy2(V & v)
|
||||
: v_(v) {}
|
||||
|
||||
template <typename T>
|
||||
void operator() (T && val) const
|
||||
{
|
||||
v_ = std::move(val);
|
||||
}
|
||||
V & v_;
|
||||
};
|
||||
|
||||
void run_boost_test(std::size_t runs)
|
||||
{
|
||||
test::Holder<boost::variant<int, double, std::string>> h;
|
||||
h.data.reserve(runs);
|
||||
for (std::size_t i=0; i< runs; ++i)
|
||||
{
|
||||
h.append_move(std::string(TEXT_SHORT));
|
||||
h.append_move(std::string(TEXT_LONG));
|
||||
h.append_move(123);
|
||||
h.append_move(3.14159);
|
||||
}
|
||||
|
||||
boost::variant<int, double, std::string> v;
|
||||
for (auto const& v2 : h.data)
|
||||
{
|
||||
dummy<boost::variant<int, double, std::string>> d(v);
|
||||
boost::apply_visitor(d, v2);
|
||||
}
|
||||
}
|
||||
|
||||
void run_variant_test(std::size_t runs)
|
||||
{
|
||||
test::Holder<util::variant<int, double, std::string>> h;
|
||||
h.data.reserve(runs);
|
||||
for (std::size_t i=0; i< runs; ++i)
|
||||
{
|
||||
h.append_move(std::string(TEXT_SHORT));
|
||||
h.append_move(std::string(TEXT_LONG));
|
||||
h.append_move(123);
|
||||
h.append_move(3.14159);
|
||||
}
|
||||
|
||||
util::variant<int, double, std::string> v;
|
||||
for (auto const& v2 : h.data)
|
||||
{
|
||||
dummy2<util::variant<int, double, std::string>> d(v);
|
||||
util::apply_visitor (d, v2);
|
||||
}
|
||||
}
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
if (argc!=2)
|
||||
{
|
||||
std::cerr << "Usage:" << argv[0] << " <num-runs>" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef SINGLE_THREADED
|
||||
const std::size_t THREADS = 4;
|
||||
#endif
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#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));
|
||||
}
|
||||
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
|
||||
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
136
third_party/variant/test/binary_visitor_test.cpp
vendored
136
third_party/variant/test/binary_visitor_test.cpp
vendored
@ -1,136 +0,0 @@
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/timer/timer.hpp>
|
||||
#include "variant.hpp"
|
||||
#include "variant_io.hpp"
|
||||
|
||||
using namespace mapbox;
|
||||
|
||||
namespace test {
|
||||
|
||||
template <typename T>
|
||||
struct string_to_number {};
|
||||
|
||||
template <>
|
||||
struct string_to_number<double>
|
||||
{
|
||||
double operator() (std::string const& str) const
|
||||
{
|
||||
return std::stod(str);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct string_to_number<std::int64_t>
|
||||
{
|
||||
std::int64_t operator() (std::string const& str) const
|
||||
{
|
||||
return std::stoll(str);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct string_to_number<std::uint64_t>
|
||||
{
|
||||
std::uint64_t operator() (std::string const& str) const
|
||||
{
|
||||
return std::stoull(str);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct string_to_number<bool>
|
||||
{
|
||||
bool operator() (std::string const& str) const
|
||||
{
|
||||
bool result;
|
||||
std::istringstream(str) >> std::boolalpha >> result;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
struct javascript_equal_visitor : util::static_visitor<bool>
|
||||
{
|
||||
template <typename T>
|
||||
bool operator() (T lhs, T rhs) const
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
|
||||
template <typename T, class = typename std::enable_if<std::is_arithmetic<T>::value>::type>
|
||||
bool operator() (T lhs, std::string const& rhs) const
|
||||
{
|
||||
return lhs == string_to_number<T>()(rhs);
|
||||
}
|
||||
|
||||
template <typename T, class = typename std::enable_if<std::is_arithmetic<T>::value>::type>
|
||||
bool operator() (std::string const& lhs, T rhs) const
|
||||
{
|
||||
return string_to_number<T>()(lhs) == rhs;
|
||||
}
|
||||
|
||||
template <typename T0, typename T1>
|
||||
bool operator() (T0 lhs, T1 rhs) const
|
||||
{
|
||||
return lhs == static_cast<T0>(rhs);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct javascript_equal
|
||||
{
|
||||
javascript_equal(T const& lhs)
|
||||
: lhs_(lhs) {}
|
||||
|
||||
bool operator() (T const& rhs) const
|
||||
{
|
||||
return util::apply_visitor(test::javascript_equal_visitor(), lhs_, rhs);
|
||||
}
|
||||
T const& lhs_;
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
|
||||
int main (/*int argc, char** argv*/)
|
||||
{
|
||||
typedef util::variant<bool, std::int64_t, std::uint64_t, double, std::string> variant_type;
|
||||
variant_type v0(3.14159);
|
||||
variant_type v1(std::string("3.14159"));
|
||||
variant_type v2(std::uint64_t(1));
|
||||
|
||||
std::cerr << v0 << " == " << v1 << " -> "
|
||||
<< std::boolalpha << util::apply_visitor(test::javascript_equal_visitor(), v0, v1) << std::endl;
|
||||
|
||||
|
||||
std::vector<variant_type> vec;
|
||||
|
||||
vec.emplace_back(std::string("1"));
|
||||
vec.push_back(variant_type(std::uint64_t(2)));
|
||||
vec.push_back(variant_type(std::uint64_t(3)));
|
||||
vec.push_back(std::string("3.14159"));
|
||||
vec.emplace_back(3.14159);
|
||||
|
||||
//auto itr = std::find_if(vec.begin(), vec.end(), [&v0](variant_type const& val) {
|
||||
// return util::apply_visitor(test::javascript_equal_visitor(), v0, val);
|
||||
// });
|
||||
|
||||
auto itr = std::find_if(vec.begin(), vec.end(), test::javascript_equal<variant_type>(v2));
|
||||
|
||||
if (itr != std::end(vec))
|
||||
{
|
||||
std::cout << "found " << *itr << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "can't find " << v2 << '\n';
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
#include <boost/variant.hpp>
|
||||
#include <cstdint>
|
||||
#include <stdexcept>
|
||||
|
||||
struct check : boost::static_visitor<>
|
||||
{
|
||||
template <typename T>
|
||||
void operator() (T const& val) const
|
||||
{
|
||||
if (val != 0) throw std::runtime_error("invalid");
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
typedef boost::variant<bool, int, double> variant_type;
|
||||
variant_type v(0);
|
||||
boost::apply_visitor(check(), v);
|
||||
return 0;
|
||||
}
|
8683
third_party/variant/test/catch.hpp
vendored
8683
third_party/variant/test/catch.hpp
vendored
File diff suppressed because it is too large
Load Diff
82
third_party/variant/test/optional_unit.cpp
vendored
82
third_party/variant/test/optional_unit.cpp
vendored
@ -1,82 +0,0 @@
|
||||
#define CATCH_CONFIG_RUNNER
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "optional.hpp"
|
||||
|
||||
using namespace mapbox;
|
||||
|
||||
struct dummy {
|
||||
dummy(int _m_1, int _m_2) : m_1(_m_1), m_2(_m_2) {}
|
||||
int m_1;
|
||||
int m_2;
|
||||
|
||||
};
|
||||
|
||||
int main (int argc, char* const argv[])
|
||||
{
|
||||
int result = Catch::Session().run(argc, argv);
|
||||
if (!result) printf("\x1b[1;32m ✓ \x1b[0m\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
TEST_CASE( "optional can be instantiated with a POD type", "[optiona]" ) {
|
||||
mapbox::util::optional<double> dbl_opt;
|
||||
|
||||
REQUIRE(!dbl_opt);
|
||||
dbl_opt = 3.1415;
|
||||
REQUIRE(dbl_opt);
|
||||
|
||||
REQUIRE(dbl_opt.get() == 3.1415);
|
||||
REQUIRE(*dbl_opt == 3.1415);
|
||||
}
|
||||
|
||||
TEST_CASE( "copy c'tor", "[optiona]" ) {
|
||||
mapbox::util::optional<double> dbl_opt;
|
||||
|
||||
REQUIRE(!dbl_opt);
|
||||
dbl_opt = 3.1415;
|
||||
REQUIRE(dbl_opt);
|
||||
|
||||
mapbox::util::optional<double> other = dbl_opt;
|
||||
|
||||
REQUIRE(other.get() == 3.1415);
|
||||
REQUIRE(*other == 3.1415);
|
||||
}
|
||||
|
||||
TEST_CASE( "const operator*, const get()", "[optiona]" ) {
|
||||
mapbox::util::optional<double> dbl_opt = 3.1415;
|
||||
|
||||
REQUIRE(dbl_opt);
|
||||
|
||||
const double pi1 = dbl_opt.get();
|
||||
const double pi2 = *dbl_opt;
|
||||
|
||||
REQUIRE(pi1 == 3.1415);
|
||||
REQUIRE(pi2 == 3.1415);
|
||||
}
|
||||
|
||||
TEST_CASE( "emplace initialization, reset", "[optional]" ) {
|
||||
mapbox::util::optional<dummy> dummy_opt;
|
||||
REQUIRE(!dummy_opt);
|
||||
|
||||
// rvalues, baby!
|
||||
dummy_opt.emplace(1, 2);
|
||||
REQUIRE(dummy_opt);
|
||||
REQUIRE(dummy_opt.get().m_1 == 1);
|
||||
REQUIRE((*dummy_opt).m_2 == 2);
|
||||
|
||||
dummy_opt.reset();
|
||||
REQUIRE(!dummy_opt);
|
||||
}
|
||||
|
||||
TEST_CASE( "assignment", "[optional]") {
|
||||
mapbox::util::optional<int> a;
|
||||
mapbox::util::optional<int> b;
|
||||
|
||||
a = 1; b = 3;
|
||||
REQUIRE(a.get() == 1);
|
||||
REQUIRE(b.get() == 3);
|
||||
b = a;
|
||||
REQUIRE(a.get() == b.get());
|
||||
REQUIRE(b.get() == 1);
|
||||
}
|
132
third_party/variant/test/recursive_wrapper_test.cpp
vendored
132
third_party/variant/test/recursive_wrapper_test.cpp
vendored
@ -1,132 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <boost/timer/timer.hpp>
|
||||
#include "variant.hpp"
|
||||
|
||||
using namespace mapbox;
|
||||
|
||||
namespace test {
|
||||
|
||||
struct add;
|
||||
struct sub;
|
||||
template <typename OpTag> struct binary_op;
|
||||
|
||||
typedef util::variant<int ,
|
||||
util::recursive_wrapper<binary_op<add>>,
|
||||
util::recursive_wrapper<binary_op<sub>>
|
||||
> expression;
|
||||
|
||||
template <typename Op>
|
||||
struct binary_op
|
||||
{
|
||||
expression left; // variant instantiated here...
|
||||
expression right;
|
||||
|
||||
binary_op(expression && lhs, expression && rhs)
|
||||
: left(std::move(lhs)), right(std::move(rhs))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct print : util::static_visitor<void>
|
||||
{
|
||||
template <typename T>
|
||||
void operator() (T const& val) const
|
||||
{
|
||||
std::cerr << val << ":" << typeid(T).name() << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct test : util::static_visitor<std::string>
|
||||
{
|
||||
template <typename T>
|
||||
std::string operator() (T const& obj) const
|
||||
{
|
||||
return std::string("TYPE_ID=") + typeid(obj).name();
|
||||
}
|
||||
};
|
||||
|
||||
struct calculator : public util::static_visitor<int>
|
||||
{
|
||||
public:
|
||||
|
||||
int operator()(int value) const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
int operator()(binary_op<add> const& binary) const
|
||||
{
|
||||
return util::apply_visitor(calculator(), binary.left)
|
||||
+ util::apply_visitor(calculator(), binary.right);
|
||||
}
|
||||
|
||||
int operator()(binary_op<sub> const& binary) const
|
||||
{
|
||||
return util::apply_visitor(calculator(), binary.left)
|
||||
- util::apply_visitor(calculator(), binary.right);
|
||||
}
|
||||
};
|
||||
|
||||
struct to_string : public util::static_visitor<std::string>
|
||||
{
|
||||
public:
|
||||
|
||||
std::string operator()(int value) const
|
||||
{
|
||||
return std::to_string(value);
|
||||
}
|
||||
|
||||
std::string operator()(binary_op<add> const& binary) const
|
||||
{
|
||||
return util::apply_visitor(to_string(), binary.left) + std::string("+")
|
||||
+ util::apply_visitor(to_string(), binary.right);
|
||||
}
|
||||
|
||||
std::string operator()(binary_op<sub> const& binary) const
|
||||
{
|
||||
return util::apply_visitor(to_string(), binary.left) + std::string("-")
|
||||
+ util::apply_visitor(to_string(), binary.right);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
std::cerr << "Usage" << argv[0] << " <num-iter>" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
const std::size_t NUM_ITER = static_cast<std::size_t>(std::stol(argv[1]));
|
||||
|
||||
test::expression result(
|
||||
test::binary_op<test::sub>(
|
||||
test::binary_op<test::add>(2, 3), 4));
|
||||
|
||||
std::cerr << "TYPE OF RESULT-> " << util::apply_visitor(test::test(), result) << std::endl;
|
||||
|
||||
{
|
||||
boost::timer::auto_cpu_timer t;
|
||||
int total = 0;
|
||||
for (std::size_t i = 0; i < NUM_ITER; ++i)
|
||||
{
|
||||
total += util::apply_visitor(test::calculator(), result);
|
||||
}
|
||||
std::cerr << "total=" << total << std::endl;
|
||||
}
|
||||
|
||||
std::cerr << util::apply_visitor(test::to_string(), result) << "=" << util::apply_visitor(test::calculator(), result) << std::endl;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <boost/timer/timer.hpp>
|
||||
#include "variant.hpp"
|
||||
|
||||
using namespace mapbox;
|
||||
|
||||
namespace test {
|
||||
|
||||
struct point
|
||||
{
|
||||
public:
|
||||
point (double x_, double y_)
|
||||
: x(x_), y(y_) {}
|
||||
double x;
|
||||
double y;
|
||||
};
|
||||
|
||||
struct line_string : std::vector<point> {};
|
||||
struct polygon : std::vector<line_string> {};
|
||||
using variant = util::variant<std::reference_wrapper<const point>,
|
||||
std::reference_wrapper<const line_string>,
|
||||
std::reference_wrapper<const polygon>>;
|
||||
|
||||
struct print
|
||||
{
|
||||
using result_type = void;
|
||||
void operator() (point const& pt) const
|
||||
{
|
||||
std::cerr << "Point(" << pt.x << "," << pt.y << ")" << std::endl;
|
||||
}
|
||||
void operator() (line_string const& line) const
|
||||
{
|
||||
std::cerr << "Line(";
|
||||
for (auto const& pt : line)
|
||||
{
|
||||
std::cerr << pt.x << " " << pt.y << ",";
|
||||
}
|
||||
std::cerr << ")" << std::endl;
|
||||
}
|
||||
template <typename T>
|
||||
void operator() (T const& val) const
|
||||
{
|
||||
std::cerr << typeid(T).name() << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
std::cerr << sizeof(test::polygon) << std::endl;
|
||||
std::cerr << sizeof(test::variant) << std::endl;
|
||||
test::point pt(123,456);
|
||||
test::variant var = std::move(std::cref(pt));
|
||||
util::apply_visitor(test::print(), var);
|
||||
test::line_string line;
|
||||
line.push_back(pt);
|
||||
line.push_back(pt);
|
||||
line.push_back(test::point(999,333));
|
||||
var = std::move(std::cref(line));
|
||||
util::apply_visitor(test::print(), var);
|
||||
std::cerr << "Is line (cref) ? " << var.is<std::reference_wrapper<test::line_string const>>() << std::endl;
|
||||
auto const& line2 = var.get<test::line_string>(); // accessing underlying type of std::reference_wrapper<T>
|
||||
test::print printer;
|
||||
printer(line2);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
128
third_party/variant/test/unique_ptr_test.cpp
vendored
128
third_party/variant/test/unique_ptr_test.cpp
vendored
@ -1,128 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
#include <boost/variant.hpp>
|
||||
#include <boost/timer/timer.hpp>
|
||||
#include "variant.hpp"
|
||||
|
||||
using namespace mapbox;
|
||||
|
||||
namespace test {
|
||||
|
||||
struct add;
|
||||
struct sub;
|
||||
template <typename OpTag> struct binary_op;
|
||||
|
||||
typedef util::variant<int ,
|
||||
std::unique_ptr<binary_op<add>>,
|
||||
std::unique_ptr<binary_op<sub>>
|
||||
> expression;
|
||||
|
||||
template <typename Op>
|
||||
struct binary_op
|
||||
{
|
||||
expression left; // variant instantiated here...
|
||||
expression right;
|
||||
|
||||
binary_op(expression && lhs, expression && rhs)
|
||||
: left(std::move(lhs)), right(std::move(rhs)) {}
|
||||
};
|
||||
|
||||
struct print : util::static_visitor<void>
|
||||
{
|
||||
template <typename T>
|
||||
void operator() (T const& val) const
|
||||
{
|
||||
std::cerr << val << ":" << typeid(T).name() << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct test : util::static_visitor<std::string>
|
||||
{
|
||||
template <typename T>
|
||||
std::string operator() (T const& obj) const
|
||||
{
|
||||
return std::string("TYPE_ID=") + typeid(obj).name();
|
||||
}
|
||||
};
|
||||
|
||||
struct calculator : public util::static_visitor<int>
|
||||
{
|
||||
public:
|
||||
|
||||
int operator()(int value) const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
int operator()(std::unique_ptr<binary_op<add>> const& binary) const
|
||||
{
|
||||
return util::apply_visitor(calculator(), binary->left)
|
||||
+ util::apply_visitor(calculator(), binary->right);
|
||||
}
|
||||
|
||||
int operator()(std::unique_ptr<binary_op<sub>> const& binary) const
|
||||
{
|
||||
return util::apply_visitor(calculator(), binary->left)
|
||||
- util::apply_visitor(calculator(), binary->right);
|
||||
}
|
||||
};
|
||||
|
||||
struct to_string : public util::static_visitor<std::string>
|
||||
{
|
||||
public:
|
||||
|
||||
std::string operator()(int value) const
|
||||
{
|
||||
return std::to_string(value);
|
||||
}
|
||||
|
||||
std::string operator()(std::unique_ptr<binary_op<add>> const& binary) const
|
||||
{
|
||||
return util::apply_visitor(to_string(), binary->left) + std::string("+")
|
||||
+ util::apply_visitor(to_string(), binary->right);
|
||||
}
|
||||
|
||||
std::string operator()(std::unique_ptr<binary_op<sub>> const& binary) const
|
||||
{
|
||||
return util::apply_visitor(to_string(), binary->left) + std::string("-")
|
||||
+ util::apply_visitor(to_string(), binary->right);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace test
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
std::cerr << "Usage" << argv[0] << " <num-iter>" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
const std::size_t NUM_ITER = static_cast<std::size_t>(std::stol(argv[1]));
|
||||
|
||||
test::expression sum(std::unique_ptr<test::binary_op<test::add>>(new test::binary_op<test::add>(2, 3)));
|
||||
test::expression result(std::unique_ptr<test::binary_op<test::sub>>(new test::binary_op<test::sub>(std::move(sum), 4)));
|
||||
std::cerr << "TYPE OF RESULT-> " << util::apply_visitor(test::test(), result) << std::endl;
|
||||
|
||||
{
|
||||
boost::timer::auto_cpu_timer t;
|
||||
int total = 0;
|
||||
for (std::size_t i = 0; i < NUM_ITER; ++i)
|
||||
{
|
||||
total += util::apply_visitor(test::calculator(), result);
|
||||
}
|
||||
std::cerr << "total=" << total << std::endl;
|
||||
}
|
||||
|
||||
std::cerr << util::apply_visitor(test::to_string(), result) << "=" << util::apply_visitor(test::calculator(), result) << std::endl;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
314
third_party/variant/test/unit.cpp
vendored
314
third_party/variant/test/unit.cpp
vendored
@ -1,314 +0,0 @@
|
||||
#define CATCH_CONFIG_RUNNER
|
||||
#include "catch.hpp"
|
||||
|
||||
#include "variant.hpp"
|
||||
#include "variant_io.hpp"
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
using namespace mapbox;
|
||||
|
||||
template <typename T>
|
||||
struct mutating_visitor
|
||||
{
|
||||
mutating_visitor(T & val)
|
||||
: val_(val) {}
|
||||
|
||||
void operator() (T & val) const
|
||||
{
|
||||
val = val_;
|
||||
}
|
||||
|
||||
template <typename T1>
|
||||
void operator() (T1& ) const {} // no-op
|
||||
|
||||
T & val_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
TEST_CASE( "variant version", "[variant]" ) {
|
||||
unsigned int version = VARIANT_VERSION;
|
||||
REQUIRE(version == 100);
|
||||
#if VARIANT_VERSION == 100
|
||||
REQUIRE(true);
|
||||
#else
|
||||
REQUIRE(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE( "variant can be moved into vector", "[variant]" ) {
|
||||
typedef util::variant<bool,std::string> variant_type;
|
||||
variant_type v(std::string("test"));
|
||||
std::vector<variant_type> vec;
|
||||
vec.emplace_back(std::move(v));
|
||||
REQUIRE(v.get<std::string>() != std::string("test"));
|
||||
REQUIRE(vec.at(0).get<std::string>() == std::string("test"));
|
||||
}
|
||||
|
||||
TEST_CASE( "variant should support built-in types", "[variant]" ) {
|
||||
SECTION( "bool" ) {
|
||||
util::variant<bool> v(true);
|
||||
REQUIRE(v.valid());
|
||||
REQUIRE(v.is<bool>());
|
||||
REQUIRE(v.get_type_index() == 0);
|
||||
REQUIRE(v.get<bool>() == true);
|
||||
v.set<bool>(false);
|
||||
REQUIRE(v.get<bool>() == false);
|
||||
v = true;
|
||||
REQUIRE(v == util::variant<bool>(true));
|
||||
}
|
||||
SECTION( "nullptr" ) {
|
||||
typedef std::nullptr_t value_type;
|
||||
util::variant<value_type> v(nullptr);
|
||||
REQUIRE(v.valid());
|
||||
REQUIRE(v.is<value_type>());
|
||||
REQUIRE(v.get_type_index() == 0);
|
||||
// TODO: commented since it breaks on windows: 'operator << is ambiguous'
|
||||
//REQUIRE(v.get<value_type>() == nullptr);
|
||||
// FIXME: does not compile: ./variant.hpp:340:14: error: use of overloaded operator '<<' is ambiguous (with operand types 'std::__1::basic_ostream<char>' and 'const nullptr_t')
|
||||
// https://github.com/mapbox/variant/issues/14
|
||||
//REQUIRE(v == util::variant<value_type>(nullptr));
|
||||
}
|
||||
SECTION( "unique_ptr" ) {
|
||||
typedef std::unique_ptr<std::string> value_type;
|
||||
util::variant<value_type> v(value_type(new std::string("hello")));
|
||||
REQUIRE(v.valid());
|
||||
REQUIRE(v.is<value_type>());
|
||||
REQUIRE(v.get_type_index() == 0);
|
||||
REQUIRE(*v.get<value_type>().get() == *value_type(new std::string("hello")).get());
|
||||
}
|
||||
SECTION( "string" ) {
|
||||
typedef std::string value_type;
|
||||
util::variant<value_type> v(value_type("hello"));
|
||||
REQUIRE(v.valid());
|
||||
REQUIRE(v.is<value_type>());
|
||||
REQUIRE(v.get_type_index() == 0);
|
||||
REQUIRE(v.get<value_type>() == value_type("hello"));
|
||||
v.set<value_type>(value_type("there"));
|
||||
REQUIRE(v.get<value_type>() == value_type("there"));
|
||||
v = value_type("variant");
|
||||
REQUIRE(v == util::variant<value_type>(value_type("variant")));
|
||||
}
|
||||
SECTION( "size_t" ) {
|
||||
typedef std::size_t value_type;
|
||||
util::variant<value_type> v(std::numeric_limits<value_type>::max());
|
||||
REQUIRE(v.valid());
|
||||
REQUIRE(v.is<value_type>());
|
||||
REQUIRE(v.get_type_index() == 0);
|
||||
REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
|
||||
v.set<value_type>(value_type(0));
|
||||
REQUIRE(v.get<value_type>() == value_type(0));
|
||||
v = value_type(1);
|
||||
REQUIRE(v == util::variant<value_type>(value_type(1)));
|
||||
}
|
||||
SECTION( "int8_t" ) {
|
||||
typedef std::int8_t value_type;
|
||||
util::variant<value_type> v(std::numeric_limits<value_type>::max());
|
||||
REQUIRE(v.valid());
|
||||
REQUIRE(v.is<value_type>());
|
||||
REQUIRE(v.get_type_index() == 0);
|
||||
REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
|
||||
v.set<value_type>(0);
|
||||
REQUIRE(v.get<value_type>() == value_type(0));
|
||||
v = value_type(1);
|
||||
REQUIRE(v == util::variant<value_type>(value_type(1)));
|
||||
}
|
||||
SECTION( "int16_t" ) {
|
||||
typedef std::int16_t value_type;
|
||||
util::variant<value_type> v(std::numeric_limits<value_type>::max());
|
||||
REQUIRE(v.valid());
|
||||
REQUIRE(v.is<value_type>());
|
||||
REQUIRE(v.get_type_index() == 0);
|
||||
REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
|
||||
v.set<value_type>(0);
|
||||
REQUIRE(v.get<value_type>() == value_type(0));
|
||||
v = value_type(1);
|
||||
REQUIRE(v == util::variant<value_type>(value_type(1)));
|
||||
}
|
||||
SECTION( "int32_t" ) {
|
||||
typedef std::int32_t value_type;
|
||||
util::variant<value_type> v(std::numeric_limits<value_type>::max());
|
||||
REQUIRE(v.valid());
|
||||
REQUIRE(v.is<value_type>());
|
||||
REQUIRE(v.get_type_index() == 0);
|
||||
REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
|
||||
v.set<value_type>(0);
|
||||
REQUIRE(v.get<value_type>() == value_type(0));
|
||||
v = value_type(1);
|
||||
REQUIRE(v == util::variant<value_type>(value_type(1)));
|
||||
}
|
||||
SECTION( "int64_t" ) {
|
||||
typedef std::int64_t value_type;
|
||||
util::variant<value_type> v(std::numeric_limits<value_type>::max());
|
||||
REQUIRE(v.valid());
|
||||
REQUIRE(v.is<value_type>());
|
||||
REQUIRE(v.get_type_index() == 0);
|
||||
REQUIRE(v.get<value_type>() == std::numeric_limits<value_type>::max());
|
||||
v.set<value_type>(0);
|
||||
REQUIRE(v.get<value_type>() == value_type(0));
|
||||
v = value_type(1);
|
||||
REQUIRE(v == util::variant<value_type>(value_type(1)));
|
||||
}
|
||||
}
|
||||
|
||||
struct MissionInteger
|
||||
{
|
||||
typedef uint64_t value_type;
|
||||
value_type val_;
|
||||
public:
|
||||
MissionInteger(uint64_t val) :
|
||||
val_(val) {}
|
||||
|
||||
bool operator==(MissionInteger const& rhs) const
|
||||
{
|
||||
return (val_ == rhs.get());
|
||||
}
|
||||
|
||||
uint64_t get() const
|
||||
{
|
||||
return val_;
|
||||
}
|
||||
};
|
||||
|
||||
// TODO - remove after https://github.com/mapbox/variant/issues/14
|
||||
std::ostream& operator<<(std::ostream& os, MissionInteger const& rhs)
|
||||
{
|
||||
os << rhs.get();
|
||||
return os;
|
||||
}
|
||||
|
||||
TEST_CASE( "variant should support custom types", "[variant]" ) {
|
||||
// http://www.missionintegers.com/integer/34838300
|
||||
util::variant<MissionInteger> v(MissionInteger(34838300));
|
||||
REQUIRE(v.valid());
|
||||
REQUIRE(v.is<MissionInteger>());
|
||||
REQUIRE(v.get_type_index() == 0);
|
||||
REQUIRE(v.get<MissionInteger>() == MissionInteger(34838300));
|
||||
REQUIRE(v.get<MissionInteger>().get() == MissionInteger::value_type(34838300));
|
||||
// TODO: should both of the set usages below compile?
|
||||
v.set<MissionInteger>(MissionInteger::value_type(0));
|
||||
v.set<MissionInteger>(MissionInteger(0));
|
||||
REQUIRE(v.get<MissionInteger>().get() == MissionInteger::value_type(0));
|
||||
v = MissionInteger(1);
|
||||
REQUIRE(v == util::variant<MissionInteger>(MissionInteger(1)));
|
||||
}
|
||||
|
||||
// Test internal api
|
||||
TEST_CASE( "variant should correctly index types", "[variant]" ) {
|
||||
typedef util::variant<bool,std::string,std::uint64_t,std::int64_t,double,float> variant_type;
|
||||
// Index is in reverse order
|
||||
REQUIRE(variant_type(true).get_type_index() == 5);
|
||||
REQUIRE(variant_type(std::string("test")).get_type_index() == 4);
|
||||
REQUIRE(variant_type(std::uint64_t(0)).get_type_index() == 3);
|
||||
REQUIRE(variant_type(std::int64_t(0)).get_type_index() == 2);
|
||||
REQUIRE(variant_type(double(0.0)).get_type_index() == 1);
|
||||
REQUIRE(variant_type(float(0.0)).get_type_index() == 0);
|
||||
}
|
||||
|
||||
// Test internal api
|
||||
TEST_CASE( "variant::which() returns zero based index of stored type", "[variant]" ) {
|
||||
typedef util::variant<bool,std::string,std::uint64_t,std::int64_t,double,float> variant_type;
|
||||
// Index is in reverse order
|
||||
REQUIRE(variant_type(true).which() == 0);
|
||||
REQUIRE(variant_type(std::string("test")).which() == 1);
|
||||
REQUIRE(variant_type(std::uint64_t(0)).which() == 2);
|
||||
REQUIRE(variant_type(std::int64_t(0)).which() == 3);
|
||||
REQUIRE(variant_type(double(0.0)).which() == 4);
|
||||
REQUIRE(variant_type(float(0.0)).which() == 5);
|
||||
}
|
||||
|
||||
TEST_CASE( "get with type not in variant type list should throw", "[variant]" ) {
|
||||
typedef util::variant<int> variant_type;
|
||||
variant_type var = 5;
|
||||
REQUIRE(var.get<int>() == 5);
|
||||
}
|
||||
|
||||
TEST_CASE( "get with wrong type (here: double) should throw", "[variant]" ) {
|
||||
typedef util::variant<int, double> variant_type;
|
||||
variant_type var = 5;
|
||||
REQUIRE(var.get<int>() == 5);
|
||||
REQUIRE_THROWS(var.get<double>());
|
||||
}
|
||||
|
||||
TEST_CASE( "get with wrong type (here: int) should throw", "[variant]" ) {
|
||||
typedef util::variant<int, double> variant_type;
|
||||
variant_type var = 5.0;
|
||||
REQUIRE(var.get<double>() == 5.0);
|
||||
REQUIRE_THROWS(var.get<int>());
|
||||
}
|
||||
|
||||
TEST_CASE( "implicit conversion", "[variant][implicit conversion]" ) {
|
||||
typedef util::variant<int> variant_type;
|
||||
variant_type var(5.0); // converted to int
|
||||
REQUIRE(var.get<int>() == 5);
|
||||
var = 6.0; // works for operator=, too
|
||||
REQUIRE(var.get<int>() == 6);
|
||||
}
|
||||
|
||||
TEST_CASE( "implicit conversion to first type in variant type list", "[variant][implicit conversion]" ) {
|
||||
typedef util::variant<long, char> variant_type;
|
||||
variant_type var = 5.0; // converted to long
|
||||
REQUIRE(var.get<long>() == 5);
|
||||
REQUIRE_THROWS(var.get<char>());
|
||||
}
|
||||
|
||||
TEST_CASE( "implicit conversion to unsigned char", "[variant][implicit conversion]" ) {
|
||||
typedef util::variant<unsigned char> variant_type;
|
||||
variant_type var = 100.0;
|
||||
CHECK(var.get<unsigned char>() == static_cast<unsigned char>(100.0));
|
||||
CHECK(var.get<unsigned char>() == static_cast<unsigned char>(static_cast<unsigned int>(100.0)));
|
||||
}
|
||||
|
||||
struct dummy {};
|
||||
|
||||
TEST_CASE( "variant value traits", "[variant::detail]" ) {
|
||||
// Users should not create variants with duplicated types
|
||||
// however our type indexing should still work
|
||||
// Index is in reverse order
|
||||
REQUIRE((util::detail::value_traits<bool, bool, int, double, std::string>::index == 3));
|
||||
REQUIRE((util::detail::value_traits<int, bool, int, double, std::string>::index == 2));
|
||||
REQUIRE((util::detail::value_traits<double, bool, int, double, std::string>::index == 1));
|
||||
REQUIRE((util::detail::value_traits<std::string, bool, int, double, std::string>::index == 0));
|
||||
REQUIRE((util::detail::value_traits<dummy, bool, int, double, std::string>::index == util::detail::invalid_value));
|
||||
REQUIRE((util::detail::value_traits<std::vector<int>, bool, int, double, std::string>::index == util::detail::invalid_value));
|
||||
}
|
||||
|
||||
TEST_CASE( "variant default constructor", "[variant][default constructor]" ) {
|
||||
// By default variant is initialised with (default constructed) first type in template parameters pack
|
||||
// As a result first type in Types... must be default constructable
|
||||
// NOTE: index in reverse order -> index = N - 1
|
||||
REQUIRE((util::variant<int, double, std::string>().get_type_index() == 2));
|
||||
REQUIRE((util::variant<int, double, std::string>(util::no_init()).get_type_index() == util::detail::invalid_value));
|
||||
}
|
||||
|
||||
TEST_CASE( "variant visitation", "[visitor][unary visitor]" ) {
|
||||
util::variant<int, double, std::string> var(123);
|
||||
REQUIRE(var.get<int>() == 123);
|
||||
int val = 456;
|
||||
mutating_visitor<int> visitor(val);
|
||||
util::apply_visitor(visitor, var);
|
||||
REQUIRE(var.get<int>() == 456);
|
||||
}
|
||||
|
||||
TEST_CASE( "variant printer", "[visitor][unary visitor][printer]" ) {
|
||||
typedef util::variant<int, double, std::string> variant_type;
|
||||
std::vector<variant_type> var = {2.1, 123, "foo", 456};
|
||||
std::stringstream out;
|
||||
std::copy(var.begin(), var.end(), std::ostream_iterator<variant_type>(out, ","));
|
||||
out << var[2];
|
||||
REQUIRE(out.str() == "2.1,123,foo,456,foo");
|
||||
}
|
||||
|
||||
int main (int argc, char* const argv[])
|
||||
{
|
||||
int result = Catch::Session().run(argc, argv);
|
||||
if (!result) printf("\x1b[1;32m ✓ \x1b[0m\n");
|
||||
return result;
|
||||
}
|
22
third_party/variant/test/variant_hello_world.cpp
vendored
22
third_party/variant/test/variant_hello_world.cpp
vendored
@ -1,22 +0,0 @@
|
||||
#include "variant.hpp"
|
||||
#include <cstdint>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace mapbox;
|
||||
|
||||
struct check : util::static_visitor<>
|
||||
{
|
||||
template <typename T>
|
||||
void operator() (T const& val) const
|
||||
{
|
||||
if (val != 0) throw std::runtime_error("invalid");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int main() {
|
||||
typedef util::variant<bool, int, double> variant_type;
|
||||
variant_type v(0);
|
||||
util::apply_visitor(check(), v);
|
||||
return 0;
|
||||
}
|
21
third_party/variant/variant.gyp
vendored
21
third_party/variant/variant.gyp
vendored
@ -1,21 +0,0 @@
|
||||
{
|
||||
"includes": [
|
||||
"common.gypi"
|
||||
],
|
||||
"targets": [
|
||||
{
|
||||
"target_name": "tests",
|
||||
"type": "executable",
|
||||
"sources": [
|
||||
"test/unit.cpp"
|
||||
],
|
||||
"xcode_settings": {
|
||||
"SDKROOT": "macosx",
|
||||
"SUPPORTED_PLATFORMS":["macosx"]
|
||||
},
|
||||
"include_dirs": [
|
||||
"./"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
886
third_party/variant/variant.hpp
vendored
886
third_party/variant/variant.hpp
vendored
@ -1,886 +0,0 @@
|
||||
#ifndef MAPBOX_UTIL_VARIANT_HPP
|
||||
#define MAPBOX_UTIL_VARIANT_HPP
|
||||
|
||||
#include <utility>
|
||||
#include <typeinfo>
|
||||
#include <type_traits>
|
||||
#include <stdexcept> // runtime_error
|
||||
#include <new> // operator new
|
||||
#include <cstddef> // size_t
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
#include "recursive_wrapper.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx
|
||||
#ifdef NDEBUG
|
||||
#define VARIANT_INLINE __forceinline
|
||||
#else
|
||||
#define VARIANT_INLINE __declspec(noinline)
|
||||
#endif
|
||||
#else
|
||||
#ifdef NDEBUG
|
||||
#define VARIANT_INLINE inline __attribute__((always_inline))
|
||||
#else
|
||||
#define VARIANT_INLINE __attribute__((noinline))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define VARIANT_MAJOR_VERSION 0
|
||||
#define VARIANT_MINOR_VERSION 1
|
||||
#define VARIANT_PATCH_VERSION 0
|
||||
|
||||
// translates to 100
|
||||
#define VARIANT_VERSION (VARIANT_MAJOR_VERSION*100000) + (VARIANT_MINOR_VERSION*100) + (VARIANT_PATCH_VERSION)
|
||||
|
||||
namespace mapbox { namespace util {
|
||||
|
||||
// static visitor
|
||||
template <typename R = void>
|
||||
struct static_visitor
|
||||
{
|
||||
using result_type = R;
|
||||
protected:
|
||||
static_visitor() {}
|
||||
~static_visitor() {}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
static constexpr std::size_t invalid_value = std::size_t(-1);
|
||||
|
||||
template <typename T, typename...Types>
|
||||
struct direct_type;
|
||||
|
||||
template <typename T, typename First, typename...Types>
|
||||
struct direct_type<T, First, Types...>
|
||||
{
|
||||
static constexpr std::size_t index = std::is_same<T, First>::value
|
||||
? sizeof...(Types) : direct_type<T, Types...>::index;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct direct_type<T>
|
||||
{
|
||||
static constexpr std::size_t index = invalid_value;
|
||||
};
|
||||
|
||||
template <typename T, typename...Types>
|
||||
struct convertible_type;
|
||||
|
||||
template <typename T, typename First, typename...Types>
|
||||
struct convertible_type<T, First, Types...>
|
||||
{
|
||||
static constexpr std::size_t index = std::is_convertible<T, First>::value
|
||||
? sizeof...(Types) : convertible_type<T, Types...>::index;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct convertible_type<T>
|
||||
{
|
||||
static constexpr std::size_t index = invalid_value;
|
||||
};
|
||||
|
||||
template <typename T, typename...Types>
|
||||
struct value_traits
|
||||
{
|
||||
static constexpr std::size_t direct_index = direct_type<T, Types...>::index;
|
||||
static constexpr std::size_t 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>
|
||||
struct is_valid_type;
|
||||
|
||||
template <typename T, typename First, typename... Types>
|
||||
struct is_valid_type<T, First, Types...>
|
||||
{
|
||||
static constexpr bool value = std::is_convertible<T, First>::value
|
||||
|| is_valid_type<T, Types...>::value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_valid_type<T> : std::false_type {};
|
||||
|
||||
template <std::size_t N, typename ... Types>
|
||||
struct select_type
|
||||
{
|
||||
static_assert(N < sizeof...(Types), "index out of bounds");
|
||||
};
|
||||
|
||||
template <std::size_t N, typename T, typename ... Types>
|
||||
struct select_type<N, T, Types...>
|
||||
{
|
||||
using type = typename select_type<N - 1, Types...>::type;
|
||||
};
|
||||
|
||||
template <typename T, typename ... Types>
|
||||
struct select_type<0, T, Types...>
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
|
||||
template <typename T, typename R = void>
|
||||
struct enable_if_type { using type = R; };
|
||||
|
||||
template <typename F, typename V, typename Enable = void>
|
||||
struct result_of_unary_visit
|
||||
{
|
||||
using type = typename std::result_of<F(V&)>::type;
|
||||
};
|
||||
|
||||
template <typename F, typename V>
|
||||
struct result_of_unary_visit<F, V, typename enable_if_type<typename F::result_type>::type >
|
||||
{
|
||||
using type = typename F::result_type;
|
||||
};
|
||||
|
||||
template <typename F, typename V, class Enable = void>
|
||||
struct result_of_binary_visit
|
||||
{
|
||||
using type = typename std::result_of<F(V&,V&)>::type;
|
||||
};
|
||||
|
||||
|
||||
template <typename F, typename V>
|
||||
struct result_of_binary_visit<F, V, typename enable_if_type<typename F::result_type>::type >
|
||||
{
|
||||
using type = typename F::result_type;
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
template <std::size_t arg1, std::size_t ... others>
|
||||
struct static_max;
|
||||
|
||||
template <std::size_t arg>
|
||||
struct static_max<arg>
|
||||
{
|
||||
static const std::size_t value = arg;
|
||||
};
|
||||
|
||||
template <std::size_t arg1, std::size_t arg2, std::size_t ... others>
|
||||
struct static_max<arg1, arg2, others...>
|
||||
{
|
||||
static const std::size_t value = arg1 >= arg2 ? static_max<arg1, others...>::value :
|
||||
static_max<arg2, others...>::value;
|
||||
};
|
||||
|
||||
template<typename... Types>
|
||||
struct variant_helper;
|
||||
|
||||
template<typename T, typename... Types>
|
||||
struct variant_helper<T, Types...>
|
||||
{
|
||||
VARIANT_INLINE static void destroy(const std::size_t id, void * data)
|
||||
{
|
||||
if (id == sizeof...(Types))
|
||||
{
|
||||
reinterpret_cast<T*>(data)->~T();
|
||||
}
|
||||
else
|
||||
{
|
||||
variant_helper<Types...>::destroy(id, data);
|
||||
}
|
||||
}
|
||||
|
||||
VARIANT_INLINE static void move(const std::size_t old_id, void * old_value, void * new_value)
|
||||
{
|
||||
if (old_id == sizeof...(Types))
|
||||
{
|
||||
new (new_value) T(std::move(*reinterpret_cast<T*>(old_value)));
|
||||
//std::memcpy(new_value, old_value, sizeof(T));
|
||||
// ^^ DANGER: this should only be considered for relocatable types e.g built-in types
|
||||
// Also, I don't see any measurable performance benefit just yet
|
||||
}
|
||||
else
|
||||
{
|
||||
variant_helper<Types...>::move(old_id, old_value, new_value);
|
||||
}
|
||||
}
|
||||
|
||||
VARIANT_INLINE static void copy(const std::size_t old_id, const void * old_value, void * new_value)
|
||||
{
|
||||
if (old_id == sizeof...(Types))
|
||||
{
|
||||
new (new_value) T(*reinterpret_cast<const T*>(old_value));
|
||||
}
|
||||
else
|
||||
{
|
||||
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<>
|
||||
{
|
||||
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 {
|
||||
|
||||
template <typename T>
|
||||
struct unwrapper
|
||||
{
|
||||
T const& operator() (T const& obj) const
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
|
||||
T& operator() (T & obj) const
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct unwrapper<recursive_wrapper<T>>
|
||||
{
|
||||
auto operator() (recursive_wrapper<T> const& obj) const
|
||||
-> typename recursive_wrapper<T>::type const&
|
||||
{
|
||||
return obj.get();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct unwrapper<std::reference_wrapper<T>>
|
||||
{
|
||||
auto operator() (std::reference_wrapper<T> const& obj) const
|
||||
-> typename std::reference_wrapper<T>::type const&
|
||||
{
|
||||
return obj.get();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <typename F, typename V, typename R, typename...Types>
|
||||
struct dispatcher;
|
||||
|
||||
template <typename F, typename V, typename R, typename T, typename...Types>
|
||||
struct dispatcher<F, V, R, T, Types...>
|
||||
{
|
||||
using result_type = R;
|
||||
VARIANT_INLINE static result_type apply_const(V const& v, F f)
|
||||
{
|
||||
if (v.get_type_index() == sizeof...(Types))
|
||||
{
|
||||
return f(unwrapper<T>()(v. template get<T>()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return dispatcher<F, V, R, Types...>::apply_const(v, f);
|
||||
}
|
||||
}
|
||||
|
||||
VARIANT_INLINE static result_type apply(V & v, F f)
|
||||
{
|
||||
if (v.get_type_index() == sizeof...(Types))
|
||||
{
|
||||
return f(unwrapper<T>()(v. template get<T>()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return dispatcher<F, V, R, Types...>::apply(v, f);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename F, typename V, typename R>
|
||||
struct dispatcher<F, V, R>
|
||||
{
|
||||
using result_type = R;
|
||||
VARIANT_INLINE static result_type apply_const(V const&, F)
|
||||
{
|
||||
throw std::runtime_error(std::string("unary dispatch: FAIL ") + typeid(V).name());
|
||||
}
|
||||
|
||||
VARIANT_INLINE static result_type apply(V &, F)
|
||||
{
|
||||
throw std::runtime_error(std::string("unary dispatch: FAIL ") + typeid(V).name());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename F, typename V, typename R, typename T, typename...Types>
|
||||
struct binary_dispatcher_rhs;
|
||||
|
||||
template <typename F, typename V, typename R, typename T0, typename T1, typename...Types>
|
||||
struct binary_dispatcher_rhs<F, V, R, T0, T1, Types...>
|
||||
{
|
||||
using result_type = R;
|
||||
VARIANT_INLINE static result_type apply_const(V const& lhs, V const& rhs, F f)
|
||||
{
|
||||
if (rhs.get_type_index() == sizeof...(Types)) // call binary functor
|
||||
{
|
||||
return f(unwrapper<T0>()(lhs. template get<T0>()),
|
||||
unwrapper<T1>()(rhs. template get<T1>()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return binary_dispatcher_rhs<F, V, R, T0, Types...>::apply_const(lhs, rhs, f);
|
||||
}
|
||||
}
|
||||
|
||||
VARIANT_INLINE static result_type apply(V & lhs, V & rhs, F f)
|
||||
{
|
||||
if (rhs.get_type_index() == sizeof...(Types)) // call binary functor
|
||||
{
|
||||
return f(unwrapper<T0>()(lhs. template get<T0>()),
|
||||
unwrapper<T1>()(rhs. template get<T1>()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return binary_dispatcher_rhs<F, V, R, T0, Types...>::apply(lhs, rhs, f);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename F, typename V, typename R, typename T>
|
||||
struct binary_dispatcher_rhs<F, V, R, T>
|
||||
{
|
||||
using result_type = R;
|
||||
VARIANT_INLINE static result_type apply_const(V const&, V const&, F)
|
||||
{
|
||||
throw std::runtime_error("binary dispatch: FAIL");
|
||||
}
|
||||
VARIANT_INLINE static result_type apply(V &, V &, F)
|
||||
{
|
||||
throw std::runtime_error("binary dispatch: FAIL");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename F, typename V, typename R, typename T, typename...Types>
|
||||
struct binary_dispatcher_lhs;
|
||||
|
||||
template <typename F, typename V, typename R, typename T0, typename T1, typename...Types>
|
||||
struct binary_dispatcher_lhs<F, V, R, T0, T1, Types...>
|
||||
{
|
||||
using result_type = R;
|
||||
VARIANT_INLINE static result_type apply_const(V const& lhs, V const& rhs, F f)
|
||||
{
|
||||
if (lhs.get_type_index() == sizeof...(Types)) // call binary functor
|
||||
{
|
||||
return f(lhs. template get<T1>(), rhs. template get<T0>());
|
||||
}
|
||||
else
|
||||
{
|
||||
return binary_dispatcher_lhs<F, V, R, T0, Types...>::apply_const(lhs, rhs, f);
|
||||
}
|
||||
}
|
||||
|
||||
VARIANT_INLINE static result_type apply(V & lhs, V & rhs, F f)
|
||||
{
|
||||
if (lhs.get_type_index() == sizeof...(Types)) // call binary functor
|
||||
{
|
||||
return f(lhs. template get<T1>(), rhs. template get<T0>());
|
||||
}
|
||||
else
|
||||
{
|
||||
return binary_dispatcher_lhs<F, V, R, T0, Types...>::apply(lhs, rhs, f);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename F, typename V, typename R, typename T>
|
||||
struct binary_dispatcher_lhs<F, V, R, T>
|
||||
{
|
||||
using result_type = R;
|
||||
VARIANT_INLINE static result_type apply_const(V const&, V const&, F)
|
||||
{
|
||||
throw std::runtime_error("binary dispatch: FAIL");
|
||||
}
|
||||
|
||||
VARIANT_INLINE static result_type apply(V &, V &, F)
|
||||
{
|
||||
throw std::runtime_error("binary dispatch: FAIL");
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F, typename V, typename R, typename...Types>
|
||||
struct binary_dispatcher;
|
||||
|
||||
template <typename F, typename V, typename R, typename T, typename...Types>
|
||||
struct binary_dispatcher<F, V, R, T, Types...>
|
||||
{
|
||||
using result_type = R;
|
||||
VARIANT_INLINE static result_type apply_const(V const& v0, V const& v1, F f)
|
||||
{
|
||||
if (v0.get_type_index() == sizeof...(Types))
|
||||
{
|
||||
if (v0.get_type_index() == v1.get_type_index())
|
||||
{
|
||||
return f(v0. template get<T>(), v1. template get<T>()); // call binary functor
|
||||
}
|
||||
else
|
||||
{
|
||||
return binary_dispatcher_rhs<F, V, R, T, Types...>::apply_const(v0, v1, f);
|
||||
}
|
||||
}
|
||||
else if (v1.get_type_index() == sizeof...(Types))
|
||||
{
|
||||
return binary_dispatcher_lhs<F, V, R, T, Types...>::apply_const(v0, v1, f);
|
||||
}
|
||||
return binary_dispatcher<F, V, R, Types...>::apply_const(v0, v1, f);
|
||||
}
|
||||
|
||||
VARIANT_INLINE static result_type apply(V & v0, V & v1, F f)
|
||||
{
|
||||
if (v0.get_type_index() == sizeof...(Types))
|
||||
{
|
||||
if (v0.get_type_index() == v1.get_type_index())
|
||||
{
|
||||
return f(v0. template get<T>(), v1. template get<T>()); // call binary functor
|
||||
}
|
||||
else
|
||||
{
|
||||
return binary_dispatcher_rhs<F, V, R, T, Types...>::apply(v0, v1, f);
|
||||
}
|
||||
}
|
||||
else if (v1.get_type_index() == sizeof...(Types))
|
||||
{
|
||||
return binary_dispatcher_lhs<F, V, R, T, Types...>::apply(v0, v1, f);
|
||||
}
|
||||
return binary_dispatcher<F, V, R, Types...>::apply(v0, v1, f);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename F, typename V, typename R>
|
||||
struct binary_dispatcher<F, V, R>
|
||||
{
|
||||
using result_type = R;
|
||||
VARIANT_INLINE static result_type apply_const(V const&, V const&, F)
|
||||
{
|
||||
throw std::runtime_error("binary dispatch: FAIL");
|
||||
}
|
||||
|
||||
VARIANT_INLINE static result_type apply(V &, V &, F)
|
||||
{
|
||||
throw std::runtime_error("binary dispatch: FAIL");
|
||||
}
|
||||
};
|
||||
|
||||
// comparator functors
|
||||
struct equal_comp
|
||||
{
|
||||
template <typename T>
|
||||
bool operator()(T const& lhs, T const& rhs) const
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
};
|
||||
|
||||
struct less_comp
|
||||
{
|
||||
template <typename T>
|
||||
bool operator()(T const& lhs, T const& rhs) const
|
||||
{
|
||||
return lhs < rhs;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Variant, typename Comp>
|
||||
class comparer
|
||||
{
|
||||
public:
|
||||
explicit comparer(Variant const& lhs) noexcept
|
||||
: lhs_(lhs) {}
|
||||
comparer& operator=(comparer const&) = delete;
|
||||
// visitor
|
||||
template<typename T>
|
||||
bool operator()(T const& rhs_content) const
|
||||
{
|
||||
T const& lhs_content = lhs_.template get<T>();
|
||||
return Comp()(lhs_content, rhs_content);
|
||||
}
|
||||
private:
|
||||
Variant const& lhs_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
struct no_init {};
|
||||
|
||||
template<typename... Types>
|
||||
class variant
|
||||
{
|
||||
private:
|
||||
|
||||
static const std::size_t data_size = static_max<sizeof(Types)...>::value;
|
||||
static const std::size_t data_align = static_max<alignof(Types)...>::value;
|
||||
|
||||
using data_type = typename std::aligned_storage<data_size, data_align>::type;
|
||||
using helper_type = variant_helper<Types...>;
|
||||
|
||||
std::size_t type_index;
|
||||
data_type data;
|
||||
|
||||
public:
|
||||
|
||||
VARIANT_INLINE variant()
|
||||
: type_index(sizeof...(Types) - 1)
|
||||
{
|
||||
new (&data) typename detail::select_type<0, Types...>::type();
|
||||
}
|
||||
|
||||
VARIANT_INLINE variant(no_init)
|
||||
: type_index(detail::invalid_value) {}
|
||||
|
||||
// http://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers
|
||||
template <typename T, class = typename std::enable_if<
|
||||
detail::is_valid_type<typename std::remove_reference<T>::type, Types...>::value>::type>
|
||||
VARIANT_INLINE variant(T && val) noexcept
|
||||
: type_index(detail::value_traits<typename std::remove_reference<T>::type, Types...>::index)
|
||||
{
|
||||
constexpr std::size_t index = sizeof...(Types) - detail::value_traits<typename std::remove_reference<T>::type, Types...>::index - 1;
|
||||
using target_type = typename detail::select_type<index, Types...>::type;
|
||||
new (&data) target_type(std::forward<T>(val)); // nothrow
|
||||
}
|
||||
|
||||
VARIANT_INLINE variant(variant<Types...> const& old)
|
||||
: type_index(old.type_index)
|
||||
{
|
||||
helper_type::copy(old.type_index, &old.data, &data);
|
||||
}
|
||||
|
||||
VARIANT_INLINE variant(variant<Types...>&& old) noexcept
|
||||
: type_index(old.type_index)
|
||||
{
|
||||
helper_type::move(old.type_index, &old.data, &data);
|
||||
}
|
||||
|
||||
private:
|
||||
VARIANT_INLINE void copy_assign(variant<Types...> const& rhs)
|
||||
{
|
||||
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 void move_assign(variant<Types...> && rhs)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
// conversions
|
||||
// move-assign
|
||||
template <typename T>
|
||||
VARIANT_INLINE variant<Types...>& operator=(T && rhs) noexcept
|
||||
{
|
||||
variant<Types...> temp(std::forward<T>(rhs));
|
||||
move_assign(std::move(temp));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// copy-assign
|
||||
template <typename T>
|
||||
VARIANT_INLINE variant<Types...>& operator=(T const& rhs)
|
||||
{
|
||||
variant<Types...> temp(rhs);
|
||||
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);
|
||||
}
|
||||
|
||||
VARIANT_INLINE bool valid() const
|
||||
{
|
||||
return (type_index != detail::invalid_value);
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
VARIANT_INLINE void set(Args&&... args)
|
||||
{
|
||||
helper_type::destroy(type_index, &data);
|
||||
new (&data) T(std::forward<Args>(args)...);
|
||||
type_index = detail::direct_type<T, Types...>::index;
|
||||
}
|
||||
|
||||
// get<T>()
|
||||
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)
|
||||
{
|
||||
return *reinterpret_cast<T*>(&data);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("in get<T>()");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<
|
||||
(detail::direct_type<T, Types...>::index != detail::invalid_value)
|
||||
>::type* = nullptr>
|
||||
VARIANT_INLINE T const& get() const
|
||||
{
|
||||
if (type_index == detail::direct_type<T, Types...>::index)
|
||||
{
|
||||
return *reinterpret_cast<T const*>(&data);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("in get<T>()");
|
||||
}
|
||||
}
|
||||
|
||||
// get<T>() - T stored as recursive_wrapper<T>
|
||||
template <typename T, typename std::enable_if<
|
||||
(detail::direct_type<recursive_wrapper<T>, Types...>::index != detail::invalid_value)
|
||||
>::type* = nullptr>
|
||||
VARIANT_INLINE T& get()
|
||||
{
|
||||
if (type_index == detail::direct_type<recursive_wrapper<T>, Types...>::index)
|
||||
{
|
||||
return (*reinterpret_cast<recursive_wrapper<T>*>(&data)).get();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("in get<T>()");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T,typename std::enable_if<
|
||||
(detail::direct_type<recursive_wrapper<T>, Types...>::index != detail::invalid_value)
|
||||
>::type* = nullptr>
|
||||
VARIANT_INLINE T const& get() const
|
||||
{
|
||||
if (type_index == detail::direct_type<recursive_wrapper<T>, Types...>::index)
|
||||
{
|
||||
return (*reinterpret_cast<recursive_wrapper<T> const*>(&data)).get();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("in get<T>()");
|
||||
}
|
||||
}
|
||||
|
||||
// get<T>() - T stored as std::reference_wrapper<T>
|
||||
template <typename T, typename std::enable_if<
|
||||
(detail::direct_type<std::reference_wrapper<T>, Types...>::index != detail::invalid_value)
|
||||
>::type* = nullptr>
|
||||
VARIANT_INLINE T& get()
|
||||
{
|
||||
if (type_index == detail::direct_type<std::reference_wrapper<T>, Types...>::index)
|
||||
{
|
||||
return (*reinterpret_cast<std::reference_wrapper<T>*>(&data)).get();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("in get<T>()");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T,typename std::enable_if<
|
||||
(detail::direct_type<std::reference_wrapper<T const>, Types...>::index != detail::invalid_value)
|
||||
>::type* = nullptr>
|
||||
VARIANT_INLINE T const& get() const
|
||||
{
|
||||
if (type_index == detail::direct_type<std::reference_wrapper<T const>, Types...>::index)
|
||||
{
|
||||
return (*reinterpret_cast<std::reference_wrapper<T const> const*>(&data)).get();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("in get<T>()");
|
||||
}
|
||||
}
|
||||
|
||||
VARIANT_INLINE std::size_t get_type_index() const
|
||||
{
|
||||
return type_index;
|
||||
}
|
||||
|
||||
VARIANT_INLINE int which() const noexcept
|
||||
{
|
||||
return static_cast<int>(sizeof...(Types) - type_index - 1);
|
||||
}
|
||||
|
||||
// visitor
|
||||
// unary
|
||||
template <typename F, typename V>
|
||||
auto VARIANT_INLINE
|
||||
static visit(V const& v, F f)
|
||||
-> decltype(detail::dispatcher<F, V,
|
||||
typename detail::result_of_unary_visit<F,
|
||||
typename detail::select_type<0, Types...>::type>::type, Types...>::apply_const(v, f))
|
||||
{
|
||||
using R = typename detail::result_of_unary_visit<F, typename detail::select_type<0, Types...>::type>::type;
|
||||
return detail::dispatcher<F, V, R, Types...>::apply_const(v, f);
|
||||
}
|
||||
// non-const
|
||||
template <typename F, typename V>
|
||||
auto VARIANT_INLINE
|
||||
static visit(V & v, F f)
|
||||
-> decltype(detail::dispatcher<F, V,
|
||||
typename detail::result_of_unary_visit<F,
|
||||
typename detail::select_type<0, Types...>::type>::type, Types...>::apply(v, f))
|
||||
{
|
||||
using R = typename detail::result_of_unary_visit<F, typename detail::select_type<0, Types...>::type>::type;
|
||||
return detail::dispatcher<F, V, R, Types...>::apply(v, f);
|
||||
}
|
||||
|
||||
// binary
|
||||
// const
|
||||
template <typename F, typename V>
|
||||
auto VARIANT_INLINE
|
||||
static binary_visit(V const& v0, V const& v1, F f)
|
||||
-> decltype(detail::binary_dispatcher<F, V,
|
||||
typename detail::result_of_binary_visit<F,
|
||||
typename detail::select_type<0, Types...>::type>::type, Types...>::apply_const(v0, v1, f))
|
||||
{
|
||||
using R = typename detail::result_of_binary_visit<F,typename detail::select_type<0, Types...>::type>::type;
|
||||
return detail::binary_dispatcher<F, V, R, Types...>::apply_const(v0, v1, f);
|
||||
}
|
||||
// non-const
|
||||
template <typename F, typename V>
|
||||
auto VARIANT_INLINE
|
||||
static binary_visit(V& v0, V& v1, F f)
|
||||
-> decltype(detail::binary_dispatcher<F, V,
|
||||
typename detail::result_of_binary_visit<F,
|
||||
typename detail::select_type<0, Types...>::type>::type, Types...>::apply(v0, v1, f))
|
||||
{
|
||||
using R = typename detail::result_of_binary_visit<F,typename detail::select_type<0, Types...>::type>::type;
|
||||
return detail::binary_dispatcher<F, V, R, Types...>::apply(v0, v1, f);
|
||||
}
|
||||
|
||||
~variant() noexcept
|
||||
{
|
||||
helper_type::destroy(type_index, &data);
|
||||
}
|
||||
|
||||
// comparison operators
|
||||
// equality
|
||||
VARIANT_INLINE bool operator==(variant const& rhs) const
|
||||
{
|
||||
if (this->get_type_index() != rhs.get_type_index())
|
||||
return false;
|
||||
detail::comparer<variant, detail::equal_comp> visitor(*this);
|
||||
return visit(rhs, visitor);
|
||||
}
|
||||
// less than
|
||||
VARIANT_INLINE bool operator<(variant const& rhs) const
|
||||
{
|
||||
if (this->get_type_index() != rhs.get_type_index())
|
||||
{
|
||||
return this->get_type_index() < rhs.get_type_index();
|
||||
// ^^ borrowed from boost::variant
|
||||
}
|
||||
detail::comparer<variant, detail::less_comp> visitor(*this);
|
||||
return visit(rhs, visitor);
|
||||
}
|
||||
};
|
||||
|
||||
// unary visitor interface
|
||||
|
||||
// const
|
||||
template <typename V, typename F>
|
||||
auto VARIANT_INLINE static apply_visitor(F f, V const& v) -> decltype(V::visit(v, f))
|
||||
{
|
||||
return V::visit(v, f);
|
||||
}
|
||||
// non-const
|
||||
template <typename V, typename F>
|
||||
auto VARIANT_INLINE static apply_visitor(F f, V & v) -> decltype(V::visit(v, f))
|
||||
{
|
||||
return V::visit(v, f);
|
||||
}
|
||||
|
||||
// binary visitor interface
|
||||
// const
|
||||
template <typename V, typename F>
|
||||
auto VARIANT_INLINE static apply_visitor(F f, V const& v0, V const& v1) -> decltype(V::binary_visit(v0, v1, f))
|
||||
{
|
||||
return V::binary_visit(v0, v1, f);
|
||||
}
|
||||
// non-const
|
||||
template <typename V, typename F>
|
||||
auto VARIANT_INLINE static apply_visitor(F f, V & v0, V & v1) -> decltype(V::binary_visit(v0, v1, f))
|
||||
{
|
||||
return V::binary_visit(v0, v1, f);
|
||||
}
|
||||
|
||||
// getter interface
|
||||
template<typename ResultType, typename T>
|
||||
ResultType & get(T & var)
|
||||
{
|
||||
return var.template get<ResultType>();
|
||||
}
|
||||
|
||||
template<typename ResultType, typename T>
|
||||
ResultType const& get(T const& var)
|
||||
{
|
||||
return var.template get<ResultType>();
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPBOX_UTIL_VARIANT_HPP
|
39
third_party/variant/variant_io.hpp
vendored
39
third_party/variant/variant_io.hpp
vendored
@ -1,39 +0,0 @@
|
||||
#ifndef MAPBOX_UTIL_VARIANT_IO_HPP
|
||||
#define MAPBOX_UTIL_VARIANT_IO_HPP
|
||||
|
||||
namespace mapbox { namespace util {
|
||||
|
||||
namespace detail {
|
||||
// operator<< helper
|
||||
template <typename Out>
|
||||
class printer
|
||||
{
|
||||
public:
|
||||
explicit printer(Out & out)
|
||||
: out_(out) {}
|
||||
printer& operator=(printer const&) = delete;
|
||||
|
||||
// visitor
|
||||
template <typename T>
|
||||
void operator()(T const& operand) const
|
||||
{
|
||||
out_ << operand;
|
||||
}
|
||||
private:
|
||||
Out & out_;
|
||||
};
|
||||
}
|
||||
|
||||
// operator<<
|
||||
template <typename charT, typename traits, typename... Types>
|
||||
VARIANT_INLINE std::basic_ostream<charT, traits>&
|
||||
operator<< (std::basic_ostream<charT, traits>& out, variant<Types...> const& rhs)
|
||||
{
|
||||
detail::printer<std::basic_ostream<charT, traits>> visitor(out);
|
||||
apply_visitor(visitor, rhs);
|
||||
return out;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif //MAPBOX_UTIL_VARIANT_IO_HPP
|
8
third_party/variant/vcbuild.bat
vendored
8
third_party/variant/vcbuild.bat
vendored
@ -1,8 +0,0 @@
|
||||
SET configuration=Debug
|
||||
IF NOT EXIST deps\gyp\ git clone --depth 1 https://chromium.googlesource.com/external/gyp.git deps/gyp
|
||||
IF EXIST %configuration% rd /s /q %configuration%
|
||||
del variant.sln
|
||||
del tests.vcxproj
|
||||
C:\Python27\python.exe deps/gyp/gyp_main.py variant.gyp --depth=. -f msvs -G msvs_version=2013
|
||||
msbuild variant.sln /nologo /p:Configuration=%configuration%;Platform=Win32
|
||||
.\"%configuration%"\tests.exe
|
Loading…
Reference in New Issue
Block a user