Use std::variant instead of mapbox::util::variant (#6903)

This commit is contained in:
Siarhei Fedartsou 2024-05-28 18:52:49 +02:00 committed by GitHub
parent 01b1673c8a
commit c1ed73126d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
117 changed files with 472 additions and 17601 deletions

View File

@ -274,15 +274,6 @@ jobs:
CXXCOMPILER: g++-12
CXXFLAGS: '-Wno-array-bounds -Wno-uninitialized'
- name: gcc-11-release
continue-on-error: false
node: 20
runs-on: ubuntu-22.04
BUILD_TOOLS: ON
BUILD_TYPE: Release
CCOMPILER: gcc-11
CXXCOMPILER: g++-11
- name: conan-linux-release-node
build_node_package: true
continue-on-error: false

View File

@ -22,6 +22,7 @@
- NodeJS:
- CHANGED: Use node-api instead of NAN. [#6452](https://github.com/Project-OSRM/osrm-backend/pull/6452)
- Misc:
- CHANGED: Use std::variant instead of mapbox::util::variant. [#6903](https://github.com/Project-OSRM/osrm-backend/pull/6903)
- CHANGED: Bump rapidjson to version f9d53419e912910fd8fa57d5705fa41425428c35 [#6906](https://github.com/Project-OSRM/osrm-backend/pull/6906)
- CHANGED: Bump mapbox/variant to version 1.2.0 [#6898](https://github.com/Project-OSRM/osrm-backend/pull/6898)
- CHANGED: Avoid copy of std::function-based callback in path unpacking [#6895](https://github.com/Project-OSRM/osrm-backend/pull/6895)

View File

@ -121,7 +121,6 @@ endif()
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/include/)
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/include/)
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/sol2-3.3.0/include)
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/variant/include)
set(BOOST_COMPONENTS date_time chrono filesystem iostreams program_options regex system thread unit_test_framework)
@ -607,7 +606,6 @@ if (BUILD_ROUTED)
set_property(TARGET osrm-routed PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
endif()
file(GLOB VariantGlob third_party/variant/include/mapbox/*.hpp)
file(GLOB FlatbuffersGlob third_party/flatbuffers/include/flatbuffers/*.h)
file(GLOB LibraryGlob include/osrm/*.hpp)
file(GLOB ParametersGlob include/engine/api/*_parameters.hpp)
@ -627,7 +625,6 @@ install(FILES ${ContractorHeader} DESTINATION include/osrm/contractor)
install(FILES ${LibraryGlob} DESTINATION include/osrm)
install(FILES ${ParametersGlob} DESTINATION include/osrm/engine/api)
install(FILES ${ApiHeader} DESTINATION include/osrm/engine/api)
install(FILES ${VariantGlob} DESTINATION include/mapbox)
install(FILES ${FlatbuffersGlob} DESTINATION include/flatbuffers)
install(TARGETS osrm-extract DESTINATION bin)
install(TARGETS osrm-partition DESTINATION bin)

View File

@ -57,15 +57,15 @@ int main(int argc, const char *argv[])
// Execute routing request, this does the heavy lifting
const auto status = osrm.Route(params, result);
auto &json_result = result.get<json::Object>();
auto &json_result = std::get<json::Object>(result);
if (status == Status::Ok)
{
auto &routes = json_result.values["routes"].get<json::Array>();
auto &routes = std::get<json::Array>(json_result.values["routes"]);
// Let's just use the first route
auto &route = routes.values.at(0).get<json::Object>();
const auto distance = route.values["distance"].get<json::Number>().value;
const auto duration = route.values["duration"].get<json::Number>().value;
auto &route = std::get<json::Object>(routes.values.at(0));
const auto distance = std::get<json::Number>(route.values["distance"]).value;
const auto duration = std::get<json::Number>(route.values["duration"]).value;
// Warn users if extract does not contain the default coordinates from above
if (distance == 0 || duration == 0)
@ -80,8 +80,8 @@ int main(int argc, const char *argv[])
}
else if (status == Status::Error)
{
const auto code = json_result.values["code"].get<json::String>().value;
const auto message = json_result.values["message"].get<json::String>().value;
const auto code = std::get<json::String>(json_result.values["code"]).value;
const auto message = std::get<json::String>(json_result.values["message"]).value;
std::cout << "Code: " << code << "\n";
std::cout << "Message: " << code << "\n";

View File

@ -2,7 +2,7 @@
#define ENGINE_API_BASE_RESULT_HPP
#include <flatbuffers/flatbuffers.h>
#include <mapbox/variant.hpp>
#include <variant>
#include <string>
@ -10,8 +10,7 @@
namespace osrm::engine::api
{
using ResultT =
mapbox::util::variant<util::json::Object, std::string, flatbuffers::FlatBufferBuilder>;
using ResultT = std::variant<util::json::Object, std::string, flatbuffers::FlatBufferBuilder>;
} // namespace osrm::engine::api
#endif

View File

@ -41,7 +41,7 @@ inline bool hasValidLanes(const guidance::IntermediateIntersection &intersection
return intersection.lanes.lanes_in_turn > 0;
}
util::json::Array coordinateToLonLat(const util::Coordinate &coordinate);
util::json::Value coordinateToLonLat(const util::Coordinate &coordinate);
/**
* Ensures that a bearing value is a whole number, and clamped to the range 0-359
@ -79,7 +79,7 @@ util::json::Object makeGeoJSONGeometry(ForwardIter begin, ForwardIter end)
coordinates.values.push_back(location);
coordinates.values.push_back(location);
}
geojson.values["coordinates"] = std::move(coordinates);
geojson.values["coordinates"] = util::json::Value{std::move(coordinates)};
return geojson;
}

View File

@ -30,14 +30,14 @@ class MatchAPI final : public RouteAPI
osrm::engine::api::ResultT &response) const
{
BOOST_ASSERT(sub_matchings.size() == sub_routes.size());
if (response.is<flatbuffers::FlatBufferBuilder>())
if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(response))
{
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
auto &fb_result = std::get<flatbuffers::FlatBufferBuilder>(response);
MakeResponse(sub_matchings, sub_routes, fb_result);
}
else
{
auto &json_result = response.get<util::json::Object>();
auto &json_result = std::get<util::json::Object>(response);
MakeResponse(sub_matchings, sub_routes, json_result);
}
}

View File

@ -29,14 +29,14 @@ class NearestAPI final : public BaseAPI
BOOST_ASSERT(phantom_nodes.size() == 1);
BOOST_ASSERT(parameters.coordinates.size() == 1);
if (response.is<flatbuffers::FlatBufferBuilder>())
if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(response))
{
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
auto &fb_result = std::get<flatbuffers::FlatBufferBuilder>(response);
MakeResponse(phantom_nodes, fb_result);
}
else
{
auto &json_result = response.get<util::json::Object>();
auto &json_result = std::get<util::json::Object>(response);
MakeResponse(phantom_nodes, json_result);
}
}

View File

@ -50,14 +50,14 @@ class RouteAPI : public BaseAPI
{
BOOST_ASSERT(!raw_routes.routes.empty());
if (response.is<flatbuffers::FlatBufferBuilder>())
if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(response))
{
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
auto &fb_result = std::get<flatbuffers::FlatBufferBuilder>(response);
MakeResponse(raw_routes, waypoint_candidates, fb_result);
}
else
{
auto &json_result = response.get<util::json::Object>();
auto &json_result = std::get<util::json::Object>(response);
MakeResponse(raw_routes, waypoint_candidates, json_result);
}
}
@ -158,7 +158,7 @@ class RouteAPI : public BaseAPI
}
template <typename ForwardIter>
mapbox::util::variant<flatbuffers::Offset<flatbuffers::String>,
std::variant<flatbuffers::Offset<flatbuffers::String>,
flatbuffers::Offset<flatbuffers::Vector<const fbresult::Position *>>>
MakeGeometry(flatbuffers::FlatBufferBuilder &builder, ForwardIter begin, ForwardIter end) const
{
@ -408,7 +408,7 @@ class RouteAPI : public BaseAPI
// Fill geometry
auto overview = MakeOverview(leg_geometries);
mapbox::util::variant<flatbuffers::Offset<flatbuffers::String>,
std::variant<flatbuffers::Offset<flatbuffers::String>,
flatbuffers::Offset<flatbuffers::Vector<const fbresult::Position *>>>
geometry;
if (overview)
@ -426,8 +426,7 @@ class RouteAPI : public BaseAPI
routeObject.add_legs(legs_vector);
if (overview)
{
mapbox::util::apply_visitor(GeometryVisitor<fbresult::RouteObjectBuilder>(routeObject),
geometry);
std::visit(GeometryVisitor<fbresult::RouteObjectBuilder>(routeObject), geometry);
}
return routeObject.Finish();
@ -644,7 +643,7 @@ class RouteAPI : public BaseAPI
stepBuilder.add_rotary_pronunciation(rotary_pronunciation_string);
stepBuilder.add_intersections(intersections_vector);
stepBuilder.add_maneuver(maneuver_buffer);
mapbox::util::apply_visitor(GeometryVisitor<fbresult::StepBuilder>(stepBuilder), geometry);
std::visit(GeometryVisitor<fbresult::StepBuilder>(stepBuilder), geometry);
return stepBuilder.Finish();
};

View File

@ -50,14 +50,14 @@ class TableAPI final : public BaseAPI
const std::vector<TableCellRef> &fallback_speed_cells,
osrm::engine::api::ResultT &response) const
{
if (response.is<flatbuffers::FlatBufferBuilder>())
if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(response))
{
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
auto &fb_result = std::get<flatbuffers::FlatBufferBuilder>(response);
MakeResponse(tables, candidates, fallback_speed_cells, fb_result);
}
else
{
auto &json_result = response.get<util::json::Object>();
auto &json_result = std::get<util::json::Object>(response);
MakeResponse(tables, candidates, fallback_speed_cells, json_result);
}
}
@ -377,7 +377,8 @@ class TableAPI final : public BaseAPI
return util::json::Value(
util::json::Number(from_alias<double>(duration) / 10.));
});
json_table.values.push_back(std::move(json_row));
json_table.values.push_back(util::json::Value{json_row});
}
return json_table;
}
@ -406,7 +407,7 @@ class TableAPI final : public BaseAPI
return util::json::Value(util::json::Number(
std::round(from_alias<double>(distance) * 10) / 10.));
});
json_table.values.push_back(std::move(json_row));
json_table.values.push_back(util::json::Value{json_row});
}
return json_table;
}
@ -415,14 +416,17 @@ class TableAPI final : public BaseAPI
MakeEstimatesTable(const std::vector<TableCellRef> &fallback_speed_cells) const
{
util::json::Array json_table;
std::for_each(fallback_speed_cells.begin(),
std::for_each(
fallback_speed_cells.begin(),
fallback_speed_cells.end(),
[&](const auto &cell)
{
util::json::Array row;
row.values.push_back(util::json::Number(cell.row));
row.values.push_back(util::json::Number(cell.column));
json_table.values.push_back(std::move(row));
util::json::Value jCellRow{util::json::Number(static_cast<double>(cell.row))};
util::json::Value jCellColumn{util::json::Number(static_cast<double>(cell.column))};
row.values.push_back(jCellRow);
row.values.push_back(jCellColumn);
json_table.values.push_back(util::json::Value{row});
});
return json_table;
}

View File

@ -27,14 +27,14 @@ class TripAPI final : public RouteAPI
{
BOOST_ASSERT(sub_trips.size() == sub_routes.size());
if (response.is<flatbuffers::FlatBufferBuilder>())
if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(response))
{
auto &fb_result = response.get<flatbuffers::FlatBufferBuilder>();
auto &fb_result = std::get<flatbuffers::FlatBufferBuilder>(response);
MakeResponse(sub_trips, sub_routes, candidates, fb_result);
}
else
{
auto &json_result = response.get<util::json::Object>();
auto &json_result = std::get<util::json::Object>(response);
MakeResponse(sub_trips, sub_routes, candidates, json_result);
}
}

View File

@ -95,7 +95,7 @@ class BasePlugin
const std::string &message,
osrm::engine::api::ResultT &result) const
{
mapbox::util::apply_visitor(ErrorRenderer(code, message), result);
std::visit(ErrorRenderer(code, message), result);
return Status::Error;
}

View File

@ -7,8 +7,8 @@
#include "util/typedefs.hpp"
#include <boost/assert.hpp>
#include <mapbox/variant.hpp>
#include <utility>
#include <variant>
namespace osrm::extractor
{

View File

@ -11,7 +11,7 @@
#include "util/std_hash.hpp"
#include "util/vector_view.hpp"
#include <mapbox/variant.hpp>
#include <variant>
#include <algorithm>

View File

@ -1,12 +1,10 @@
#ifndef RESTRICTION_HPP
#define RESTRICTION_HPP
#include "turn_path.hpp"
#include "util/coordinate.hpp"
#include "util/opening_hours.hpp"
#include "util/typedefs.hpp"
#include "mapbox/variant.hpp"
#include "turn_path.hpp"
#include <limits>
namespace osrm::extractor

View File

@ -4,7 +4,7 @@
#include "util/typedefs.hpp"
#include <algorithm>
#include <mapbox/variant.hpp>
#include <variant>
#include <vector>
namespace osrm::extractor
@ -61,50 +61,50 @@ struct InputViaWayPath
struct InputTurnPath
{
mapbox::util::variant<InputViaNodePath, InputViaWayPath> node_or_way;
std::variant<InputViaNodePath, InputViaWayPath> node_or_way;
TurnPathType Type() const
{
BOOST_ASSERT(node_or_way.which() < TurnPathType::NUM_TURN_PATH_TYPES);
return static_cast<TurnPathType>(node_or_way.which());
BOOST_ASSERT(node_or_way.index() < TurnPathType::NUM_TURN_PATH_TYPES);
return static_cast<TurnPathType>(node_or_way.index());
}
OSMWayID From() const
{
return node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH
? mapbox::util::get<InputViaNodePath>(node_or_way).from
: mapbox::util::get<InputViaWayPath>(node_or_way).from;
return node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH
? std::get<InputViaNodePath>(node_or_way).from
: std::get<InputViaWayPath>(node_or_way).from;
}
OSMWayID To() const
{
return node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH
? mapbox::util::get<InputViaNodePath>(node_or_way).to
: mapbox::util::get<InputViaWayPath>(node_or_way).to;
return node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH
? std::get<InputViaNodePath>(node_or_way).to
: std::get<InputViaWayPath>(node_or_way).to;
}
InputViaWayPath &AsViaWayPath()
{
BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_WAY_TURN_PATH);
return mapbox::util::get<InputViaWayPath>(node_or_way);
BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_WAY_TURN_PATH);
return std::get<InputViaWayPath>(node_or_way);
}
const InputViaWayPath &AsViaWayPath() const
{
BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_WAY_TURN_PATH);
return mapbox::util::get<InputViaWayPath>(node_or_way);
BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_WAY_TURN_PATH);
return std::get<InputViaWayPath>(node_or_way);
}
InputViaNodePath &AsViaNodePath()
{
BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH);
return mapbox::util::get<InputViaNodePath>(node_or_way);
BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH);
return std::get<InputViaNodePath>(node_or_way);
}
const InputViaNodePath &AsViaNodePath() const
{
BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH);
return mapbox::util::get<InputViaNodePath>(node_or_way);
BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH);
return std::get<InputViaNodePath>(node_or_way);
}
};
@ -175,63 +175,63 @@ struct ViaWayPath
// between node/way paths
struct TurnPath
{
mapbox::util::variant<ViaNodePath, ViaWayPath> node_or_way;
std::variant<ViaNodePath, ViaWayPath> node_or_way;
NodeID To() const
{
return node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH
? mapbox::util::get<ViaNodePath>(node_or_way).to
: mapbox::util::get<ViaWayPath>(node_or_way).to;
return node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH
? std::get<ViaNodePath>(node_or_way).to
: std::get<ViaWayPath>(node_or_way).to;
}
NodeID From() const
{
return node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH
? mapbox::util::get<ViaNodePath>(node_or_way).from
: mapbox::util::get<ViaWayPath>(node_or_way).from;
return node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH
? std::get<ViaNodePath>(node_or_way).from
: std::get<ViaWayPath>(node_or_way).from;
}
NodeID FirstVia() const
{
if (node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH)
if (node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH)
{
return mapbox::util::get<ViaNodePath>(node_or_way).via;
return std::get<ViaNodePath>(node_or_way).via;
}
else
{
BOOST_ASSERT(!mapbox::util::get<ViaWayPath>(node_or_way).via.empty());
return mapbox::util::get<ViaWayPath>(node_or_way).via[0];
BOOST_ASSERT(!std::get<ViaWayPath>(node_or_way).via.empty());
return std::get<ViaWayPath>(node_or_way).via[0];
}
}
ViaWayPath &AsViaWayPath()
{
BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_WAY_TURN_PATH);
return mapbox::util::get<ViaWayPath>(node_or_way);
BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_WAY_TURN_PATH);
return std::get<ViaWayPath>(node_or_way);
}
const ViaWayPath &AsViaWayPath() const
{
BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_WAY_TURN_PATH);
return mapbox::util::get<ViaWayPath>(node_or_way);
BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_WAY_TURN_PATH);
return std::get<ViaWayPath>(node_or_way);
}
ViaNodePath &AsViaNodePath()
{
BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH);
return mapbox::util::get<ViaNodePath>(node_or_way);
BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH);
return std::get<ViaNodePath>(node_or_way);
}
const ViaNodePath &AsViaNodePath() const
{
BOOST_ASSERT(node_or_way.which() == TurnPathType::VIA_NODE_TURN_PATH);
return mapbox::util::get<ViaNodePath>(node_or_way);
BOOST_ASSERT(node_or_way.index() == TurnPathType::VIA_NODE_TURN_PATH);
return std::get<ViaNodePath>(node_or_way);
}
TurnPathType Type() const
{
BOOST_ASSERT(node_or_way.which() < TurnPathType::NUM_TURN_PATH_TYPES);
return static_cast<TurnPathType>(node_or_way.which());
BOOST_ASSERT(node_or_way.index() < TurnPathType::NUM_TURN_PATH_TYPES);
return static_cast<TurnPathType>(node_or_way.index());
}
bool operator==(const TurnPath &other) const

View File

@ -29,7 +29,7 @@ struct V8Renderer
for (const auto &keyValue : object.values)
{
Napi::Value child;
mapbox::util::apply_visitor(V8Renderer(env, child), keyValue.second);
std::visit(V8Renderer(env, child), keyValue.second);
obj.Set(keyValue.first, child);
}
out = obj;
@ -41,7 +41,7 @@ struct V8Renderer
for (auto i = 0u; i < array.values.size(); ++i)
{
Napi::Value child;
mapbox::util::apply_visitor(V8Renderer(env, child), array.values[i]);
std::visit(V8Renderer(env, child), array.values[i]);
a.Set(i, child);
}
out = a;

View File

@ -28,6 +28,7 @@
#include <sstream>
#include <stdexcept>
#include <string>
#include <variant>
#include <vector>
#include <exception>
@ -50,7 +51,7 @@ struct PluginParameters
bool renderToBuffer = false;
};
using ObjectOrString = typename mapbox::util::variant<osrm::json::Object, std::string>;
using ObjectOrString = typename std::variant<osrm::json::Object, std::string>;
template <typename ResultT> inline Napi::Value render(const Napi::Env &env, const ResultT &result);
@ -61,18 +62,18 @@ template <> Napi::Value inline render(const Napi::Env &env, const std::string &r
template <> Napi::Value inline render(const Napi::Env &env, const ObjectOrString &result)
{
if (result.is<osrm::json::Object>())
if (std::holds_alternative<osrm::json::Object>(result))
{
// Convert osrm::json object tree into matching v8 object tree
Napi::Value value;
renderToV8(env, value, result.get<osrm::json::Object>());
renderToV8(env, value, std::get<osrm::json::Object>(result));
return value;
}
else
{
// Return the string object as a node Buffer
return Napi::Buffer<char>::Copy(
env, result.get<std::string>().data(), result.get<std::string>().size());
env, std::get<std::string>(result).data(), std::get<std::string>(result).size());
}
}
@ -95,7 +96,7 @@ inline void ParseResult(const osrm::Status &result_status, osrm::json::Object &r
if (result_status == osrm::Status::Error)
{
throw std::logic_error(code_iter->second.get<osrm::json::String>().value.c_str());
throw std::logic_error(std::get<osrm::json::String>(code_iter->second).value.c_str());
}
result.values.erase(code_iter);

View File

@ -5,7 +5,7 @@
#include "osrm/osrm.hpp"
#include "util/coordinate.hpp"
#include <mapbox/variant.hpp>
#include <variant>
#include <string>
#include <vector>

View File

@ -51,7 +51,7 @@ class GeojsonLogger
if (!first)
ofs << ",\n\t\t";
util::json::render(ofs, object.get<util::json::Object>());
util::json::render(ofs, std::get<util::json::Object>(object));
first = false;
}

View File

@ -55,12 +55,12 @@ inline util::json::Object makeStyle(const GeojsonStyleSize size_type,
struct CoordinateToJsonArray
{
util::json::Array operator()(const util::Coordinate coordinate)
util::json::Value operator()(const util::Coordinate coordinate)
{
util::json::Array json_coordinate;
json_coordinate.values.push_back(static_cast<double>(toFloating(coordinate.lon)));
json_coordinate.values.push_back(static_cast<double>(toFloating(coordinate.lat)));
return json_coordinate;
return util::json::Value{json_coordinate};
}
};
@ -73,7 +73,7 @@ struct NodeIdToCoordinate
const std::vector<util::Coordinate> &node_coordinates;
util::json::Array operator()(const NodeID nid)
util::json::Value operator()(const NodeID nid)
{
auto coordinate = node_coordinates[nid];
CoordinateToJsonArray converter;

View File

@ -31,11 +31,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef JSON_CONTAINER_HPP
#define JSON_CONTAINER_HPP
#include <mapbox/variant.hpp>
#include <string>
#include <unordered_map>
#include <utility>
#include <variant>
#include <vector>
namespace osrm::util::json
@ -96,13 +95,7 @@ struct Null
*
* Dispatch on its type by either by using apply_visitor or its get function.
*/
using Value = mapbox::util::variant<String,
Number,
mapbox::util::recursive_wrapper<Object>,
mapbox::util::recursive_wrapper<Array>,
True,
False,
Null>;
using Value = std::variant<String, Number, Object, Array, True, False, Null>;
/**
* Typed Object.

View File

@ -81,8 +81,8 @@ struct Comparator
const auto &rhs_child = rhs.values.find(key)->second;
const auto &lhs_child = lhs.values.find(key)->second;
auto is_same = mapbox::util::apply_visitor(
Comparator(reason, lhs_path + "." + key, rhs_path + "." + key),
auto is_same =
std::visit(Comparator(reason, lhs_path + "." + key, rhs_path + "." + key),
lhs_child,
rhs_child);
if (!is_same)
@ -104,8 +104,7 @@ struct Comparator
for (auto i = 0UL; i < lhs.values.size(); ++i)
{
auto is_same =
mapbox::util::apply_visitor(Comparator(reason,
auto is_same = std::visit(Comparator(reason,
lhs_path + "[" + std::to_string(i) + "]",
rhs_path + "[" + std::to_string(i) + "]"),
lhs.values[i],
@ -151,8 +150,7 @@ struct Comparator
inline bool compare(const Value &reference, const Value &result, std::string &reason)
{
return mapbox::util::apply_visitor(
Comparator(reason, "reference", "result"), reference, result);
return std::visit(Comparator(reason, "reference", "result"), reference, result);
}
} // namespace osrm::util::json

View File

@ -67,7 +67,7 @@ template <typename Out> struct Renderer
write('\"');
write(it->first);
write<>("\":");
mapbox::util::apply_visitor(Renderer(out), it->second);
std::visit(Renderer(out), it->second);
if (++it != end)
{
write(',');
@ -81,7 +81,7 @@ template <typename Out> struct Renderer
write('[');
for (auto it = array.values.cbegin(), end = array.values.cend(); it != end;)
{
mapbox::util::apply_visitor(Renderer(out), *it);
std::visit(Renderer(out), *it);
if (++it != end)
{
write(',');

View File

@ -12,9 +12,6 @@ set -o nounset
OSMIUM_PATH="osmcode/libosmium"
OSMIUM_TAG=v2.14.0
VARIANT_PATH="mapbox/variant"
VARIANT_TAG=v1.2.0
SOL_PATH="ThePhD/sol2"
SOL_TAG=v2.17.5
@ -56,6 +53,6 @@ function update_subtree () {
}
## Update dependencies
for dep in osmium variant sol rapidjson microtar protozero vtzero fmt; do
for dep in osmium sol rapidjson microtar protozero vtzero fmt; do
update_subtree $dep
done

View File

@ -86,7 +86,7 @@ json::Object load(const char *filename)
json::Value result;
convert(document, result);
return result.get<json::Object>();
return std::get<json::Object>(result);
}
} // namespace

View File

@ -232,9 +232,9 @@ try
{
engine::api::ResultT result = json::Object();
const auto rc = osrm.Match(params, result);
auto &json_result = result.get<json::Object>();
auto &json_result = std::get<json::Object>(result);
if (rc != Status::Ok ||
json_result.values.at("matchings").get<json::Array>().values.size() != 1)
std::get<json::Array>(json_result.values.at("matchings")).values.size() != 1)
{
throw std::runtime_error{"Couldn't match"};
}

View File

@ -76,7 +76,7 @@ try
{
engine::api::ResultT result = json::Object();
const auto rc = osrm.Route(params, result);
auto &json_result = result.get<json::Object>();
auto &json_result = std::get<json::Object>(result);
if (rc != Status::Ok || json_result.values.find("routes") == json_result.values.end())
{
throw std::runtime_error{"Couldn't route"};

View File

@ -74,12 +74,12 @@ std::string waypointTypeToString(const guidance::WaypointType waypoint_type)
return waypoint_type_names[static_cast<std::size_t>(waypoint_type)];
}
util::json::Array coordinateToLonLat(const util::Coordinate &coordinate)
util::json::Value coordinateToLonLat(const util::Coordinate &coordinate)
{
util::json::Array array;
array.values.push_back(static_cast<double>(util::toFloating(coordinate.lon)));
array.values.push_back(static_cast<double>(util::toFloating(coordinate.lat)));
return array;
return util::json::Value{std::move(array)};
}
} // namespace detail

View File

@ -663,7 +663,7 @@ Status TilePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
{
BOOST_ASSERT(parameters.IsValid());
auto &pbf_buffer = result.get<std::string>();
auto &pbf_buffer = std::get<std::string>(result);
const auto &facade = algorithms.GetFacade();
auto edges = getEdges(facade, parameters.x, parameters.y, parameters.z);
auto segregated_nodes = getSegregatedNodes(facade, edges);

View File

@ -0,0 +1,60 @@
#include "engine/routing_algorithms/routing_base_mld.hpp"
namespace osrm::engine::routing_algorithms::mld
{
double getNetworkDistance(SearchEngineData<mld::Algorithm> &engine_working_data,
const DataFacade<mld::Algorithm> &facade,
typename SearchEngineData<mld::Algorithm>::QueryHeap &forward_heap,
typename SearchEngineData<mld::Algorithm>::QueryHeap &reverse_heap,
const PhantomNode &source_phantom,
const PhantomNode &target_phantom,
EdgeWeight weight_upper_bound)
{
forward_heap.Clear();
reverse_heap.Clear();
const PhantomEndpoints endpoints{source_phantom, target_phantom};
insertNodesInHeaps(forward_heap, reverse_heap, endpoints);
auto [weight, unpacked_nodes, unpacked_edges] = search(
engine_working_data, facade, forward_heap, reverse_heap, {}, weight_upper_bound, endpoints);
if (weight == INVALID_EDGE_WEIGHT)
{
return std::numeric_limits<double>::max();
}
BOOST_ASSERT(unpacked_nodes.size() >= 1);
EdgeDistance distance = {0.0};
if (source_phantom.forward_segment_id.id == unpacked_nodes.front())
{
BOOST_ASSERT(source_phantom.forward_segment_id.enabled);
distance = EdgeDistance{0} - source_phantom.GetForwardDistance();
}
else if (source_phantom.reverse_segment_id.id == unpacked_nodes.front())
{
BOOST_ASSERT(source_phantom.reverse_segment_id.enabled);
distance = EdgeDistance{0} - source_phantom.GetReverseDistance();
}
for (size_t index = 0; index < unpacked_nodes.size() - 1; ++index)
{
distance += facade.GetNodeDistance(unpacked_nodes[index]);
}
if (target_phantom.forward_segment_id.id == unpacked_nodes.back())
{
BOOST_ASSERT(target_phantom.forward_segment_id.enabled);
distance += target_phantom.GetForwardDistance();
}
else if (target_phantom.reverse_segment_id.id == unpacked_nodes.back())
{
BOOST_ASSERT(target_phantom.reverse_segment_id.enabled);
distance += target_phantom.GetReverseDistance();
}
return from_alias<double>(distance);
}
} // namespace osrm::engine::routing_algorithms::mld

View File

@ -147,7 +147,7 @@ inline void async(const Napi::CallbackInfo &info,
osrm::engine::api::ResultT r;
r = osrm::util::json::Object();
const auto status = ((*osrm).*(service))(*params, r);
auto &json_result = r.get<osrm::json::Object>();
auto &json_result = std::get<osrm::json::Object>(r);
ParseResult(status, json_result);
if (pluginParams.renderToBuffer)
{
@ -165,7 +165,7 @@ inline void async(const Napi::CallbackInfo &info,
{
osrm::engine::api::ResultT r = flatbuffers::FlatBufferBuilder();
const auto status = ((*osrm).*(service))(*params, r);
const auto &fbs_result = r.get<flatbuffers::FlatBufferBuilder>();
const auto &fbs_result = std::get<flatbuffers::FlatBufferBuilder>(r);
ParseResult(status, fbs_result);
BOOST_ASSERT(pluginParams.renderToBuffer);
std::string result_str(
@ -240,7 +240,7 @@ inline void asyncForTiles(const Napi::CallbackInfo &info,
{
result = std::string();
const auto status = ((*osrm).*(service))(*params, result);
auto str_result = result.get<std::string>();
auto str_result = std::get<std::string>(result);
ParseResult(status, str_result);
}
catch (const std::exception &e)
@ -252,7 +252,7 @@ inline void asyncForTiles(const Napi::CallbackInfo &info,
{
Napi::HandleScope scope{Env()};
Callback().Call({Env().Null(), render(Env(), result.get<std::string>())});
Callback().Call({Env().Null(), render(Env(), std::get<std::string>(result))});
}
// Keeps the OSRM object alive even after shutdown until we're done with callback

View File

@ -65,7 +65,7 @@ Status OSRM::Route(const engine::api::RouteParameters &params, json::Object &jso
{
osrm::engine::api::ResultT result = json::Object();
auto status = engine_->Route(params, result);
json_result = std::move(result.get<json::Object>());
json_result = std::move(std::get<json::Object>(result));
return status;
}
@ -78,7 +78,7 @@ Status OSRM::Table(const engine::api::TableParameters &params, json::Object &jso
{
osrm::engine::api::ResultT result = json::Object();
auto status = engine_->Table(params, result);
json_result = std::move(result.get<json::Object>());
json_result = std::move(std::get<json::Object>(result));
return status;
}
@ -91,7 +91,7 @@ Status OSRM::Nearest(const engine::api::NearestParameters &params, json::Object
{
osrm::engine::api::ResultT result = json::Object();
auto status = engine_->Nearest(params, result);
json_result = std::move(result.get<json::Object>());
json_result = std::move(std::get<json::Object>(result));
return status;
}
@ -104,7 +104,7 @@ Status OSRM::Trip(const engine::api::TripParameters &params, json::Object &json_
{
osrm::engine::api::ResultT result = json::Object();
auto status = engine_->Trip(params, result);
json_result = std::move(result.get<json::Object>());
json_result = std::move(std::get<json::Object>(result));
return status;
}
@ -118,7 +118,7 @@ Status OSRM::Match(const engine::api::MatchParameters &params, json::Object &jso
{
osrm::engine::api::ResultT result = json::Object();
auto status = engine_->Match(params, result);
json_result = std::move(result.get<json::Object>());
json_result = std::move(std::get<json::Object>(result));
return status;
}
@ -131,7 +131,7 @@ Status OSRM::Tile(const engine::api::TileParameters &params, std::string &str_re
{
osrm::engine::api::ResultT result = std::string();
auto status = engine_->Tile(params, result);
str_result = std::move(result.get<std::string>());
str_result = std::move(std::get<std::string>(result));
return status;
}

View File

@ -15,7 +15,6 @@
#include "util/coordinate.hpp"
#include "util/geojson_debug_logger.hpp"
#include "util/geojson_debug_policies.hpp"
#include "util/integer_range.hpp"
#include "util/json_container.hpp"
#include "util/log.hpp"

View File

@ -21,6 +21,7 @@
#include <algorithm>
#include <string>
#include <thread>
#include <variant>
namespace osrm::server
{
@ -38,17 +39,17 @@ void SendResponse(ServiceHandler::ResultT &result, http::reply &current_reply)
current_reply.headers.emplace_back("Access-Control-Allow-Methods", "GET");
current_reply.headers.emplace_back("Access-Control-Allow-Headers",
"X-Requested-With, Content-Type");
if (result.is<util::json::Object>())
if (std::holds_alternative<util::json::Object>(result))
{
current_reply.headers.emplace_back("Content-Type", "application/json; charset=UTF-8");
current_reply.headers.emplace_back("Content-Disposition",
"inline; filename=\"response.json\"");
util::json::render(current_reply.content, result.get<util::json::Object>());
util::json::render(current_reply.content, std::get<util::json::Object>(result));
}
else if (result.is<flatbuffers::FlatBufferBuilder>())
else if (std::holds_alternative<flatbuffers::FlatBufferBuilder>(result))
{
auto &buffer = result.get<flatbuffers::FlatBufferBuilder>();
auto &buffer = std::get<flatbuffers::FlatBufferBuilder>(result);
current_reply.content.resize(buffer.GetSize());
std::copy(buffer.GetBufferPointer(),
buffer.GetBufferPointer() + buffer.GetSize(),
@ -59,10 +60,10 @@ void SendResponse(ServiceHandler::ResultT &result, http::reply &current_reply)
}
else
{
BOOST_ASSERT(result.is<std::string>());
current_reply.content.resize(result.get<std::string>().size());
std::copy(result.get<std::string>().cbegin(),
result.get<std::string>().cend(),
BOOST_ASSERT(std::holds_alternative<std::string>(result));
current_reply.content.resize(std::get<std::string>(result).size());
std::copy(std::get<std::string>(result).cbegin(),
std::get<std::string>(result).cend(),
current_reply.content.begin());
current_reply.headers.emplace_back("Content-Type", "application/x-protobuf");
@ -127,7 +128,7 @@ void RequestHandler::HandleRequest(const http::request &current_request, http::r
current_reply.status = http::reply::bad_request;
result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
auto &json_result = std::get<util::json::Object>(result);
json_result.values["code"] = "InvalidUrl";
json_result.values["message"] = "URL string malformed close to position " +
std::to_string(position) + ": \"" + context + "\"";
@ -174,7 +175,7 @@ void RequestHandler::HandleRequest(const http::request &current_request, http::r
current_reply.status = http::reply::bad_request;
ServiceHandler::ResultT result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
auto &json_result = std::get<util::json::Object>(result);
json_result.values["code"] = "DisabledDataset";
json_result.values["message"] = e.what();
SendResponse(result, current_reply);

View File

@ -42,7 +42,7 @@ engine::Status MatchService::RunQuery(std::size_t prefix_length,
osrm::engine::api::ResultT &result)
{
result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
auto &json_result = std::get<util::json::Object>(result);
auto query_iterator = query.begin();
auto parameters =

View File

@ -36,7 +36,7 @@ engine::Status NearestService::RunQuery(std::size_t prefix_length,
osrm::engine::api::ResultT &result)
{
result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
auto &json_result = std::get<util::json::Object>(result);
auto query_iterator = query.begin();
auto parameters =

View File

@ -40,7 +40,7 @@ engine::Status RouteService::RunQuery(std::size_t prefix_length,
osrm::engine::api::ResultT &result)
{
result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
auto &json_result = std::get<util::json::Object>(result);
auto query_iterator = query.begin();
auto parameters =

View File

@ -71,7 +71,7 @@ engine::Status TableService::RunQuery(std::size_t prefix_length,
osrm::engine::api::ResultT &result)
{
result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
auto &json_result = std::get<util::json::Object>(result);
auto query_iterator = query.begin();
auto parameters =

View File

@ -22,7 +22,7 @@ engine::Status TileService::RunQuery(std::size_t prefix_length,
{
const auto position = std::distance(query.begin(), query_iterator);
result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
auto &json_result = std::get<util::json::Object>(result);
json_result.values["code"] = "InvalidQuery";
json_result.values["message"] =
"Query string malformed close to position " + std::to_string(prefix_length + position);
@ -33,7 +33,7 @@ engine::Status TileService::RunQuery(std::size_t prefix_length,
if (!parameters->IsValid())
{
result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
auto &json_result = std::get<util::json::Object>(result);
json_result.values["code"] = "InvalidOptions";
json_result.values["message"] = "Invalid coodinates. Only zoomlevel 12+ is supported";
return engine::Status::Error;

View File

@ -42,7 +42,7 @@ engine::Status TripService::RunQuery(std::size_t prefix_length,
osrm::engine::api::ResultT &result)
{
result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
auto &json_result = std::get<util::json::Object>(result);
auto query_iterator = query.begin();
auto parameters =
@ -51,7 +51,7 @@ engine::Status TripService::RunQuery(std::size_t prefix_length,
{
const auto position = std::distance(query.begin(), query_iterator);
result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
auto &json_result = std::get<util::json::Object>(result);
json_result.values["code"] = "InvalidQuery";
json_result.values["message"] =
"Query string malformed close to position " + std::to_string(prefix_length + position);

View File

@ -31,7 +31,7 @@ engine::Status ServiceHandler::RunQuery(api::ParsedURL parsed_url,
if (service_iter == service_map.end())
{
result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
auto &json_result = std::get<util::json::Object>(result);
json_result.values["code"] = "InvalidService";
json_result.values["message"] = "Service " + parsed_url.service + " not found!";
return engine::Status::Error;
@ -41,7 +41,7 @@ engine::Status ServiceHandler::RunQuery(api::ParsedURL parsed_url,
if (service->GetVersion() != parsed_url.version)
{
result = util::json::Object();
auto &json_result = result.get<util::json::Object>();
auto &json_result = std::get<util::json::Object>(result);
json_result.values["code"] = "InvalidVersion";
json_result.values["message"] = "Service " + parsed_url.service + " not found!";
return engine::Status::Error;

View File

@ -1,89 +0,0 @@
---
# Mapbox.Variant C/C+ style
Language: Cpp
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: false
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
BeforeCatch: true
BeforeElse: true
IndentBraces: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
ColumnLimit: 0
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 4
UseTab: Never
...

View File

@ -1,9 +0,0 @@
.DS_Store
out
profiling
build
deps
*.gcda
*.gcno
.ycm_extra_conf.pyc
mason_packages

View File

@ -1,3 +0,0 @@
[submodule ".mason"]
path = .mason
url = https://github.com/mapbox/mason.git

@ -1 +0,0 @@
Subproject commit 6adb140160cb549400f73ea35c1d9eb5782210e0

View File

@ -1,159 +0,0 @@
language: generic
sudo: false
matrix:
include:
# clang++ 4.0 via mason with -flto and -fsanitize=cfi
- os: linux
compiler: "clang++-40-mason"
env: CXX=clang++-4.0 CXXFLAGS="-flto -fsanitize=cfi -fvisibility=hidden" LDFLAGS="-flto -fsanitize=cfi -fvisibility=hidden"
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libstdc++-4.9-dev' ]
before_install:
- git submodule update --init
- ./.mason/mason install clang++ 4.0.1
- export PATH=$(./.mason/mason prefix clang++ 4.0.1)/bin:${PATH}
- ./.mason/mason install binutils 2.27
- export PATH=$(./.mason/mason prefix binutils 2.27)/bin:${PATH}
# clang++ 4.0 via mason with -fsanitize=address
- os: linux
compiler: "clang++-40-mason"
env: CXX=clang++-4.0 CXXFLAGS="-fsanitize=address -fsanitize-address-use-after-scope -fno-omit-frame-pointer -fno-common" LDFLAGS="-fsanitize=address" ASAN_OPTIONS=check_initialization_order=1:detect_stack_use_after_return=1
sudo: required
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libstdc++-4.9-dev' ]
before_install:
- git submodule update --init
- ./.mason/mason install clang++ 4.0.1
- export PATH=$(./.mason/mason prefix clang++ 4.0.1)/bin:${PATH}
# clang++ 4.0 via mason with -fsanitize=undefined
- os: linux
compiler: "clang++-40-mason"
env: CXX=clang++-4.0 CXXFLAGS="-fsanitize=undefined" LDFLAGS="-fsanitize=undefined"
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libstdc++-4.9-dev' ]
before_install:
- git submodule update --init
- ./.mason/mason install clang++ 4.0.1
- export PATH=$(./.mason/mason prefix clang++ 4.0.1)/bin:${PATH}
# clang++ 4.0 via mason with -fsanitize=integer
- os: linux
compiler: "clang++-40-mason"
env: CXX=clang++-4.0 CXXFLAGS="-fsanitize=integer" LDFLAGS="-fsanitize=integer"
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libstdc++-4.9-dev' ]
before_install:
- git submodule update --init
- ./.mason/mason install clang++ 4.0.1
- export PATH=$(./.mason/mason prefix clang++ 4.0.1)/bin:${PATH}
# clang++ 4.0 via mason with -fsanitize=safe-stack
- os: linux
compiler: "clang++-40-mason"
env: CXX=clang++-4.0 CXXFLAGS="-fsanitize=safe-stack" LDFLAGS="-fsanitize=safe-stack"
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'libstdc++-4.9-dev' ]
before_install:
- git submodule update --init
- ./.mason/mason install clang++ 4.0.1
- export PATH=$(./.mason/mason prefix clang++ 4.0.1)/bin:${PATH}
- os: osx
osx_image: xcode8
env: OSX_OLDEST_SUPPORTED=10.7 TEST_GYP_BUILD=True
compiler: clang
- os: osx
osx_image: xcode8
env: OSX_OLDEST_SUPPORTED=10.12
compiler: clang
- os: linux
compiler: "clang35"
env: CXX=clang++-3.5 COVERAGE=True
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test', 'llvm-toolchain-precise-3.5' ]
packages: [ 'clang-3.5', 'libstdc++-4.9-dev' ]
- os: linux
compiler: "clang36"
env: CXX=clang++-3.6
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test', 'llvm-toolchain-precise-3.6' ]
packages: [ 'clang-3.6' ]
- os: linux
compiler: "gcc48"
env: CXX=g++-4.8
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'g++-4.8' ]
- os: linux
compiler: "gcc49"
env: CXX=g++-4.9
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'g++-4.9' ]
- os: linux
compiler: "gcc5"
env: CXX=g++-5
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'g++-5' ]
- os: linux
compiler: "gcc6"
env: CXX=g++-6 CXX_STD=c++14
addons:
apt:
sources: [ 'ubuntu-toolchain-r-test' ]
packages: [ 'g++-6' ]
install:
- echo ${CXX}
- if [[ $(uname -s) == 'Linux' ]]; then
export PYTHONPATH=$(pwd)/.local/lib/python2.7/site-packages;
else
export PYTHONPATH=$(pwd)/.local/lib/python/site-packages;
fi
- if [[ ${COVERAGE:-0} == 'True' ]]; then
PYTHONUSERBASE=$(pwd)/.local pip install --user cpp-coveralls;
fi
script:
# Build in Release
- make
- make test
- make bench
- make sizes
- scripts/run_compilation_failure_tests.sh
- make clean;
# Build in Debug
- export BUILDTYPE=Debug
- make
- make test
- make bench
- make sizes
- scripts/run_compilation_failure_tests.sh
- if [[ ${TEST_GYP_BUILD:-0} == 'True' ]]; then
make clean;
make gyp;
fi
after_script:
- if [[ ${COVERAGE:-0} == 'True' ]]; then
make clean;
make coverage;
./out/cov-test;
cp unit*gc* test/;
./.local/bin/cpp-coveralls --gcov /usr/bin/llvm-cov-3.5 --gcov-options '\-lp' -i optional.hpp -i recursive_wrapper.hpp -i variant.hpp -i variant_io.hpp variant_cast.hpp;
fi

View File

@ -1,40 +0,0 @@
#-----------------------------------------------------------------------------
#
# Configuration for YouCompleteMe Vim plugin
#
# http://valloric.github.io/YouCompleteMe/
#
#-----------------------------------------------------------------------------
from os.path import realpath, dirname
basedir = dirname(realpath(__file__))
# some default flags
# for more information install clang-3.2-doc package and
# check UsersManual.html
flags = [
'-Werror',
'-Wall',
'-Wextra',
'-pedantic',
'-std=c++11',
# '-x' and 'c++' also required
# use 'c' for C projects
'-x',
'c++',
# include third party libraries
'-I.',
]
# youcompleteme is calling this function to get flags
# You can also set database for flags. Check: JSONCompilationDatabase.html in
# clang-3.2-doc package
def FlagsForFile( filename ):
return {
'flags': flags,
'do_cache': True
}

View File

@ -1,420 +0,0 @@
# Variant changelog
## 1.2.0
Released: July 3, 2020
(82f9561)
* Use perfect forwarding for internal value types deductions (#178) (#180)
* Implement support for "moving" values out (#142) (#178) (#180)
* Preserve ability to specify explicit `return_type` in visitors (#181)
* Add self-assignment checks in copy and move assignment operator= (#164)
* Add relevant tests
## 1.1.6
Released: April 25, 2019
(a4f87dc)
* make type used for `type_index` configurable via `type_index_t` typdef + use `unsigned int` by default. This addresses `sizeof` discrepancies between boost/std/mapbox variants (ref #19) [view commit](http://github.com/mapbox/variant/commit/9eec1fd48947d81af3debb82686c593b15f79aad)
* use `mapbox::util::type_index_t` (#19) [view commit](http://github.com/mapbox/variant/commit/05ee9aca16c3968e34db3b241c44eecb981344e0)
* Ensure internal index type is capable of holding all alternatives (ref #138) [view commit](http://github.com/mapbox/variant/commit/fa8e124a2367abc9c06f7e83926691085eed45c0)
* Add compile time check to disallow array types as alternatives. [view commit](http://github.com/mapbox/variant/commit/3f6fd131ef07a091338cec81ec8d23d6ca44528d)
* Make `type_index_t` configurable at compile time via `MAPBOX_VARIANT_MINIMIZE_SIZE` and `MAPBOX_VARIANT_OPTIMIZE_FOR_SPEED`. Default is `unsigned int`. (ref #138) [view commit](http://github.com/mapbox/variant/commit/35487cd39400b9a4bd30a18e6dfbf9cb1aaa80cd)
* add missing <limits> [view commit](http://github.com/mapbox/variant/commit/c839c666c324306a252b0fbcadd31e80e02e2898)
* Adds a test for polymorphic lambdas in match, resolves #140 [view commit](http://github.com/mapbox/variant/commit/9ac8978f5125182ac1bd9a1b68533bf9695f7289)
* Merge pull request #138 from mapbox/sizeof [view commit](http://github.com/mapbox/variant/commit/3d807d31621d52a8b27494c8f80aa50f6464f17d)
* Merge pull request #141 from mapbox/match-otherwise [view commit](http://github.com/mapbox/variant/commit/916139a2e51e125816efce6e19d428385601273f)
* Update bundled Catch to v1.9.0 [view commit](http://github.com/mapbox/variant/commit/f9c265d7e7a188aa4437f534d4c0648af0118b51)
* REQUIRE_THROWS etc take an expression not a block [view commit](http://github.com/mapbox/variant/commit/a064940e2ce7e40ef5e4db5710b399c68a71be4b)
* Merge pull request #143 from tomhughes/catch [view commit](http://github.com/mapbox/variant/commit/550ac2f159ca883d360c196149b466955c77a573)
* Add static_variant_cast, dynamic_variant_cast [view commit](http://github.com/mapbox/variant/commit/51fccd755b05ee9d3dec9da239acd15d0823c381)
* Merge pull request #144 from narizhny/Casts [view commit](http://github.com/mapbox/variant/commit/291121f6ac682c6cc5a7a69f253492f03ca7324f)
* recursive_wrapper fail to compile when used with 2 classes which are base and derived #146 [view commit](http://github.com/mapbox/variant/commit/7a541ba10d2eb9a9da0f11bb27319cd125d43a3d)
* recursive_wrapper test - avoid constructing new functor in recursive calls, call itself via `this` pointer. [view commit](http://github.com/mapbox/variant/commit/ea106db54b167b8dce7c0b3b9b59bb06b209db33)
* Merge branch 'master' of https://github.com/BlueSolei/variant into BlueSolei-master [view commit](http://github.com/mapbox/variant/commit/195367cfc19e1e08933487fa7cc56cb7f6d25cc8)
* Merge branch 'BlueSolei-master' [view commit](http://github.com/mapbox/variant/commit/e01b7bf3334e788fb99f4a510d5bc87a4a581342)
* add test for ref #147 + https://github.com/mapbox/variant/pull/147 [view commit](http://github.com/mapbox/variant/commit/6247207595902dbf898a430346335af2a3485c74)
* - Add a project mapbox_variant. - Use of the 'os' module to capture CXX_STD. - Common configs moved to project. - Built targets moved to 'out' directory. [view commit](http://github.com/mapbox/variant/commit/b2471ffc74c163194943b17b2b2c5758c59655ca)
* - Remove the use of boost libraries. - Add default build. [view commit](http://github.com/mapbox/variant/commit/561a09dd005468f9cdef651030471a1215f1885f)
* - Use of the module 'os' to get BOOST_DIR. - Add macro SINGLE_THREADED to single threading mode. - Define single threading mode as default. - Add lambda_overload_test and hashable_test. [view commit](http://github.com/mapbox/variant/commit/bd0a2d559724b8daa7d1ff33df90976e26a595aa)
* - Add auxiliar rule exe-test. [view commit](http://github.com/mapbox/variant/commit/04a6797a6aa2a86dd3eb6517893255c010f6e524)
* Merge pull request #153 from ricardocosme/boost-build [view commit](http://github.com/mapbox/variant/commit/266f68d9f1c3ad65e6d6c264f0130bc4c652618a)
* Use forwarding reference in make_visitor and visitor [view commit](http://github.com/mapbox/variant/commit/9f991da78d3146d32be67695a89c2b1197c826b2)
* Add copy assignment and move assignment operators. [view commit](http://github.com/mapbox/variant/commit/f0b50062b4fd2bf2b86aeada2efa8e36cfa6cb1c)
* Merge pull request #154 from ricardocosme/forwarding_reference_make_visitor [view commit](http://github.com/mapbox/variant/commit/b78b51548743737357e5b3bbe296f465d5f4fdae)
* add CHANGELOG.md skeleton [view commit](http://github.com/mapbox/variant/commit/555436f715e5e0929a13664f0911ecc4931356d1)
* add <sha1> to CHANGELOG entries. [view commit](http://github.com/mapbox/variant/commit/6497bce683e6e8edf80f80bc4fed65235690b335)
* update CHANGELOG (git log <tag1>...<tag2> --pretty=format:'* %s [view commit](http://github.com/mapbox/variant/commit/%H)' --reverse) [view commit](http://github.com/mapbox/variant/commit/75bb549d233eb94c74d2730dc3a8d8ed35c87f3d)
* use full sha1 [view commit](http://github.com/mapbox/variant/commit/ba3085a5eb6e874d43432dc75f3392092e1e7214)
* add intial `variant_alternative` implementation (#161 http://en.cppreference.com/w/cpp/utility/variant/variant_alternative) [view commit](http://github.com/mapbox/variant/commit/43357808cc93e69d2975e31e68986137ac5e88c9)
* add lost test check + remove stderr [view commit](http://github.com/mapbox/variant/commit/4b98c485cf7d74691f7921145054641daa66936e)
* alternative implementation of `variant_alternative` [view commit](http://github.com/mapbox/variant/commit/3449d00cf525d8ef98cee0f4a276e2928398a8f9)
* add `variant_alternative_t` [view commit](http://github.com/mapbox/variant/commit/3ffef950b005f31961f167242911b2f97d2634c3)
* add optimized 'variant_alternative' implementation usinh built-in `__type_pack_element` when available (clang++) [view commit](http://github.com/mapbox/variant/commit/ae193141379c1706e17098c67c5b4e4f48b19c48)
* add compile index in range check for __type_pack_element branch. [view commit](http://github.com/mapbox/variant/commit/8b1de314711bff2f9f3c748ac0ed7cd7d6400331)
* fix preprocessor logic [view commit](http://github.com/mapbox/variant/commit/30560e19e60c23227b29bc3434a163d2343333d3)
* add `variant_size` helper [view commit](http://github.com/mapbox/variant/commit/835ebc19321c6a9696a2072b7fbd5ca3de818860)
* Merge pull request #162 from mapbox/variant_alternative [view commit](http://github.com/mapbox/variant/commit/237f83cad2c76b1717ba4076c30aca32339336a8)
* Removes deprecated static_visitor to avoid msvc C4996 compiler warning [view commit](http://github.com/mapbox/variant/commit/215d64585ef92e16f18f5da81195b0279f53f599)
* Merge pull request #163 from MaxRis/master [view commit](http://github.com/mapbox/variant/commit/859a8c933a0c2ab18941acb9dcf834799c0de46c)
* Fix README.md issues [view commit](http://github.com/mapbox/variant/commit/0888a8e92df4c1cfd85419b05910355b2d78013b)
* Merge pull request #165 from nick70/master [view commit](http://github.com/mapbox/variant/commit/5eee328d69aaa805bd0b43bdaede12a8eb4632eb)
* Fix the noexcept specifications for move assignment and conversion. [view commit](http://github.com/mapbox/variant/commit/9c81bef8cf285d9fb45f1eaf9b29eba4fee08d1b)
* Merge pull request #160 from mlogan/master [view commit](http://github.com/mapbox/variant/commit/256ddd55582bb7c06c342315dbacc6a42fee4b34)
* report actual file size not allocated size. [view commit](http://github.com/mapbox/variant/commit/ef3856c85f389d4be7feb6555336168c4adcfa0e)
* use `ls -lah` as `du -h --apparent-size` is not universally supported. [view commit](http://github.com/mapbox/variant/commit/a64062576d9af09469183a94b9770c8e7f877a93)
* fix Makefile [view commit](http://github.com/mapbox/variant/commit/502e32b8bade6e19d7fe511f4634e7033f61235f)
* try fixing travis via upgrading clang++ from 3.9.1 -> 4.0.1 [view commit](http://github.com/mapbox/variant/commit/f31bcfb4bc97cf4c5e89b01bbfa7df4cd553f576)
* steady .. downgrade clang++ to 4.0.0 [view commit](http://github.com/mapbox/variant/commit/11a36a9f12adc30ac47afc9681ec8aa1a2d68c28)
* update mason [view commit](http://github.com/mapbox/variant/commit/fe0a0666fc734033f6a9cd2256226eec5943138a)
* update mason + update clang++ to 4.0.1 [view commit](http://github.com/mapbox/variant/commit/c1a14e7d9e9a10ea7d793d83043d9a18b974ca8e)
* Run ASAN builda in isolated VM via `sudo : required` [view commit](http://github.com/mapbox/variant/commit/5a5ecca5bef02072109a714bab840a36ea772f01)
* Merge pull request #167 from mapbox/clang++4 [view commit](http://github.com/mapbox/variant/commit/0f734f01e685a298e3756d30044a4164786c58c5)
* Moved to in-class initialization [view commit](http://github.com/mapbox/variant/commit/2fef61f08e44bcc99b1acc21ea78554b08d8f6e7)
* Merge pull request #171 from mapbox/jrex-mute-clang-analyzer [view commit](http://github.com/mapbox/variant/commit/0305fdb2a462ca39db7b8cce189561bed17b48
## 1.1.5
Released: January 7, 2017
(d2588a8f1d6b5d480d228e6d8a906ce634bdea9a)
* add package.json for publishing to npm [view commit](http://github.com/mapbox/variant/commit/cb5635ba2556d76aaba97e4d0fc14b82b48f8b61)
* test with clang 3.9 and g++-6 [view commit](http://github.com/mapbox/variant/commit/efa75df2735d3f5a5fa2646528d4006bf9b5b3dc)
* travis: fix addons [view commit](http://github.com/mapbox/variant/commit/ce2eea64499cd37eec7932ddf82f72b9f1a1b79e)
* makefile improvements [view commit](http://github.com/mapbox/variant/commit/c81b475b40797d503f18ddad4c065f6b1694d341)
* upgrade boost to 1.62.0 [view commit](http://github.com/mapbox/variant/commit/b9c58d631a22e97f4069a819765f5c157525df6a)
* upgrade mason [view commit](http://github.com/mapbox/variant/commit/a760cea8dab53e587498470861b364f1256a5e0d)
* test clang++ via mason [view commit](http://github.com/mapbox/variant/commit/84eeb54c9408297db4bc57e3ea5a1b3d9f075a66)
* fix clang++ PATH [view commit](http://github.com/mapbox/variant/commit/e07a533a8f451fe541db683fc713eb0012730115)
* disable clang++ 3.9, will work on getting working in a branch [view commit](http://github.com/mapbox/variant/commit/702826365d1ea13710b82949c254af5920c92999)
* test with clang++ sanitizers and flto [view commit](http://github.com/mapbox/variant/commit/9b2de45460f4df3a22c6607043d50df730dd42af)
* fix LDFLAGS [view commit](http://github.com/mapbox/variant/commit/20d693ed9a04cc6b689f4c6a1ed58c96f964b08a)
* -fsanitize=cfi and -fsanitize=safe-stack [view commit](http://github.com/mapbox/variant/commit/d1bb6e54608c6bfe3970b2653971da49b3c15ef8)
* more sanitizer options [view commit](http://github.com/mapbox/variant/commit/4fe5ced5db2cb46b23a6e326b5bf9292d95c0642)
* re-enable older compilers, trim excess [view commit](http://github.com/mapbox/variant/commit/6317a0b7406395729139327a83a71cfa14513fac)
* avoid expensive instantiation of tuple constructor in noexcept [view commit](http://github.com/mapbox/variant/commit/4febf973c2a0fc297869d78fc82368a16ee7f4fb)
* Merge pull request #132 from lightmare/avoid-tuple-instantiation [view commit](http://github.com/mapbox/variant/commit/18919174da93165a79ca5fdbfde4b172182c6156)
* enable -Werror, suppress warnings from non variant headers using isystem [view commit](http://github.com/mapbox/variant/commit/253047f53549c3fb1df441859cfd42aecc9f3a8f)
* fix conversion warnings [view commit](http://github.com/mapbox/variant/commit/539d712746d08a172e68a47f7aa73ffdda40b70b)
* build in both release and debug on travis [view commit](http://github.com/mapbox/variant/commit/cf9a534991b5a36f86674975768e0a1600c776be)
* fortification flags + -pthreads for linux where needed [view commit](http://github.com/mapbox/variant/commit/886377de081dd8099ef4a7869ae3ff5d6c850c8d)
* try without pthreads [view commit](http://github.com/mapbox/variant/commit/1023f2d9adcf0a14be7cb729abab8156ecd962c5)
* limit some flags to clang++ [view commit](http://github.com/mapbox/variant/commit/904dcaee6d0d872eae52578e38199577418f9a32)
* Add -pthread [view commit](http://github.com/mapbox/variant/commit/b433986199b7dfbe59fa498eb80791a49c625170)
* upgrade libstdc++ for coverage build [view commit](http://github.com/mapbox/variant/commit/7b409402c3cf4a0260aa36ee768ee474aa3683c1)
* drop -Wstack-protector which gives unhelpful warnings [view commit](http://github.com/mapbox/variant/commit/c8ec829ffb4498a0aea8ffa9b62ba4932cdefbdf)
* disable -Wparentheses for older gcc [view commit](http://github.com/mapbox/variant/commit/a80beaafc20c2c015ace5fb1e4c99f6de8c24d75)
* Merge pull request #133 from mapbox/Werror [view commit](http://github.com/mapbox/variant/commit/a9707c3de095c715f84a1855684a3dc8e37a594a)
* remove useless and/or dubious compiler flags [view commit](http://github.com/mapbox/variant/commit/5141d8d21a5b648e9fef879bfc12b29ffac7288d)
* Merge pull request #134 from lightmare/warnings [view commit](http://github.com/mapbox/variant/commit/18a8055fef0e14110c313ca358f0f7c88290bed0)
* osx: test that will support both latest (10.12) and oldest with c++11 support: 10.7 [view commit](http://github.com/mapbox/variant/commit/4923eb527c129060ba970d622d639ad2ada42497)
* fix gyp build [view commit](http://github.com/mapbox/variant/commit/5baa948fa73313091bc082b9f3d17c5b5f600cac)
* upgrade to llvm 3.9.1 [view commit](http://github.com/mapbox/variant/commit/f5fb4661ebf1ecd0167bce50b00a8339604395b0)
* upgrade mason [view commit](http://github.com/mapbox/variant/commit/61f8acea1b09de639b46c8af0c5aae29f51dd05c)
* Merge pull request #135 from mapbox/llvm-3.9.1 [view commit](http://github.com/mapbox/variant/commit/05b7612aa86c28f95d39ba786c7b611e811e4bf8)
* Trivial missing comma in README example code [view commit](http://github.com/mapbox/variant/commit/d2588a8f1d6b5d480d228e6d8a906ce634bdea9a)
## 1.1.4
Released: December 21, 2016
(02bd1ac4c07e6db9fe0f01267853e43b41637b74)
* Provides Convenient Lambda Overload Visitor Interface, resolves #113. [view commit](http://github.com/mapbox/variant/commit/d09188640b6d5a637f391108f849a962d02dbb40)
* Removes ::type Usage [view commit](http://github.com/mapbox/variant/commit/2275a61974aaf117fa8d08c08d640ffd05935db8)
* Adds C++14 SFINAE Test [view commit](http://github.com/mapbox/variant/commit/4d462f27b2d852f66a3769e5983691c0f9233c9e)
* Merge branch 'daniel-j-h-lambda-visitor' [view commit](http://github.com/mapbox/variant/commit/9a115c5eb3c09509c70a57b25b283b6e1cbba919)
* Makes variant<Ts...> hashable iff Ts... are hashable, closes #125 [view commit](http://github.com/mapbox/variant/commit/97d0379f0afc87cd74a10be56fbccfa04785f568)
* Implements Pattern Matching for Sum Types via `.match` Member Function. [view commit](http://github.com/mapbox/variant/commit/720c23736bb318937d0f53a413a617ff05040b73)
* Adds Documentation for Readme, resolves #98 [view commit](http://github.com/mapbox/variant/commit/d0266436b18ea3b1f15c8a244985b57a0a2b3770)
* Merge pull request #126 from daniel-j-h/hashable [view commit](http://github.com/mapbox/variant/commit/3c17c37aea0d7e3d9e860b746d54160ec820e6a2)
* Merge pull request #128 from daniel-j-h/match [view commit](http://github.com/mapbox/variant/commit/ed84def128ed99a4b3b1ebcde278be7f761e782e)
* Merge pull request #129 from daniel-j-h/docs [view commit](http://github.com/mapbox/variant/commit/02bd1ac4c07e6db9fe0f01267853e43b41637b74)
## 1.1.3
Released: October 24, 2016
(a5a79a594f39d705a7ef969f54a0743516f0bc6d)
* use C++17 disjunction for no-references and one-convertible tests [view commit](http://github.com/mapbox/variant/commit/2c7ddecdb7ec3b1c1a6bc1797528375e513b7ab0)
* Merge pull request #116 from lightmare/disjunction [view commit](http://github.com/mapbox/variant/commit/8e2f6964157885f1655c1673d65f3aea9b90fe18)
* Update README [view commit](http://github.com/mapbox/variant/commit/aaddee9270e3956cee98cdd7d04aea848d69f5f0)
* expose `using types = std::tuple<Types...>;` - useful for adapting variant to `boost::spirit` (QI,Karma,X3) [view commit](http://github.com/mapbox/variant/commit/e5818212a8f7ef89df0aa76d5244eca78b8dbb8d)
* add `struct adapted_variant_tag;` [view commit](http://github.com/mapbox/variant/commit/173a7457952d0f24e2c55d5eb3ea785ad41639fb)
* Merge pull request #120 from mapbox/types [view commit](http://github.com/mapbox/variant/commit/84a426a31ad3b63c4b8f8d189841e19af48cda40)
* nicer stderr [view commit](http://github.com/mapbox/variant/commit/9b46167f5c42a19a3b66cb92eb60418486b4e424)
* Fix #122 by adding an extra compile check in universal ctor (via @lightmare) + test case [view commit](http://github.com/mapbox/variant/commit/a5a79a594f39d705a7ef969f54a0743516f0bc6d)
## 1.1.2
Released: July 26, 2016
(388376ac9f0102feba2d2122873b08e15a66a879)
* Re-implement type matching logic to reject ambigious conversions [view commit](http://github.com/mapbox/variant/commit/71ac8fdf96e547dca34fe58c5cd8d1dce2ef0dac)
* update tests [view commit](http://github.com/mapbox/variant/commit/8be6a2aa8f85e1455198eff31a577a1fb95e1d46)
* comment out code [view commit](http://github.com/mapbox/variant/commit/075d9636fdfe563b535fa3ba087409f940c018e4)
* Merge pull request #114 from mapbox/strict-conversions [view commit](http://github.com/mapbox/variant/commit/388376ac9f0102feba2d2122873b08e15a66a879)
## 1.1.1
Released: July 18, 2016
(c511b2f34d966c09e02a1b833db33a9a1f9b2196)
## 1.1.0
Released: February 11, 2016
(5aab5df0dc899b484c04ce9c649645787ee0bc5c)
* remove erroneous `;` ref #96 [view commit](http://github.com/mapbox/variant/commit/3f025adbf599d8dd9bfca02d45b37e49a2cae841)
* fix coverage to avoid warning: unit.gcno:version '402*', prefer '406*' [view commit](http://github.com/mapbox/variant/commit/b0ee4729bfc9ea649abe40f279de384df75b79d1)
* fix clang 3.8 compile, try 3.9 [view commit](http://github.com/mapbox/variant/commit/f034d5571de987d14b404dba94e7269ac41fa583)
* remove invalid option for llvm-cov [view commit](http://github.com/mapbox/variant/commit/5f6ed7149d737edf9f1f019beb54cbe5289c474c)
* run coverage with clang 3.5 - fix clang 3.8 build [view commit](http://github.com/mapbox/variant/commit/82bb901b6cc0de8c238a07292163dc7c28a26ce4)
* issue warning `-Wweak-vtables` so this issue is not forgotten (https://github.com/mapbox/variant/issues/95) [view commit](http://github.com/mapbox/variant/commit/35ca16c74f5712afb4f042f45ea64078fa0b630e)
* move headers into include/mapbox folder - closes #99 [view commit](http://github.com/mapbox/variant/commit/f00b24bf65e8af7fddc56ac4a3abe67ed974b0a5)
* Update README.md [view commit](http://github.com/mapbox/variant/commit/13c631a6297d9abc9677c1afc1a3907fec7c16b4)
* Add include directory [view commit](http://github.com/mapbox/variant/commit/7e4a01189bb4050524954b2a88c82de7cb82ea4a)
* Merge branch 'master' into include [view commit](http://github.com/mapbox/variant/commit/9bd902536f533305186aaf70edb2f0b9713f6b6b)
* fix typo [view commit](http://github.com/mapbox/variant/commit/a606e90243dcf145cf06d46e8e30c447f85af178)
* ammend include dir [view commit](http://github.com/mapbox/variant/commit/343831611e60e324e311d67f05da953e357df0a1)
* update remaining `<variant.hpp>` to `<mapbox/variant.hpp>` [view commit](http://github.com/mapbox/variant/commit/bfe0f19dd14dedad9c0a6f1e211e81bd1233564e)
* fix compilation [view commit](http://github.com/mapbox/variant/commit/390229a59703d2467347d62f3e134e67ea6835cc)
* Merge pull request #101 from mapbox/include [view commit](http://github.com/mapbox/variant/commit/1bc46e525a9dec71af28f822e5fc031c1352ad2e)
* Remove Xcode 6 from CI matrix [view commit](http://github.com/mapbox/variant/commit/9b2fc858ccd84509fd7164a4847e7dc95e58d5a5)
* Install boost with mason; eliminate boost::timer dependency [view commit](http://github.com/mapbox/variant/commit/04dc3a46b02d6b8714d00280bb85c88716727862)
* `is<T>()` - add specialisation for recursive_wrapper<T> + update tests (ref #102) [view commit](http://github.com/mapbox/variant/commit/c6ae1ea0acf8c4392a806ad3abd5b11eb3b8a8ce)
* remove expected error string - current implementation emits compiler specific error message e.g [view commit](http://github.com/mapbox/variant/commit/4368d75292ae5149034b59b483fc3f8b3956a839)
* Jamroot - add missing include directory ./test/include for auto_cpu_timer.hpp [view commit](http://github.com/mapbox/variant/commit/7f7470fee6a42c3c68f1fa359a28cf762df385c3)
* Update README.md [view commit](http://github.com/mapbox/variant/commit/8bdad6b6d73844ef8437f004654c0745f0cec96a)
* Fix building with GCC (g++-5.2.0) on OS X (Darwin) (ref #108) [view commit](http://github.com/mapbox/variant/commit/55579f03fba747500b3a105ae73a7dfe6059cfc1)
* Update README.md [view commit](http://github.com/mapbox/variant/commit/33e27ec4c7cc5e1669f2181d13eacdfff15dfb61)
* Merge pull request #109 from mapbox/darwin-build-flags [view commit](http://github.com/mapbox/variant/commit/2f8a4a381f2ad8f9c2d3d068a757a3e0e9994495)
* Add get_unchecked<T>() to enable use with exceptions disabled [view commit](http://github.com/mapbox/variant/commit/434dab048d52e4141146bb95fdabdf7aa62e799b)
* remove unused internal metafunctions [view commit](http://github.com/mapbox/variant/commit/48d60445cca1d71fbebb6456b5d45a18bb9cb3b8)
* add static which<T>() function to get a contained types' which value [view commit](http://github.com/mapbox/variant/commit/74ce146d9b96081965d5fcdf53feefab6199468c)
* Merge branch 'master' into 111-which-constexpr [view commit](http://github.com/mapbox/variant/commit/dca3d967c165de1d0fb3bb5e1c2d6b4bcd76782f)
* Merge branch '111-which-constexpr' [view commit](http://github.com/mapbox/variant/commit/bb8c2d20317191f5228341a87b0c362c4d15be5b)
* variant - yield return type of mapbox::util::get<T> automatically and make interface consistent (addresses #82) [view commit](http://github.com/mapbox/variant/commit/adf0e02bceb74339b8ccc3e9e3f316917cb3cc22)
* uncomment tests ref #82 [view commit](http://github.com/mapbox/variant/commit/37acc5a7caef10d2f52dbdcee71be53b79dda027)
* Merge pull request #110 from mapbox/110-get_unchecked [view commit](http://github.com/mapbox/variant/commit/20e44accb1edf84d944d44f91ed7401198368aae)
* c++ apply formatting [view commit](http://github.com/mapbox/variant/commit/372d7c88fe796a138d0e578328914ac80e5a949a)
* use local HAS_EXCEPTIONS #define (__EXCEPTIONS is g++/clang specific macro) [view commit](http://github.com/mapbox/variant/commit/eedafd31f9fdbaffcb605d8d34a3a3443a4f7a2d)
* update .mason pkgs [view commit](http://github.com/mapbox/variant/commit/b5728ad76e1402c130a9330aa44b6f4b655b13b4)
* fix value_traits to be able to match T, T& and T const& to the direct type stored in variant (ref #112) [view commit](http://github.com/mapbox/variant/commit/b3a002d185afac295486e2ebd6b84c78a2267ba0)
* add test for b3a002d185afac295486e2ebd6b84c78a2267ba0 (ref #112) [view commit](http://github.com/mapbox/variant/commit/c511b2f34d966c09e02a1b833db33a9a1f9b2196)
## 1.0
Released: April 1, 2015
(bf485dfb59aef26f3ef2183d7c8c1111ad97062b)
* Initial commit [view commit](http://github.com/mapbox/variant/commit/9b82890ea11742eafd686f44b8cc7075029dbd7b)
* initial import [view commit](http://github.com/mapbox/variant/commit/bb95645b86a8fe427df9af799ecd139e4fab38ef)
* remove unused boost::static_visitor [view commit](http://github.com/mapbox/variant/commit/2dbc79fdd28c2ad9623c6516069ae616af11cdc5)
* call reserve in boost::variant test and change order [view commit](http://github.com/mapbox/variant/commit/9c1d245388396ac289ccee238b549e48a7916f9e)
* add readme and makefile [view commit](http://github.com/mapbox/variant/commit/5afa5b2e1756dfb0e332f3e11bffdfb33cd31f75)
* makefile fixups [view commit](http://github.com/mapbox/variant/commit/c627c07afc972b3f1bab3ca219416d6e918cd39b)
* turn on more aggressive warnings and fix them where appropriate [view commit](http://github.com/mapbox/variant/commit/20ee8ffe2889f9e0f4974ba2aba028ccd3ce347a)
* -Wsign-compare [view commit](http://github.com/mapbox/variant/commit/12ef94a8c0edb897858b82d0064093e251ac4024)
* remove unneeded headers [view commit](http://github.com/mapbox/variant/commit/eeba005f2f2e287f23661e9dd555e57e0365d22c)
* include <stdexcept> [view commit](http://github.com/mapbox/variant/commit/a7b562eb0ef665b57e3a29a2ff83721bc3f66a03)
* include headers for new/size_t/move [view commit](http://github.com/mapbox/variant/commit/c3963a96aab7d3d2e380652e4268c5d729778a59)
* add sizes target to check object sizes [view commit](http://github.com/mapbox/variant/commit/a1685041726cba13aa9fb728ec4963f3e7872200)
* add tests [view commit](http://github.com/mapbox/variant/commit/df1d00cc50d3b5a1cce203305d52f536f622663c)
* interleave test runs to ensure first run penalty does not murky the results [view commit](http://github.com/mapbox/variant/commit/969a346db6ab41adb66f7b3cbbcc92cd15c3b339)
* add to gitignore [view commit](http://github.com/mapbox/variant/commit/e98fc0736064d3131a25e899420b41276e801a45)
* fix build on ubuntu/g++-4.8 [view commit](http://github.com/mapbox/variant/commit/b8ab4b8c6beb2d0d4bb2afc9fda901c83588d153)
* debug/release builds + profiling [view commit](http://github.com/mapbox/variant/commit/a25c3597deb4d889085bc9492d2cf4f6df847a5a)
* pass release flags to make sizes [view commit](http://github.com/mapbox/variant/commit/23f112ae5e551a731939e8220a16a6c7a29d844b)
* force inlining to reduce final object size (yes **reduce**, with clang++ at least) [view commit](http://github.com/mapbox/variant/commit/c65aa114402e8f7b1d44062ff973f7c807741d06)
* optimization: avoid overhead of function call for invalid type check [view commit](http://github.com/mapbox/variant/commit/cebd6a31e54d84811cccab62991d142aa8aacbad)
* test threaded [view commit](http://github.com/mapbox/variant/commit/5a84ea2f40ccd2cadbc1091fae05b37b1d69c85c)
* 10 threads [view commit](http://github.com/mapbox/variant/commit/c06ebf15268925ef5e0f3ce763db13fd0c27ef2b)
* use perfect forwarding instead of move [view commit](http://github.com/mapbox/variant/commit/cd81aed73c9f1176e26090abc60a9d2467f5d5bf)
* const as const can. also reimplementation of operator= to allow for ADL in swap [view commit](http://github.com/mapbox/variant/commit/33603114129c387c5938287f1839f852a8f3a5f2)
* Merge pull request #1 from artemp/consts_and_fwds [view commit](http://github.com/mapbox/variant/commit/dff07459931e6d76b4eea6092041cbf247e01f64)
* implement comparison operators (==,<) implement operator<< [view commit](http://github.com/mapbox/variant/commit/cb9374b1ebb4c2da42e06af71ca738e9316b0582)
* make THREADS=4 ( we want to test variant not an operating system, better still make it config (TODO)) add simple test for operator== and operator<< ( define VARIANT_LOGICAL_TESTS to enable) [view commit](http://github.com/mapbox/variant/commit/68aa114c5d06a979b8fb31f0cdd2647833544cb1)
* c++ : better names (#2) [view commit](http://github.com/mapbox/variant/commit/48dd83308ebb5ab21c295499948d27d42801b306)
* c++ : better names (#2) [view commit](http://github.com/mapbox/variant/commit/46f40479fd02170b9d4bf48655a6a6a7845d77cc)
* Merge branch 'master' of github.com:artemp/variant [view commit](http://github.com/mapbox/variant/commit/41d5626bee25a4edd36c2e2d05bde46751417baa)
* Added const [view commit](http://github.com/mapbox/variant/commit/9d7afc7362e095acf032b5a3d2057d960157ffcb)
* Fixed var names [view commit](http://github.com/mapbox/variant/commit/7423b70b907b640b477c9675d79b43abb6bf21ed)
* changing const keyword position to 'T const &' [view commit](http://github.com/mapbox/variant/commit/f6677d163a1c1df6d960baa7d0d7983edac95cc3)
* Add -march=native to release build flags, implies -mtune=.. [view commit](http://github.com/mapbox/variant/commit/3ff69626f348da3f6827fc1573e014400d5f6813)
* Merge pull request #7 from artemp/const_correctness_part2 [view commit](http://github.com/mapbox/variant/commit/f8ff1da09fdb3902b39cb6893fda048b2760da68)
* Merge pull request #8 from artemp/architecture-optimizations [view commit](http://github.com/mapbox/variant/commit/4b325da289df3e91bc32d71d4adceb28d3cf8215)
* fix remaining names [view commit](http://github.com/mapbox/variant/commit/2de14db6a431689e07630f42ee18a30101ed11b3)
* add -march=native to Jamroot [view commit](http://github.com/mapbox/variant/commit/8c03239ed115ed51d181ea52a40f0e9e8ec73f42)
* more name fixing ref #2 [view commit](http://github.com/mapbox/variant/commit/f27bd4c7f514f9f646eb0766cfd8f4b7e8f0ed33)
* structs dont have private members [view commit](http://github.com/mapbox/variant/commit/3d0072d34600bbf2fc21bee3db65770cf6796402)
* add pgo option to Makefile [view commit](http://github.com/mapbox/variant/commit/7f4f85e93d09630dd78ba5eb113bb03fb9804979)
* Merge pull request #9 from artemp/classes_and_structs [view commit](http://github.com/mapbox/variant/commit/21ced9474d93a96bb5c7cd527efa5e0ba742e84a)
* Merge pull request #10 from artemp/profile_guided_optimization [view commit](http://github.com/mapbox/variant/commit/0fc8f6b3911b6b6c0dbe72d5c440c7c094add899)
* + implement binary visitation [view commit](http://github.com/mapbox/variant/commit/943b24689b918f13ee1bdeb43111cbdf49139797)
* more realistic test [view commit](http://github.com/mapbox/variant/commit/e481fdb58ac2fec43a18ba119715f539ba000007)
* fix return types [view commit](http://github.com/mapbox/variant/commit/b41b4f69c21e552198310ebaf17c4776e2b4dc1f)
* Return uint64_t [view commit](http://github.com/mapbox/variant/commit/de6db67da287a8f80b956c85a5a6bff2af6cd52f)
* recursive_wrapper init impl [view commit](http://github.com/mapbox/variant/commit/f1c12747d921763288435beb53fbf23eafb6100d)
* Merge branch 'master' of github.com:artemp/variant [view commit](http://github.com/mapbox/variant/commit/49274509129f7f5957cc785b82771ad772fb2478)
* + add static_visitor requirement to ease return_type deduction [view commit](http://github.com/mapbox/variant/commit/80d999a3471b5647a17c14217ef237f8e9f82543)
* fix binary visitor test [view commit](http://github.com/mapbox/variant/commit/87207d76fb81f87b0bbde00c1ed44ec6043103fa)
* use static_visitor as a base class for all visitors [view commit](http://github.com/mapbox/variant/commit/48f78bcd767b99575a5af4aeb0490342e8a2b7a9)
* recursive_wrapper test (work-in-progress) [view commit](http://github.com/mapbox/variant/commit/05af9c4f21eefc91c713bc1e34e0e04b0556519a)
* include recursive_wrapper [view commit](http://github.com/mapbox/variant/commit/cbd9e2cf91e58baebd79ce336ba4b20148f303af)
* update test (FIXME - inteface is very clunky atm and needs more work) [view commit](http://github.com/mapbox/variant/commit/d2cda9a88684d2e7fad3d3527e53f7c64c84378e)
* unwrap recursive_wrapper [view commit](http://github.com/mapbox/variant/commit/bc65cb8d7be23806dc63c2adf03fc8e9b5557f66)
* + const [view commit](http://github.com/mapbox/variant/commit/6e9a10f43eab476d68399d6dcc51a2464cd2f0b8)
* recursive variant test using std::unique_ptr move semantics [view commit](http://github.com/mapbox/variant/commit/5ebf86772daade4490652218e3437d5d0ca7d1de)
* add missing test file [view commit](http://github.com/mapbox/variant/commit/b4abfa58efb676aa86a3dd2dfee04f7e95aee7fd)
* update recursive_wrapper and unique_ptr tests to accept <num-iter> arg [view commit](http://github.com/mapbox/variant/commit/edcb444afc193784cb6237616d68973b36e7920e)
* make test -> make bench [view commit](http://github.com/mapbox/variant/commit/fc80297390285e83394983201473d01edfa17d4c)
* fix compile of test/variant [view commit](http://github.com/mapbox/variant/commit/da417016e6af968cdcea1b2ec9f2023d3ee77cad)
* recursive_wrapper.hpp depends on boost checked delete for the moment [view commit](http://github.com/mapbox/variant/commit/a8d019d470e11eb3a569581ce140397bb6f6e31d)
* shuffle code, all build targets in out/ directory [view commit](http://github.com/mapbox/variant/commit/8e5abd0f14e298b9cc93f7428c2cd21ce732fad9)
* all tests in ./test directory [view commit](http://github.com/mapbox/variant/commit/dadea1f2a7d9c08e1a5979cc5bb824779fb73380)
* add travis [view commit](http://github.com/mapbox/variant/commit/7e775d10774261b5461474013b840fdd899db023)
* fix travis targets [view commit](http://github.com/mapbox/variant/commit/c6bd4f8131f6a58d6d6dfaf3017c8793a0da9819)
* travis: upgrade to gcc-4.8 for c++11 support [view commit](http://github.com/mapbox/variant/commit/84fdc9e2c0701980c083ff3cb8701f3076f10fa6)
* fix a few -Wsign-compare warnings [view commit](http://github.com/mapbox/variant/commit/d3d0704c59dba67f925b707d6c72babadd607ce9)
* fix -Wshadow warning [view commit](http://github.com/mapbox/variant/commit/e19d0e5aca3b4e4a76e29e34352d634b7c495202)
* fix linux compile of binary_visitor_test.cpp [view commit](http://github.com/mapbox/variant/commit/d8df077f29428c55688910d5f96e79b6d351d5e1)
* qualify c++11 int types [view commit](http://github.com/mapbox/variant/commit/62e7165925bfce3e4c11a2fce1cad8d486825613)
* fix #12 [view commit](http://github.com/mapbox/variant/commit/c0593af2c3066d13f30bf15241da313539539f18)
* test with both gcc 4.7 and 4.8 [view commit](http://github.com/mapbox/variant/commit/916719bb38cec2e9f4ff7c3d2ef480734badbb7d)
* Add BSD license [view commit](http://github.com/mapbox/variant/commit/cf7f7bef518d7dd67d74e84bdbaf40a6c5826114)
* add unit tests [view commit](http://github.com/mapbox/variant/commit/0ef558f9607844fa88b1857e6ff993121dd84d71)
* port logical tests to test/unit.cpp - refs #15 [view commit](http://github.com/mapbox/variant/commit/7109df9c4f423b846839240d720de4a89be101c8)
* version, starting at 0.1.0 [view commit](http://github.com/mapbox/variant/commit/e5c89779e59bc22571ce5beb27a823b94b2be786)
* try building on windows with gyp [view commit](http://github.com/mapbox/variant/commit/b97876a2e5ddaf8931cecd36b5a649fb3e1eb420)
* call gyp_main.py [view commit](http://github.com/mapbox/variant/commit/24cddfbc76c713046b130158c72231bd827d4a23)
* be explicit about config and platform [view commit](http://github.com/mapbox/variant/commit/bc80b31f8c4afd469f65046cfc3fe18bba95fbd3)
* also test building with gyp on travis [view commit](http://github.com/mapbox/variant/commit/51eda4f439c24223a964fe25d077ff1efa27dce0)
* try 'any cpu' [view commit](http://github.com/mapbox/variant/commit/41056fa781bf3c6a79182db338595b44d6370c25)
* put msbuild on path [view commit](http://github.com/mapbox/variant/commit/948a6ccb89ae2b4a3682805519b585bf573763a9)
* appveyor: try building 32 bit [view commit](http://github.com/mapbox/variant/commit/1b89ab841021d28da193e3b1fab27269651bdc17)
* Update README.md [view commit](http://github.com/mapbox/variant/commit/011b5125a4bb139f794bb37080bd33cae6519f7c)
* + it breaks builds for me - I have 'using clang ..' in $(boost-dir)/tools/build/v2/user-config.jam where it should be. [view commit](http://github.com/mapbox/variant/commit/1b2fc49bbc7e76bbaf2c64ea44cb3f287d5948a5)
* ```apply_visitor``` interface not-compatible with boost::apply_visitor (by changing args order) wasn't smart [view commit](http://github.com/mapbox/variant/commit/67ac560672e5ea7bf99a4a823b5259ccd6d1bd5d)
* fix syntax [view commit](http://github.com/mapbox/variant/commit/002ccdcde4aacfcc6b67ad4981c05402514c09f1)
* windows support [view commit](http://github.com/mapbox/variant/commit/64f8fb4473f3ef6f7117dc02f02a20645e415b72)
* update readme [view commit](http://github.com/mapbox/variant/commit/20f26eceebef717a0ee759b42bfe939a95874807)
* appeveyor: try building for just x86 [view commit](http://github.com/mapbox/variant/commit/b3f8117d05071981106b7d1fe15405a318d3c1df)
* fix setting of msbuild_toolset for c++11 support [view commit](http://github.com/mapbox/variant/commit/d0603d41a8597089c0c1cd099ebb8bcf5e1414d3)
* Add vcbuild.bat [view commit](http://github.com/mapbox/variant/commit/bb12b87574fcdaa7bdca6c1529d442eab2d52b97)
* remove sizeof checks since they are implementation depedenent [view commit](http://github.com/mapbox/variant/commit/f5af06c20329a0c762af9420a3ae2e3d22c02c91)
* comment failing test on windows [view commit](http://github.com/mapbox/variant/commit/7d4dc68667659e7585d28f743509956e92759255)
* appveyor: re-enable matrix [view commit](http://github.com/mapbox/variant/commit/6dbc0546bdab9e8dc291eb08d2e6dce13a0dcfe8)
* add <utility> to be include order agnostic [view commit](http://github.com/mapbox/variant/commit/9be8c519c67ef2ec8d3b5a7b736f0a8b870b43ed)
* Merge pull request #16 from DennisOSRM/master [view commit](http://github.com/mapbox/variant/commit/b27a14e98d9eadf2aabd628a602f9e4a5fcb0a5f)
* move detail tests + add initial comments (@artemp, please review) [view commit](http://github.com/mapbox/variant/commit/ea25e84aeec16588857ac83c1241d34a5df4adac)
* fix typo in code comment [skip ci] [view commit](http://github.com/mapbox/variant/commit/b773421f5868315eccd504204f32ee8c02e78dc6)
* rename internal id to index, add tests [view commit](http://github.com/mapbox/variant/commit/390e2315b97bbc71aa575d98bacc1ed760d0aa4a)
* Merge pull request #18 from mapbox/type_index [view commit](http://github.com/mapbox/variant/commit/046296a95c9d34224c23c843bc8bd6d502f81b47)
* modify tests slightly to output num_iter ((3+2)-4) [view commit](http://github.com/mapbox/variant/commit/602eceb753751ae30cd5ca7a25d3337179ba6b5e)
* boost is uneeded for unit.cpp tests [view commit](http://github.com/mapbox/variant/commit/e1de3d78e8827d5b6819cc91b430429a46093c95)
* enable ctor's for valid types at compile time [view commit](http://github.com/mapbox/variant/commit/31e3fd96fe4f86d9ac5ac53d6e3e07605307eb5c)
* [travis] multi-os [view commit](http://github.com/mapbox/variant/commit/2f1e36d25f152c31cc3b2673946a8670dd189e74)
* fix path to boost/variant.hpp on linux [view commit](http://github.com/mapbox/variant/commit/b31579c99042d36672fa9eefb09bcdb01e1bcc0a)
* move variant and friends into mapbox namespace for easy integration [view commit](http://github.com/mapbox/variant/commit/df55ab6ef48d1a28c58e409d71b3ee4b416cdf31)
* fix namespace [view commit](http://github.com/mapbox/variant/commit/397ed9c90bc55bbf2f3331f43a707789869d064a)
* inline accessors/setters [view commit](http://github.com/mapbox/variant/commit/2ebabd9b6cb1b95605b01708899498ac70b84201)
* default ctor : initialise with default contructed first type in parameters pack [view commit](http://github.com/mapbox/variant/commit/4d038f1462698c0977e14eacfd9abeb8da95c852)
* add default ctor test [view commit](http://github.com/mapbox/variant/commit/d7fa62b52f771f0d194441b5889409e792eff740)
* c++11 : use type aliases instead of typedefs [view commit](http://github.com/mapbox/variant/commit/03eb4c7d287b72eb43d2b6456ef38437c8c0ac34)
* converting operator= [view commit](http://github.com/mapbox/variant/commit/0eed7c3c1477e0673d379336b0745606d2780d8f)
* avoid wrapped object copying [view commit](http://github.com/mapbox/variant/commit/f7648ba392aea548fe0d583ceee2048ad57e2f54)
* fix move ctor + housekeeping [view commit](http://github.com/mapbox/variant/commit/6aee8c4a7543e0d38f64a07d67aaf394bea704d9)
* add <string> [view commit](http://github.com/mapbox/variant/commit/82cc6e2335b377b5e61e9a3bc974e619658ab515)
* remove unused header [view commit](http://github.com/mapbox/variant/commit/74425f135a6b7cdd49d86d2dd84cf9bdfe9154c2)
* uncomment to test single threaded [view commit](http://github.com/mapbox/variant/commit/7296d18458e2dbfc7ddb39f0fe5b96962c264dc6)
* fix bug : assign correct index (in reverse order of args) e.g first type is sizeof...(Types) - 1 [view commit](http://github.com/mapbox/variant/commit/7eb748eb65729c2d91a7c4f16e5bd56eb3038bdd)
* fix default ctor unit test [view commit](http://github.com/mapbox/variant/commit/03af9e421b36e17a9b873cb24347f6bad7c3dc6d)
* [gyp] fix typo in Windows release targets [view commit](http://github.com/mapbox/variant/commit/2d8ca78704f69c6498a0e689222588275c8f33aa)
* add non-const visitor interface (#22) [view commit](http://github.com/mapbox/variant/commit/54d07c9d336c989fe3c1231bbb7f6465ebc68da2)
* add unary_visitor test [view commit](http://github.com/mapbox/variant/commit/3b31c34368613c4cd101e6f7ee9677c2c7b6b75e)
* support implicit type convertions [view commit](http://github.com/mapbox/variant/commit/724a40baec3ded142c631b66521502840d8d183f)
* update to use recursive_wrapper<T> -> T conversions [view commit](http://github.com/mapbox/variant/commit/7e609812f15cbf41fab978fd3222c6029a5b67eb)
* unit test : update to use latest variant impl [view commit](http://github.com/mapbox/variant/commit/d1392fa431b5b5dac99cdb8b937ec05e13d98847)
* Mapbox name without the inner uppercase B. [view commit](http://github.com/mapbox/variant/commit/4e11d41723af714895c90cb8b9798527c946b2b4)
* Fix typo in comment. [view commit](http://github.com/mapbox/variant/commit/01509c76c30bea7a6bfffd0e59f9bbdbae8f1026)
* Formatting fixes. [view commit](http://github.com/mapbox/variant/commit/cfd7d991b23b2ecc659d18f22a2f78a05074450c)
* Use formatting "TYPE const&". [view commit](http://github.com/mapbox/variant/commit/9253ffdda65bd41ed21f9328a20a335fa0f5d582)
* Remove superfluous and inconsistent whitespace. [view commit](http://github.com/mapbox/variant/commit/d855ba8672fc5f439594325663899564f0632c94)
* Add comments for closing namespaces. [view commit](http://github.com/mapbox/variant/commit/3c2d662abb352bd429777251ddc613e751e49123)
* Merge branch 'joto-master' [view commit](http://github.com/mapbox/variant/commit/49e9f351a7a8d5615f8fb5ae2d4840042fc95bcc)
* Fix typos, whitespace and test tags. [view commit](http://github.com/mapbox/variant/commit/a12326984f323d10648115d94ace0b510d097b06)
* Add tests for implicit conversion and exceptions for wrong types. [view commit](http://github.com/mapbox/variant/commit/12c70938b00215ce86e48657d60a650dbfd8966e)
* Add test for printer visitor. [view commit](http://github.com/mapbox/variant/commit/fd470a6fde0941407a74c3d544c009eac0579e4f)
* Add test case for issue #25. [view commit](http://github.com/mapbox/variant/commit/74f1c5d9b02788fb9524ae674d43fdf07671d9cc)
* fix appveyor link in readme [view commit](http://github.com/mapbox/variant/commit/d49f82efb7689b8bc67be30633dd7f41b54f2e5a)
* Remove the need for the static_visitor class. [view commit](http://github.com/mapbox/variant/commit/e9283622a33231500c8cc3d1f27358d431c1e8a2)
* msvs: also define _DEBUG for debug builds [view commit](http://github.com/mapbox/variant/commit/c4bb359f883b568a88d5be8b3e4ce5c45626d71f)
* [appveyor] more debug flags [view commit](http://github.com/mapbox/variant/commit/b852c8d386e59a145a6b684d036ee7e327d0efe2)
* [appveyor][gyp] correct msvs_settings usage [view commit](http://github.com/mapbox/variant/commit/1f707864e37c305779e3398006b20e2ee5f14866)
* customize release builds [view commit](http://github.com/mapbox/variant/commit/4661a3c06b3738c7564c18474577d4faece6613a)
* [gyp][windows] add exception handling/rtti [view commit](http://github.com/mapbox/variant/commit/02556c9c317834ad3f05aa88dacc072ad9a63c99)
* use numeric values in valid range to avoid overflowing [view commit](http://github.com/mapbox/variant/commit/854c5a7a115d92b67698f3654d915edd483456b9)
* Removed wrong comments. [view commit](http://github.com/mapbox/variant/commit/8b6c0b34b76144d697ede0f386f1ea2f9c6ae2d1)
* Removed test case. [view commit](http://github.com/mapbox/variant/commit/08a7e04e3cf3ebd54e289201b1bd3d85225248ee)
* allow explicit un-initilised variant ctor [view commit](http://github.com/mapbox/variant/commit/d99139d4dee3ae4fa2b7465000d08fc5f5907e82)
* add boost::variant compatible accessors [view commit](http://github.com/mapbox/variant/commit/2afd3415cc28b8b7184e2750ac90e739c078b335)
* more verbose output to test script [view commit](http://github.com/mapbox/variant/commit/0c8b6b736788718ed28a0676cdb0b390249d5540)
* variant : make operator<< stricter to avoid unexpected instantiations [view commit](http://github.com/mapbox/variant/commit/76027798360405d910f8af9d6ae873fa5905be13)
* Add details on advantages of Mapbox variant [view commit](http://github.com/mapbox/variant/commit/a5ee02b2aacb0109725c611beaafc27dce89c12d)
* remove unneeded header [view commit](http://github.com/mapbox/variant/commit/73da70737f0e55b2276173ca923eb91bd8ae4f32)
* less debug info in release mode [view commit](http://github.com/mapbox/variant/commit/607ed1344f8117000e03da0b8bfb9268a1f826ee)
* rough cut of an optional type [view commit](http://github.com/mapbox/variant/commit/9badbd0fa37863240cf678be61116003d345a20a)
* add operator* and a static assert against reference types [view commit](http://github.com/mapbox/variant/commit/1141292eeed4a95f3e54c85e98f9ded180f84f32)
* Merge pull request #30 from DennisOSRM/optional [view commit](http://github.com/mapbox/variant/commit/32f971794c643d11f5bf374caef44cee295cdf7d)
* remove some whitespace [view commit](http://github.com/mapbox/variant/commit/f4bcf3ff733acbd4a798f1e9a5f80d5422bc9b79)
* explicit operator bool() const noexcept [view commit](http://github.com/mapbox/variant/commit/c77d98b3e8d06714ed0b0c288cd9ad457f2708c4)
* rename none_t -> none_type, move to private member of optional [view commit](http://github.com/mapbox/variant/commit/43e2e9a943555c09ce6ffb9c825a64bff229a3a6)
* remove instantiation of none_type as per @kkaefer's suggestion [view commit](http://github.com/mapbox/variant/commit/7242396fb5468defba37afd03e7a633075fa51ce)
* remove none_type and its complicated typedef from detail namespace, add it as private member class to optional [view commit](http://github.com/mapbox/variant/commit/c5f720515ad21fe3913fc841ea427ebdd1fa4c68)
* guard against self-assignment [view commit](http://github.com/mapbox/variant/commit/10a039c78b58857f8793dae3b0359cf1d6fb11ef)
* add unit tests for optional type [view commit](http://github.com/mapbox/variant/commit/607c6332cb96261a43a16fa94aea5d034ae58aac)
* Merge pull request #31 from mapbox/optional [view commit](http://github.com/mapbox/variant/commit/4cdd805a04175248b221753a0974de15c8f5b397)
* reformat optional.hpp to be more legible and less linty [view commit](http://github.com/mapbox/variant/commit/54e1dfe7631207da3f6a2bbc895c5240592ea5ea)
* universal-references: template <typename T> variant(T && val) {} it turned out we don't need a separate converting copy ctor (fixes windows compiler) [view commit](http://github.com/mapbox/variant/commit/82df4ed9cd2a8335c7e50b913f827216604dab07)
* Merge pull request #32 from mapbox/universal-references [view commit](http://github.com/mapbox/variant/commit/804fb6f370a35eaea3e273ebfcb2f92ef7379e91)
* use std::forward<T> for perfect forwarding (via @DennisOSRM) [view commit](http://github.com/mapbox/variant/commit/eb995158362307cea98e36eb782dd4ae63593d0f)
* fix assignment of optionals, adds a unit test [view commit](http://github.com/mapbox/variant/commit/f69f317069523cb6994fa9d594240deeb537753c)
* Merge pull request #33 from mapbox/fix_assignment_operator [view commit](http://github.com/mapbox/variant/commit/c56af229af98b71ba8ef637f3237cab828f0ec14)
* readme improvements [view commit](http://github.com/mapbox/variant/commit/5b8972b6ebcd095f35b810c43639785235218bbd)
* Merge branch 'master' into result_of [view commit](http://github.com/mapbox/variant/commit/4900027d0f66a7c701e22c667e92ce7b7521a73c)
* cast lhs to rhs type to avoid signed/unsigned comparisons warnings [view commit](http://github.com/mapbox/variant/commit/17074a3de539256ccab3871033df33c9d387dcbf)
* attempting to fix travis [view commit](http://github.com/mapbox/variant/commit/4fb9bd65ac4a204f8721f9528df9c14907a151f9)
* Merge branch 'master' into result_of [view commit](http://github.com/mapbox/variant/commit/fbcc50b57e58460e0cd90a232673271eff72311c)
* make deriving from static_visitor and providing result_type an option [view commit](http://github.com/mapbox/variant/commit/76ab6d4aa54664d7f8849695896ca57f4984bed0)
* Merge branch 'result_of' [view commit](http://github.com/mapbox/variant/commit/3cc2d708e0552ba4ebce11d4d67f798813f15aa2)
* fix automatic return_type calculation - ref #35 [view commit](http://github.com/mapbox/variant/commit/00ab88117ed25f78cdca2faa00beea0061271e85)
* test either g++ or clang++ [view commit](http://github.com/mapbox/variant/commit/199b3eca054075319a1978f09bdd77f9ff42e681)
* try adding code coverage / coveralls upload [view commit](http://github.com/mapbox/variant/commit/11e65282e335ed4a50bf261d21b8194230787ed8)
* fix bash syntax [view commit](http://github.com/mapbox/variant/commit/2fbfcd33998992df4d77f329e7a75c864616d0ab)
* add recursive wrapper to coverage [view commit](http://github.com/mapbox/variant/commit/f87a1cf10d62814d3bf4e72ac260a92e483ffb25)
* move operator<< into separate header <variant_io.hpp> [view commit](http://github.com/mapbox/variant/commit/24dcab23c4f70e54838e4a32a228aba8045ae17b)
* add coverage report [view commit](http://github.com/mapbox/variant/commit/89f8a41a4da81c2a01d39f83cf52e61997ce76ba)
* clean up coverage files in test directory too [skip ci] [view commit](http://github.com/mapbox/variant/commit/7dfdfa271e43780aff640852a632e88443b6fe32)
* add get<T>() overloads for when T is stored in recursive_wrapper<T> also makes get<T>() a compile time error where T is not in Types... (ref #24) [view commit](http://github.com/mapbox/variant/commit/36f1e12f66570f2a1f04535dc0ac0485d48e2bbe)
* update unit test to match c64c74775a80474f2012c1a49ab2865e3666107a [view commit](http://github.com/mapbox/variant/commit/c117592337cc20c238d4ce9f9d8847aff0cd55ab)
* add which() method returning zero based index of stored T in Types... for boost::variant() compatibility [view commit](http://github.com/mapbox/variant/commit/3b02ca0e3ab1a36dd6ec9138e7f93eb3176ae5f7)
* add reference_wrapper test [view commit](http://github.com/mapbox/variant/commit/5a2d5c5f292ae2d6128d02e7ee2b3b3d72facfc2)
* remove boost variant header [view commit](http://github.com/mapbox/variant/commit/c53422fb2d4e44b7e276fcde65498b603f429a2f)
* add support for 'unwrapping' std::reference_wrapper<T> and accessing std::reference_wrapper<T>::type through get<T>() + update test [view commit](http://github.com/mapbox/variant/commit/587519521ae0d9a24f997ab2dff77f13309aa5d2)
* pass F (functor) by ref/const ref [view commit](http://github.com/mapbox/variant/commit/2e0ce4a86d0b9d0ff9855838349fb599b15a274a)
* pass by const ref in 'apply_const' [view commit](http://github.com/mapbox/variant/commit/a3014f54651b71e25d81fbeaf99f29d63c625703)
* Revert "pass by const ref in 'apply_const'" [view commit](http://github.com/mapbox/variant/commit/e031c53d0c876ecf2b9d4a6e0a5383bd4169df71)
* Revert "pass F (functor) by ref/const ref" [view commit](http://github.com/mapbox/variant/commit/bf485dfb59aef26f3ef2183d7c8c1111ad97062b)

View File

@ -1,62 +0,0 @@
# Unofficial and incomplete build file using Boost build system.
# You should use make unless you know what you are doing.
import os ;
local boost_dir = [ os.environ BOOST_DIR ] ;
if ! $(boost_dir)
{
boost_dir = "/usr/local" ;
}
#using clang : : ;
local cxx_std = [ os.environ CXX_STD ] ;
if ! $(cxx_std)
{
cxx_std = c++11 ;
}
project mapbox_variant
: requirements
<cxxflags>-std=$(cxx_std)
<include>$(boost_dir)/include
<include>include
<include>test/include
<variant>release:<cxxflags>-march=native
<threading>single:<define>SINGLE_THREADED
: default-build
<variant>release
<optimization>speed
<threading>single
;
rule exe-test ( name : reqs * : deps * )
{
exe $(name)
: test/$(name).cpp
: $(reqs)
: $(deps)
;
explicit $(name) ;
}
exe-test bench_variant
: <variant>release:<cxxflags>-Wweak-vtables
;
exe-test binary_visitor_test ;
exe-test recursive_wrapper_test ;
exe-test unique_ptr_test ;
exe-test reference_wrapper_test ;
exe-test lambda_overload_test ;
exe-test hashable_test ;
install out
: bench_variant
binary_visitor_test
unique_ptr_test
reference_wrapper_test
lambda_overload_test
hashable_test
;

View File

@ -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.

View File

@ -1,23 +0,0 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@ -1,157 +0,0 @@
MASON = .mason/mason
BOOST_VERSION = 1.62.0
CXX := $(CXX)
CXX_STD ?= c++11
BOOST_ROOT = $(shell $(MASON) prefix boost $(BOOST_VERSION))
BOOST_FLAGS = -isystem $(BOOST_ROOT)/include/
RELEASE_FLAGS = -O3 -DNDEBUG -march=native -DSINGLE_THREADED -fvisibility-inlines-hidden -fvisibility=hidden
DEBUG_FLAGS = -O0 -g -DDEBUG -fno-inline-functions -fno-omit-frame-pointer -fPIE
WARNING_FLAGS = -Werror -Wall -Wextra -pedantic \
-Wformat=2 -Wsign-conversion -Wshadow -Wunused-parameter
COMMON_FLAGS = -std=$(CXX_STD)
COMMON_FLAGS += $(WARNING_FLAGS)
CXXFLAGS := $(CXXFLAGS)
LDFLAGS := $(LDFLAGS)
export BUILDTYPE ?= Release
OS := $(shell uname -s)
ifeq ($(OS), Linux)
EXTRA_FLAGS = -pthread
endif
ifeq ($(OS), Darwin)
OSX_OLDEST_SUPPORTED ?= 10.7
# we need to explicitly ask for libc++ otherwise the
# default will flip back to libstdc++ for mmacosx-version-min < 10.9
EXTRA_FLAGS = -stdlib=libc++ -mmacosx-version-min=$(OSX_OLDEST_SUPPORTED)
endif
ifeq ($(BUILDTYPE),Release)
FINAL_CXXFLAGS := $(COMMON_FLAGS) $(RELEASE_FLAGS) $(CXXFLAGS) $(EXTRA_FLAGS)
else
FINAL_CXXFLAGS := $(COMMON_FLAGS) $(DEBUG_FLAGS) $(CXXFLAGS) $(EXTRA_FLAGS)
endif
ALL_HEADERS = $(shell find include/mapbox/ '(' -name '*.hpp' ')')
all: out/bench-variant out/unique_ptr_test out/unique_ptr_test out/recursive_wrapper_test out/binary_visitor_test out/lambda_overload_test out/hashable_test
$(MASON):
git submodule update --init .mason
mason_packages/headers/boost: $(MASON)
$(MASON) install boost $(BOOST_VERSION)
./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/$(BUILDTYPE)/tests
out/bench-variant-debug: Makefile mason_packages/headers/boost test/bench_variant.cpp
mkdir -p ./out
$(CXX) -o out/bench-variant-debug test/bench_variant.cpp -I./include -isystem test/include $(FINAL_CXXFLAGS) $(LDFLAGS) $(BOOST_FLAGS)
out/bench-variant: Makefile mason_packages/headers/boost test/bench_variant.cpp
mkdir -p ./out
$(CXX) -o out/bench-variant test/bench_variant.cpp -I./include -isystem test/include $(FINAL_CXXFLAGS) $(LDFLAGS) $(BOOST_FLAGS)
out/unique_ptr_test: Makefile mason_packages/headers/boost test/unique_ptr_test.cpp
mkdir -p ./out
$(CXX) -o out/unique_ptr_test test/unique_ptr_test.cpp -I./include -isystem test/include $(FINAL_CXXFLAGS) $(LDFLAGS) $(BOOST_FLAGS)
out/recursive_wrapper_test: Makefile mason_packages/headers/boost test/recursive_wrapper_test.cpp
mkdir -p ./out
$(CXX) -o out/recursive_wrapper_test test/recursive_wrapper_test.cpp -I./include -isystem test/include $(FINAL_CXXFLAGS) $(LDFLAGS) $(BOOST_FLAGS)
out/binary_visitor_test: Makefile mason_packages/headers/boost test/binary_visitor_test.cpp
mkdir -p ./out
$(CXX) -o out/binary_visitor_test test/binary_visitor_test.cpp -I./include -isystem test/include $(FINAL_CXXFLAGS) $(LDFLAGS) $(BOOST_FLAGS)
out/lambda_overload_test: Makefile mason_packages/headers/boost test/lambda_overload_test.cpp
mkdir -p ./out
$(CXX) -o out/lambda_overload_test test/lambda_overload_test.cpp -I./include -isystem test/include $(FINAL_CXXFLAGS) $(LDFLAGS) $(BOOST_FLAGS)
out/hashable_test: Makefile mason_packages/headers/boost test/hashable_test.cpp
mkdir -p ./out
$(CXX) -o out/hashable_test test/hashable_test.cpp -I./include -isystem test/include $(FINAL_CXXFLAGS) $(LDFLAGS) $(BOOST_FLAGS)
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.o: Makefile test/unit.cpp
mkdir -p ./out
$(CXX) -c -o $@ test/unit.cpp -isystem test/include $(FINAL_CXXFLAGS)
out/%.o: test/t/%.cpp Makefile $(ALL_HEADERS)
mkdir -p ./out
$(CXX) -c -o $@ $< -Iinclude -isystem test/include $(FINAL_CXXFLAGS)
out/unit: out/unit.o \
out/binary_visitor_1.o \
out/binary_visitor_2.o \
out/binary_visitor_3.o \
out/binary_visitor_4.o \
out/binary_visitor_5.o \
out/binary_visitor_6.o \
out/issue21.o \
out/issue122.o \
out/mutating_visitor.o \
out/optional.o \
out/recursive_wrapper.o \
out/sizeof.o \
out/unary_visitor.o \
out/variant.o \
out/variant_alternative.o \
out/nothrow_move.o \
out/visitor_result_type.o \
mkdir -p ./out
$(CXX) -o $@ $^ $(LDFLAGS)
test: out/unit
./out/unit
coverage:
mkdir -p ./out
$(CXX) -o out/cov-test --coverage test/unit.cpp test/t/*.cpp -I./include -isystem test/include $(FINAL_CXXFLAGS) $(LDFLAGS)
sizes: Makefile
mkdir -p ./out
@$(CXX) -o ./out/our_variant_hello_world.out include/mapbox/variant.hpp -I./include $(FINAL_CXXFLAGS) && ls -lah ./out/our_variant_hello_world.out
@$(CXX) -o ./out/boost_variant_hello_world.out $(BOOST_ROOT)/include/boost/variant.hpp -I./include $(FINAL_CXXFLAGS) $(BOOST_FLAGS) && ls -lah ./out/boost_variant_hello_world.out
@$(CXX) -o ./out/our_variant_hello_world ./test/our_variant_hello_world.cpp -I./include $(FINAL_CXXFLAGS) && ls -lah ./out/our_variant_hello_world
@$(CXX) -o ./out/boost_variant_hello_world ./test/boost_variant_hello_world.cpp -I./include $(FINAL_CXXFLAGS) $(BOOST_FLAGS) && ls -lah ./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
rm -f *.gcda *.gcno
pgo: out Makefile
$(CXX) -o out/bench-variant test/bench_variant.cpp -I./include $(FINAL_CXXFLAGS) $(LDFLAGS) $(BOOST_FLAGS) -pg -fprofile-generate
./test-variant 500000 >/dev/null 2>/dev/null
$(CXX) -o out/bench-variant test/bench_variant.cpp -I./include $(FINAL_CXXFLAGS) $(LDFLAGS) $(BOOST_FLAGS) -fprofile-use
.PHONY: sizes test

View File

@ -1,248 +0,0 @@
# Mapbox Variant
An header-only alternative to `boost::variant` for C++11 and C++14
[![Build Status](https://secure.travis-ci.org/mapbox/variant.svg)](https://travis-ci.org/mapbox/variant)
[![Build status](https://ci.appveyor.com/api/projects/status/v9tatx21j1k0fcgy)](https://ci.appveyor.com/project/Mapbox/variant)
[![Coverage Status](https://coveralls.io/repos/mapbox/variant/badge.svg?branch=master&service=github)](https://coveralls.io/r/mapbox/variant?branch=master)
## Introduction
Variant's basic building blocks are:
- `variant<Ts...>` - a type-safe representation for sum-types / discriminated unions
- `recursive_wrapper<T>` - a helper type to represent recursive "tree-like" variants
- `apply_visitor(visitor, myVariant)` - to invoke a custom visitor on the variant's underlying type
- `get<T>()` - a function to directly unwrap a variant's underlying type
- `.match([](Type){})` - a variant convenience member function taking an arbitrary number of lambdas creating a visitor behind the scenes and applying it to the variant
### Basic Usage - HTTP API Example
Suppose you want to represent a HTTP API response which is either a JSON result or an error:
```c++
struct Result {
Json object;
};
struct Error {
int32_t code;
string message;
};
```
You can represent this at type level using a variant which is either an `Error` or a `Result`:
```c++
using Response = variant<Error, Result>;
Response makeRequest() {
return Error{501, "Not Implemented"};
}
Response ret = makeRequest();
```
To see which type the `Response` holds you pattern match on the variant unwrapping the underlying value:
```c++
ret.match([] (Result r) { print(r.object); },
[] (Error e) { print(e.message); });
```
Instead of using the variant's convenience `.match` pattern matching function you can create a type visitor functor and use `apply_visitor` manually:
```c++
struct ResponseVisitor {
void operator()(Result r) const {
print(r.object);
}
void operator()(Error e) const {
print(e.message);
}
};
ResponseVisitor visitor;
apply_visitor(visitor, ret);
```
In both cases the compiler makes sure you handle all types the variant can represent at compile.
### Recursive Variants - JSON Example
[JSON](http://www.json.org/) consists of types `String`, `Number`, `True`, `False`, `Null`, `Array` and `Object`.
```c++
struct String { string value; };
struct Number { double value; };
struct True { };
struct False { };
struct Null { };
struct Array { vector<?> values; };
struct Object { unordered_map<string, ?> values; };
```
This works for primitive types but how do we represent recursive types such as `Array` which can hold multiple elements and `Array` itself, too?
For these use cases Variant provides a `recursive_wrapper` helper type which lets you express recursive Variants.
```c++
struct String { string value; };
struct Number { double value; };
struct True { };
struct False { };
struct Null { };
// Forward declarations only
struct Array;
struct Object;
using Value = variant<String, Number, True, False, Null, recursive_wrapper<Array>, recursive_wrapper<Object>>;
struct Array {
vector<Value> values;
};
struct Object {
unordered_map<string, Value> values;
};
```
For walking the JSON representation you can again either create a `JSONVisitor`:
```c++
struct JSONVisitor {
void operator()(Null) const {
print("null");
}
// same for all other JSON types
};
JSONVisitor visitor;
apply_visitor(visitor, json);
```
Or use the convenience `.match` pattern matching function:
```c++
json.match([] (Null) { print("null"); },
...);
```
To summarize: use `recursive_wrapper` to represent recursive "tree-like" representations:
```c++
struct Empty { };
struct Node;
using Tree = variant<Empty, recursive_wrapper<Node>>;
struct Node {
uint64_t value;
}
```
### Advanced Usage Tips
Creating type aliases for variants is a great way to reduce repetition.
Keep in mind those type aliases are not checked at type level, though.
We recommend creating a new type for all but basic variant usage:
```c++
// the compiler can't tell the following two apart
using APIResult = variant<Error, Result>;
using FilesystemResult = variant<Error, Result>;
// new type
struct APIResult : variant<Error, Result> {
using Base = variant<Error, Result>;
using Base::Base;
}
```
## 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
(Numbers from an older version of Mapbox variant.)
## Goals
Mapbox `variant` has been a very valuable, lightweight alternative for apps
that can use c++11 or c++14 but that do not want a boost dependency.
Mapbox `variant` has also been useful in apps that do depend on boost, like
mapnik, to help (slightly) with compile times and to majorly lessen dependence
on boost in core headers. The original goal and near term goal is to maintain
external API compatibility with `boost::variant` such that Mapbox `variant`
can be a "drop in". At the same time the goal is to stay minimal: Only
implement the features that are actually needed in existing software. So being
an "incomplete" implementation is just fine.
Currently Mapbox variant doesn't try to be API compatible with the upcoming
variant standard, because the standard is not finished and it would be too much
work. But we'll revisit this decision in the future if needed.
If Mapbox variant is not for you, have a look at [these other
implementations](doc/other_implementations.md).
Want to know more about the upcoming standard? Have a look at our
[overview](doc/standards_effort.md).
Most modern high-level languages provide ways to express sum types directly.
If you're curious have a look at Haskell's pattern matching or Rust's and Swift's enums.
## Depends
- Compiler supporting `-std=c++11` or `-std=c++14`
Tested with:
- g++-4.7
- g++-4.8
- g++-4.9
- g++-5.2
- clang++-3.5
- clang++-3.6
- clang++-3.7
- clang++-3.8
- clang++-3.9
- Visual Studio 2015
## Unit Tests
On Unix systems compile and run the unit tests with `make test`.
On Windows run `scripts/build-local.bat`.
## Limitations
- The `variant` can not hold references (something like `variant<int&>` is
not possible). You might want to try `std::reference_wrapper` instead.
## Deprecations
- The included implementation of `optional` is deprecated and will be removed
in a future version. See [issue #64](https://github.com/mapbox/variant/issues/64).
- Old versions of the code needed visitors to derive from `static_visitor`.
This is not needed any more and marked as deprecated. The `static_visitor`
class will be removed in future versions.
## Benchmarks
make bench
## Check object sizes
make sizes /path/to/boost/variant.hpp

View File

@ -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

View File

@ -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" ]
}
}
}
}
}]
]
}

View File

@ -1,15 +0,0 @@
# Other implementations of variant and optional
These are some other implementations of `variant` and/or `optional` types.
They are not necessarily compatible with this implementation. This is an
incomplete list.
* [Boost Variant](http://www.boost.org/doc/libs/1_59_0/doc/html/variant.html) and [Boost Optional](http://www.boost.org/doc/libs/1_59_0/libs/optional/doc/html/index.html)
* [Eggs Variant](http://eggs-cpp.github.io/variant/) by [Agustín Bergé](http://talesofcpp.fusionfenix.com/)
* [anthonyw/variant](https://bitbucket.org/anthonyw/variant) (implementation of P0110R0)
* [JasonL9000/cppcon14](https://github.com/JasonL9000/cppcon14)
* [tomilov/variant](https://github.com/tomilov/variant)
* [akrzemi1/Optional](https://github.com/akrzemi1/Optional)
* [mpark/variant](https://github.com/mpark/variant)

View File

@ -1,28 +0,0 @@
# Standards efforts
A `variant` type is on planned for inclusion in the C++ Standard, probably in
C++17. Current working papers are (list extracted from [2015 working group
papers](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/)):
* 2015-09-28: Variant design review. [P0086R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0086r0.pdf)
* 2015-09-28: Variant: a type-safe union without undefined behavior (v2) [P0087R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0087r0.pdf)
* 2015-09-27: Variant: a type-safe union that is rarely invalid (v5) [P0088R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0088r0.pdf)
* 2015-09-24: Simply a Strong Variant [P0093R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0093r0.html)
* 2015-09-24: Simply a Basic Variant [P0094R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0094r0.html)
* 2015-09-24: The Case for a Language Based Variant [P0096R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0095r0.html)
* 2015-09-25: Implementing the strong guarantee for variant<> assignment [P0110R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0110r0.html)
* 2015-09-24: Homogeneous interface for variant, any and optional (Revision 1) [P0032R1](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0032r1.pdf)
Last state can be seen from
[The Variant Saga: A happy ending?](https://isocpp.org/blog/2015/11/the-variant-saga-a-happy-ending).
The `optional` type is also on the way into the standard. The papers are:
* 2013-10-03: A proposal to add a utility class to represent optional objects (Revision 5) [N3793](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3793.html)
* 2014-01-18: Working Draft, Technical Specification on C++ Extensions for Library Fundamentals [N3848](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3848.html)
## Older Papers
* Older working drafts are: N4218 (rev 1), N4516 (rev 2), N4450 (rev 3), and [N4542](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4542.pdf) (rev 4). They have been split into P0086 (general design discussions) and P0087 and P0088 (containing two competing? specs).
* 2015-07-28: Variant: Discriminated Union with Value Semantics [P0080R0](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0080r0.pdf) An alternative proposal to N4542.

View File

@ -1,74 +0,0 @@
#ifndef MAPBOX_UTIL_OPTIONAL_HPP
#define MAPBOX_UTIL_OPTIONAL_HPP
#pragma message("This implementation of optional is deprecated. See https://github.com/mapbox/variant/issues/64.")
#include <type_traits>
#include <utility>
#include <mapbox/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{}; }
}; // class optional
} // namespace util
} // namespace mapbox
#endif // MAPBOX_UTIL_OPTIONAL_HPP

View File

@ -1,122 +0,0 @@
#ifndef MAPBOX_UTIL_RECURSIVE_WRAPPER_HPP
#define MAPBOX_UTIL_RECURSIVE_WRAPPER_HPP
// Based on variant/recursive_wrapper.hpp from boost.
//
// Original license:
//
// Copyright (c) 2002-2003
// Eric Friedman, Itay Maman
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <cassert>
#include <utility>
namespace mapbox {
namespace util {
template <typename T>
class recursive_wrapper
{
T* p_;
void assign(T const& rhs)
{
this->get() = rhs;
}
public:
using type = T;
/**
* Default constructor default initializes the internally stored value.
* For POD types this means nothing is done and the storage is
* uninitialized.
*
* @throws std::bad_alloc if there is insufficient memory for an object
* of type T.
* @throws any exception thrown by the default constructur of T.
*/
recursive_wrapper()
: p_(new T){}
~recursive_wrapper() noexcept { delete p_; }
recursive_wrapper(recursive_wrapper const& operand)
: p_(new T(operand.get())) {}
recursive_wrapper(T const& operand)
: p_(new T(operand)) {}
recursive_wrapper(recursive_wrapper&& operand)
: p_(new T(std::move(operand.get()))) {}
recursive_wrapper(T&& operand)
: p_(new T(std::move(operand))) {}
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;
}
T& get()
{
assert(p_);
return *get_pointer();
}
T const& get() const
{
assert(p_);
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(); }
}; // class recursive_wrapper
template <typename T>
inline void swap(recursive_wrapper<T>& lhs, recursive_wrapper<T>& rhs) noexcept
{
lhs.swap(rhs);
}
} // namespace util
} // namespace mapbox
#endif // MAPBOX_UTIL_RECURSIVE_WRAPPER_HPP

File diff suppressed because it is too large Load Diff

View File

@ -1,85 +0,0 @@
#ifndef VARIANT_CAST_HPP
#define VARIANT_CAST_HPP
#include <type_traits>
namespace mapbox {
namespace util {
namespace detail {
template <class T>
class static_caster
{
public:
template <class V>
T& operator()(V& v) const
{
return static_cast<T&>(v);
}
};
template <class T>
class dynamic_caster
{
public:
using result_type = T&;
template <class V>
T& operator()(V& v, typename std::enable_if<!std::is_polymorphic<V>::value>::type* = nullptr) const
{
throw std::bad_cast();
}
template <class V>
T& operator()(V& v, typename std::enable_if<std::is_polymorphic<V>::value>::type* = nullptr) const
{
return dynamic_cast<T&>(v);
}
};
template <class T>
class dynamic_caster<T*>
{
public:
using result_type = T*;
template <class V>
T* operator()(V& v, typename std::enable_if<!std::is_polymorphic<V>::value>::type* = nullptr) const
{
return nullptr;
}
template <class V>
T* operator()(V& v, typename std::enable_if<std::is_polymorphic<V>::value>::type* = nullptr) const
{
return dynamic_cast<T*>(&v);
}
};
}
template <class T, class V>
typename detail::dynamic_caster<T>::result_type
dynamic_variant_cast(V& v)
{
return mapbox::util::apply_visitor(detail::dynamic_caster<T>(), v);
}
template <class T, class V>
typename detail::dynamic_caster<const T>::result_type
dynamic_variant_cast(const V& v)
{
return mapbox::util::apply_visitor(detail::dynamic_caster<const T>(), v);
}
template <class T, class V>
T& static_variant_cast(V& v)
{
return mapbox::util::apply_visitor(detail::static_caster<T>(), v);
}
template <class T, class V>
const T& static_variant_cast(const V& v)
{
return mapbox::util::apply_visitor(detail::static_caster<const T>(), v);
}
}
}
#endif // VARIANT_CAST_HPP

View File

@ -1,45 +0,0 @@
#ifndef MAPBOX_UTIL_VARIANT_IO_HPP
#define MAPBOX_UTIL_VARIANT_IO_HPP
#include <iosfwd>
#include <mapbox/variant.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;
}
} // namespace util
} // namespace mapbox
#endif // MAPBOX_UTIL_VARIANT_IO_HPP

View File

@ -1,43 +0,0 @@
#ifndef MAPBOX_UTIL_VARIANT_VISITOR_HPP
#define MAPBOX_UTIL_VARIANT_VISITOR_HPP
#include <utility>
namespace mapbox {
namespace util {
template <typename... Fns>
struct visitor;
template <typename Fn>
struct visitor<Fn> : Fn
{
using Fn::operator();
template<typename T>
visitor(T&& fn) : Fn(std::forward<T>(fn)) {}
};
template <typename Fn, typename... Fns>
struct visitor<Fn, Fns...> : Fn, visitor<Fns...>
{
using Fn::operator();
using visitor<Fns...>::operator();
template<typename T, typename... Ts>
visitor(T&& fn, Ts&&... fns)
: Fn(std::forward<T>(fn))
, visitor<Fns...>(std::forward<Ts>(fns)...) {}
};
template <typename... Fns>
visitor<typename std::decay<Fns>::type...> make_visitor(Fns&&... fns)
{
return visitor<typename std::decay<Fns>::type...>
(std::forward<Fns>(fns)...);
}
} // namespace util
} // namespace mapbox
#endif // MAPBOX_UTIL_VARIANT_VISITOR_HPP

View File

@ -1,10 +0,0 @@
{
"name": "variant",
"version": "1.1.6",
"description": "C++11/C++14 variant",
"main": "./package.json",
"repository" : {
"type" : "git",
"url" : "git://github.com/mapbox/variant.git"
}
}

View File

@ -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 --quiet --depth 1 https://chromium.googlesource.com/external/gyp.git deps/gyp
CALL deps\gyp\gyp.bat variant.gyp --depth=. ^
-f msvs ^
-G msvs_version=2015 ^
--generator-output=build
SET MSBUILD_PLATFORM=%platform%
IF /I "%MSBUILD_PLATFORM%" == "x86" SET MSBUILD_PLATFORM=Win32
msbuild ^
build\variant.sln ^
/nologo ^
/toolsversion:14.0 ^
/p:PlatformToolset=v140 ^
/p:Configuration=%configuration% ^
/p:Platform=%MSBUILD_PLATFORM%
build\"%configuration%"\tests.exe

View File

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

View File

@ -1,49 +0,0 @@
#!/bin/sh
#
# Try to compile all programs in the test/compilation_failure directory.
# Compilation must fail and the error message must match the pattern in the
# corresponding .pattern file.
#
DIR="test/compilation_failure"
CXX=${CXX:-clang++}
if [ `uname -s` = "Darwin" ]; then
CXXFLAGS="$CXXFLAGS -stdlib=libc++"
fi
error_msg() {
if [ ! -z "$1" ]; then
printf 'output was:\n=======\n%s\n=======\n' "$1"
fi
}
exit_code=0
for test_code in $DIR/*.cpp; do
name=`basename $test_code .cpp`
result=`${CXX} -std=c++11 -c -o /dev/null -I./include ${CXXFLAGS} ${test_code} 2>&1`
status=$?
if [ $status = 1 ]; then
expected=`sed -n -e '/@EXPECTED/s/.*: \+//p' ${test_code}`
if echo $result | grep -q "$expected"; then
echo "$name [OK]"
else
echo "$name [FAILED - wrong error message]"
echo "Expected error message: $expected"
error_msg "$result"
exit_code=1
fi
elif [ $status = 0 ]; then
echo "$name [FAILED - compile was successful]"
error_msg "$result"
exit_code=1
else
echo "$name [FAILED - unknown error in compile]"
error_msg "$result"
exit_code=1
fi
done
exit ${exit_code}

View File

@ -1,184 +0,0 @@
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <memory>
#include <string>
#include <thread>
#include <utility>
#include <vector>
#include "auto_cpu_timer.hpp"
#include <boost/variant.hpp>
#include <mapbox/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
{
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
{
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: ";
auto_cpu_timer t;
run_variant_test(NUM_RUNS);
}
{
std::cerr << "boost variant: ";
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: ";
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: ";
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;
}

View File

@ -1,138 +0,0 @@
#include <algorithm>
#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include <mapbox/variant.hpp>
#include <mapbox/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
{
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()
{
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;
}

View File

@ -1,20 +0,0 @@
#include <boost/variant.hpp>
#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;
}

View File

@ -1,21 +0,0 @@
// @EXPECTED: First type in variant must be default constructible to allow default construction of variant
#include <mapbox/variant.hpp>
// Checks that the first type in a variant must be default constructible to
// make the variant default constructible.
struct no_def_constructor
{
int value;
no_def_constructor() = delete;
no_def_constructor(int v) : value(v) {}
};
int main()
{
mapbox::util::variant<no_def_constructor> x;
}

View File

@ -1,10 +0,0 @@
// @EXPECTED: Template parameter type list of variant can not be empty
#include <mapbox/variant.hpp>
// Empty type list should not work.
int main()
{
mapbox::util::variant<> x;
}

View File

@ -1,10 +0,0 @@
// @EXPECTED:
#include <mapbox/variant.hpp>
int main()
{
mapbox::util::variant<int> x;
mapbox::util::variant<double> y;
x == y;
}

View File

@ -1,9 +0,0 @@
// @EXPECTED: no matching .*\<function for call to .*\<get\>
#include <mapbox/variant.hpp>
int main()
{
mapbox::util::variant<int, double> x;
x.get<std::string>();
}

View File

@ -1,9 +0,0 @@
// @EXPECTED:
#include <mapbox/variant.hpp>
int main()
{
mapbox::util::variant<int, double> x;
x.is<std::string>();
}

View File

@ -1,23 +0,0 @@
// @EXPECTED: no matching function for call to .*\<apply_visitor\>
#include <mapbox/variant.hpp>
struct mutating_visitor
{
mutating_visitor(int val)
: val_(val) {}
void operator()(int& val) const
{
val = val_;
}
int val_;
};
int main()
{
const mapbox::util::variant<int> var(123);
const mutating_visitor visitor(456);
mapbox::util::apply_visitor(visitor, var);
}

View File

@ -1,8 +0,0 @@
// @EXPECTED: Variant can not hold reference types
#include <mapbox/variant.hpp>
int main()
{
mapbox::util::variant<double, int&, long> x{mapbox::util::no_init()};
}

View File

@ -1,158 +0,0 @@
#include <cstddef>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <string>
#include <unordered_set>
#include <utility>
#include <mapbox/variant.hpp>
using namespace mapbox::util;
void test_singleton()
{
using V = variant<int>;
V singleton = 5;
if (std::hash<V>{}(singleton) != std::hash<int>{}(5))
{
std::cerr << "Expected variant hash to be the same as hash of its value\n";
std::exit(EXIT_FAILURE);
}
}
void test_default_hashable()
{
using V = variant<int, double, std::string>;
V var;
// Check int hashes
var = 1;
if (std::hash<V>{}(var) != std::hash<int>{}(1))
{
std::cerr << "Expected variant hash to be the same as hash of its value\n";
std::exit(EXIT_FAILURE);
}
// Check double hashes
var = 23.4;
if (std::hash<V>{}(var) != std::hash<double>{}(23.4))
{
std::cerr << "Expected variant hash to be the same as hash of its value\n";
std::exit(EXIT_FAILURE);
}
// Check string hashes
var = std::string{"Hello, World!"};
if (std::hash<V>{}(var) != std::hash<std::string>{}("Hello, World!"))
{
std::cerr << "Expected variant hash to be the same as hash of its value\n";
std::exit(EXIT_FAILURE);
}
}
struct Hashable
{
static const constexpr auto const_hash = 5;
};
namespace std {
template <>
struct hash<Hashable>
{
std::size_t operator()(const Hashable&) const noexcept
{
return Hashable::const_hash;
}
};
}
void test_custom_hasher()
{
using V = variant<int, Hashable, double>;
V var;
var = Hashable{};
if (std::hash<V>{}(var) != Hashable::const_hash)
{
std::cerr << "Expected variant hash to be the same as hash of its value\n";
std::exit(EXIT_FAILURE);
}
}
void test_hashable_in_container()
{
using V = variant<int, std::string, double>;
// won't compile if V is not Hashable
std::unordered_set<V> vs;
vs.insert(1);
vs.insert(2.3);
vs.insert("4");
}
struct Empty
{
};
struct Node;
using Tree = variant<Empty, recursive_wrapper<Node>>;
struct Node
{
Node(Tree left_, Tree right_) : left(std::move(left_)), right(std::move(right_)) {}
Tree left = Empty{};
Tree right = Empty{};
};
namespace std {
template <>
struct hash<Empty>
{
std::size_t operator()(const Empty&) const noexcept
{
return 3;
}
};
template <>
struct hash<Node>
{
std::size_t operator()(const Node& n) const noexcept
{
return 5 + std::hash<Tree>{}(n.left) + std::hash<Tree>{}(n.right);
}
};
}
void test_recursive_hashable()
{
Tree tree = Node{Node{Empty{}, Empty{}}, Empty{}};
if (std::hash<Tree>{}(tree) != ((5 + (5 + (3 + 3))) + 3))
{
std::cerr << "Expected variant hash to be the same as hash of its value\n";
std::exit(EXIT_FAILURE);
}
}
int main()
{
test_singleton();
test_default_hashable();
test_custom_hasher();
test_hashable_in_container();
test_recursive_hashable();
}

View File

@ -1,16 +0,0 @@
#pragma once
#include <chrono>
#include <iostream>
struct auto_cpu_timer {
std::chrono::time_point<std::chrono::high_resolution_clock> start;
auto_cpu_timer() : start(std::chrono::high_resolution_clock::now()) {
}
~auto_cpu_timer() {
auto end = std::chrono::high_resolution_clock::now();
std::chrono::microseconds elapsed =
std::chrono::duration_cast<std::chrono::microseconds>(end - start);
std::cerr << elapsed.count() << "us" << std::endl;
}
};

File diff suppressed because it is too large Load Diff

View File

@ -1,282 +0,0 @@
#include <iostream>
#include <vector>
#include <mapbox/variant.hpp>
#include <mapbox/variant_visitor.hpp>
#if __cplusplus >= 201402L
#define HAS_CPP14_SUPPORT
#endif
using namespace mapbox::util;
template <typename T>
struct tag
{
static void dump(const char* prefix)
{
std::cout << prefix << ": " << typeid(tag<T>).name() << std::endl;
}
};
template <typename Left, typename Right>
using Either = mapbox::util::variant<Left, Right>;
struct Response
{
};
struct Error
{
};
void test_lambda_overloads()
{
Either<Error, Response> rv;
rv = Response{};
auto visitor = make_visitor([](Response) { std::cout << "Response\n"; }, //
[](Error) { std::cout << "Error\n"; }); //
apply_visitor(visitor, rv);
}
void test_lambda_overloads_capture()
{
Either<Error, Response> rv;
rv = Error{};
int ok = 0;
int err = 0;
auto visitor = make_visitor([&](Response) { ok += 1; }, //
[&](Error) { err += 1; }); //
apply_visitor(visitor, rv);
std::cout << "Got " << ok << " ok, " << err << " err" << std::endl;
}
void test_singleton_variant()
{
variant<int> singleton;
apply_visitor(make_visitor([](int) {}), singleton);
}
// See #180
struct test_call_nonconst_member_visitor
{
template <typename T>
void operator() (T & obj) const
{
tag<decltype(obj)>::dump("test_call_nonconst_member: visitor");
obj.foo();
}
};
void test_call_nonconst_member()
{
struct object
{
void foo() { val = 42;}
int val = 0;
};
variant<object> v = object{};
apply_visitor(test_call_nonconst_member_visitor{}, v);
#ifdef HAS_CPP14_SUPPORT
apply_visitor([](auto& obj)
{
tag<decltype(obj)>::dump("test_call_nonconst_member: lambda");
obj.foo();
}, v);
#endif
}
void test_lambda_overloads_sfinae()
#ifdef HAS_CPP14_SUPPORT
{
variant<int, float, std::vector<int>> var;
auto visitor = make_visitor([](auto range) -> decltype(std::begin(range), void()) {
for (auto each : range)
std::cout << each << ' '; },
[](auto x) -> decltype(std::cout << x, void()) {
std::cout << x << std::endl;
});
var = 1;
apply_visitor(visitor, var);
var = 2.f;
apply_visitor(visitor, var);
var = std::vector<int>{4, 5, 6};
apply_visitor(visitor, var);
}
#else
{
}
#endif
void test_match_singleton()
{
variant<int> singleton = 5;
singleton.match([](int) {});
auto lambda = [](int) {};
singleton.match(lambda);
}
void test_match_overloads()
{
Either<Error, Response> rv;
rv = Response{};
rv.match([](Response) { std::cout << "Response\n"; }, //
[](Error) { std::cout << "Error\n"; }); //
}
void test_match_overloads_capture()
{
Either<Error, Response> rv;
rv = Error{};
int ok = 0;
int err = 0;
rv.match([&](Response) { ok += 1; }, //
[&](Error) { err += 1; }); //
std::cout << "Got " << ok << " ok, " << err << " err" << std::endl;
}
struct MovableOnly
{
MovableOnly() = default;
MovableOnly(MovableOnly&&) = default;
MovableOnly& operator=(MovableOnly&&) = default;
};
struct MovableCopyable
{
MovableCopyable() = default;
MovableCopyable(MovableCopyable&&) = default;
MovableCopyable& operator=(MovableCopyable&&) = default;
MovableCopyable(const MovableCopyable&) = default;
MovableCopyable& operator=(const MovableCopyable&) = default;
};
void test_match_overloads_init_capture()
#ifdef HAS_CPP14_SUPPORT
{
Either<Error, Response> rv;
rv = Error{};
rv.match([p = MovableOnly{}](auto&&) {});
{
auto lambda = [p = MovableCopyable{}](auto&&) {};
rv.match(lambda);
rv.match([p = MovableOnly{}](Response) { std::cout << "Response\n"; },
[p = MovableOnly{}](Error) { std::cout << "Error\n"; });
}
{
auto lambda = [](Error) { std::cout << "Error\n"; };
rv.match([p = MovableOnly{}](Response) { std::cout << "Response\n"; },
lambda);
rv.match(lambda,
[p = MovableOnly{}](Response) { std::cout << "Response\n"; });
}
}
#else
{
}
#endif
// See #140
void test_match_overloads_otherwise()
#ifdef HAS_CPP14_SUPPORT
{
struct Center
{
};
struct Indent
{
};
struct Justify
{
};
struct None
{
};
using Properties = mapbox::util::variant<Center, Indent, Justify, None>;
Properties props = Justify{};
props.match([&](Center) { std::cout << "Center\n"; }, //
[&](Indent) { std::cout << "Indent\n"; }, //
[&](auto&&) { std::cout << "Otherwise\n"; }); //
}
#else
{
}
#endif
template <typename>
struct Moveable
{
Moveable() = default; // Default constructible
Moveable(const Moveable&) = delete; // Disable copy ctor
Moveable& operator=(const Moveable&) = delete; // Disable copy assign op
Moveable(Moveable&&) = default; // Enable move ctor
Moveable& operator=(Moveable&&) = default; // Enable move assign op
};
void test_match_move_out_of_variant()
{
// Distinguishable at type level
using T1 = Moveable<struct Tag1>;
using T2 = Moveable<struct Tag2>;
using T3 = mapbox::util::recursive_wrapper<int>;
mapbox::util::variant<T1, T2> v = T1{};
std::move(v).match([](T1&&) {}, // Consume T1 by value
[](T2&&) {}); // Consume T2 by value
mapbox::util::variant<T3, T2> w = T2{};
std::move(w).match([](int&&) {}, // Consume unwrapped int
[](T2&&) {}); // Consume T2 by value
}
int main()
{
test_lambda_overloads();
test_singleton_variant();
test_call_nonconst_member();
test_lambda_overloads_capture();
test_lambda_overloads_sfinae();
test_match_singleton();
test_match_overloads();
test_match_overloads_capture();
test_match_overloads_init_capture();
test_match_overloads_otherwise();
test_match_move_out_of_variant();
}
#undef HAS_CPP14_SUPPORT

View File

@ -1,20 +0,0 @@
#include <mapbox/variant.hpp>
#include <stdexcept>
struct check
{
template <typename T>
void operator()(T const& val) const
{
if (val != 0) throw std::runtime_error("invalid");
}
};
int main()
{
typedef mapbox::util::variant<bool, int, double> variant_type;
variant_type v(0);
mapbox::util::apply_visitor(check(), v);
return 0;
}

View File

@ -1,124 +0,0 @@
#include <cstdlib>
#include <iostream>
#include <string>
#include <typeinfo>
#include <utility>
#include "auto_cpu_timer.hpp"
#include <mapbox/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
{
template <typename T>
void operator()(T const& val) const
{
std::cerr << val << ":" << typeid(T).name() << std::endl;
}
};
struct test
{
template <typename T>
std::string operator()(T const& obj) const
{
return std::string("TYPE_ID=") + typeid(obj).name();
}
};
struct calculator
{
public:
int operator()(int value) const
{
return value;
}
int operator()(binary_op<add> const& binary) const
{
return util::apply_visitor(*this, binary.left) + util::apply_visitor(*this, binary.right);
}
int operator()(binary_op<sub> const& binary) const
{
return util::apply_visitor(*this, binary.left) - util::apply_visitor(*this, binary.right);
}
};
struct to_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(*this, binary.left) + std::string("+") + util::apply_visitor(*this, binary.right);
}
std::string operator()(binary_op<sub> const& binary) const
{
return util::apply_visitor(*this, binary.left) + std::string("-") + util::apply_visitor(*this, 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(test::binary_op<test::add>(2, 3));
test::expression result(test::binary_op<test::sub>(std::move(sum), 4));
std::cerr << "TYPE OF RESULT-> " << util::apply_visitor(test::test(), result) << std::endl;
int total = 0;
{
auto_cpu_timer t;
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;
}

View File

@ -1,79 +0,0 @@
#include <cstdlib>
#include <functional>
#include <iostream>
#include <type_traits>
#include <typeinfo>
#include <utility>
#include <vector>
#include <mapbox/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(";
bool first = true;
for (auto const& pt : line)
{
if (!first) std::cerr << ",";
std::cerr << pt.x << " " << pt.y;
if (first) first = false;
}
std::cerr << ")" << std::endl;
}
template <typename T>
void operator()(T const& val) const
{
std::cerr << typeid(T).name() << std::endl;
}
};
}
int main()
{
std::cerr << sizeof(test::polygon) << std::endl;
std::cerr << sizeof(test::variant) << std::endl;
test::point pt(123, 456);
test::variant var = 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::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;
}

View File

@ -1,7 +0,0 @@
#include <mapbox/variant.hpp>
#define NAME_EXT " i-d"
using variant_type = mapbox::util::variant<int, double>;
#include "binary_visitor_impl.hpp"

View File

@ -1,7 +0,0 @@
#include <mapbox/variant.hpp>
#define NAME_EXT " b-i-d"
using variant_type = mapbox::util::variant<bool, int, double>;
#include "binary_visitor_impl.hpp"

View File

@ -1,7 +0,0 @@
#include <mapbox/variant.hpp>
#define NAME_EXT " i-d-b"
using variant_type = mapbox::util::variant<int, double, bool>;
#include "binary_visitor_impl.hpp"

View File

@ -1,7 +0,0 @@
#include <mapbox/variant.hpp>
#define NAME_EXT " b-i-d-c"
using variant_type = mapbox::util::variant<bool, int, double, char>;
#include "binary_visitor_impl.hpp"

View File

@ -1,7 +0,0 @@
#include <mapbox/variant.hpp>
#define NAME_EXT " b-i-c-d-i"
using variant_type = mapbox::util::variant<bool, int, char, double, int>;
#include "binary_visitor_impl.hpp"

View File

@ -1,7 +0,0 @@
#include <mapbox/variant.hpp>
#define NAME_EXT " b-i-i-d-c-u"
using variant_type = mapbox::util::variant<bool, int, int, double, char, short int>;
#include "binary_visitor_impl.hpp"

View File

@ -1,204 +0,0 @@
#include <type_traits>
#include "catch.hpp"
#include <mapbox/variant_io.hpp>
struct add_visitor
{
add_visitor() {}
template <typename A, typename B>
double operator()(A a, B b) const
{
return a + b;
}
};
TEST_CASE("const binary visitor works on const variants" NAME_EXT, "[visitor][binary visitor]")
{
const variant_type a{7};
const variant_type b = 3;
const variant_type c{7.1};
const variant_type d = 2.9;
const add_visitor v;
REQUIRE(mapbox::util::apply_visitor(v, a, b) == Approx(10));
REQUIRE(mapbox::util::apply_visitor(v, c, d) == Approx(10));
REQUIRE(mapbox::util::apply_visitor(v, a, c) == Approx(14.1));
REQUIRE(mapbox::util::apply_visitor(v, a, d) == Approx(9.9));
REQUIRE(mapbox::util::apply_visitor(v, b, a) == Approx(10));
REQUIRE(mapbox::util::apply_visitor(v, d, c) == Approx(10));
REQUIRE(mapbox::util::apply_visitor(v, c, a) == Approx(14.1));
REQUIRE(mapbox::util::apply_visitor(v, d, a) == Approx(9.9));
}
TEST_CASE("non-const binary visitor works on const variants" NAME_EXT, "[visitor][binary visitor]")
{
const variant_type a = 7;
const variant_type b = 3;
const variant_type c = 7.1;
const variant_type d = 2.9;
add_visitor v;
REQUIRE(mapbox::util::apply_visitor(v, a, b) == Approx(10));
REQUIRE(mapbox::util::apply_visitor(v, c, d) == Approx(10));
REQUIRE(mapbox::util::apply_visitor(v, a, c) == Approx(14.1));
REQUIRE(mapbox::util::apply_visitor(v, a, d) == Approx(9.9));
REQUIRE(mapbox::util::apply_visitor(v, b, a) == Approx(10));
REQUIRE(mapbox::util::apply_visitor(v, d, c) == Approx(10));
REQUIRE(mapbox::util::apply_visitor(v, c, a) == Approx(14.1));
REQUIRE(mapbox::util::apply_visitor(v, d, a) == Approx(9.9));
}
TEST_CASE("const binary visitor works on non-const variants" NAME_EXT, "[visitor][binary visitor]")
{
variant_type a = 7;
variant_type b = 3;
variant_type c = 7.1;
variant_type d = 2.9;
const add_visitor v;
REQUIRE(mapbox::util::apply_visitor(v, a, b) == Approx(10));
REQUIRE(mapbox::util::apply_visitor(v, c, d) == Approx(10));
REQUIRE(mapbox::util::apply_visitor(v, a, c) == Approx(14.1));
REQUIRE(mapbox::util::apply_visitor(v, a, d) == Approx(9.9));
REQUIRE(mapbox::util::apply_visitor(v, b, a) == Approx(10));
REQUIRE(mapbox::util::apply_visitor(v, d, c) == Approx(10));
REQUIRE(mapbox::util::apply_visitor(v, c, a) == Approx(14.1));
REQUIRE(mapbox::util::apply_visitor(v, d, a) == Approx(9.9));
}
TEST_CASE("non-const binary visitor works on non-const variants" NAME_EXT, "[visitor][binary visitor]")
{
variant_type a = 7;
variant_type b = 3;
variant_type c = 7.1;
variant_type d = 2.9;
add_visitor v;
REQUIRE(mapbox::util::apply_visitor(v, a, b) == Approx(10));
REQUIRE(mapbox::util::apply_visitor(v, c, d) == Approx(10));
REQUIRE(mapbox::util::apply_visitor(v, a, c) == Approx(14.1));
REQUIRE(mapbox::util::apply_visitor(v, a, d) == Approx(9.9));
REQUIRE(mapbox::util::apply_visitor(v, b, a) == Approx(10));
REQUIRE(mapbox::util::apply_visitor(v, d, c) == Approx(10));
REQUIRE(mapbox::util::apply_visitor(v, c, a) == Approx(14.1));
REQUIRE(mapbox::util::apply_visitor(v, d, a) == Approx(9.9));
}
TEST_CASE("rvalue binary visitor works on const variants" NAME_EXT, "[visitor][binary visitor]")
{
const variant_type a = 7;
const variant_type b = 3;
const variant_type c = 7.1;
const variant_type d = 2.9;
REQUIRE(mapbox::util::apply_visitor(add_visitor{}, a, b) == Approx(10));
REQUIRE(mapbox::util::apply_visitor(add_visitor{}, c, d) == Approx(10));
REQUIRE(mapbox::util::apply_visitor(add_visitor{}, a, c) == Approx(14.1));
REQUIRE(mapbox::util::apply_visitor(add_visitor{}, a, d) == Approx(9.9));
REQUIRE(mapbox::util::apply_visitor(add_visitor{}, b, a) == Approx(10));
REQUIRE(mapbox::util::apply_visitor(add_visitor{}, d, c) == Approx(10));
REQUIRE(mapbox::util::apply_visitor(add_visitor{}, c, a) == Approx(14.1));
REQUIRE(mapbox::util::apply_visitor(add_visitor{}, d, a) == Approx(9.9));
}
struct sum_mul_visitor
{
double sum;
sum_mul_visitor() : sum(0.0) {}
template <typename A, typename B>
double operator()(A a, B b)
{
double m = a * b;
sum += m;
return m;
}
};
TEST_CASE("mutable binary visitor works" NAME_EXT, "[visitor][binary visitor]")
{
const variant_type a = 2;
const variant_type b = 3;
const variant_type c = 0.1;
const variant_type d = 0.2;
sum_mul_visitor v;
REQUIRE(mapbox::util::apply_visitor(v, a, b) == Approx(6));
REQUIRE(mapbox::util::apply_visitor(v, c, d) == Approx(0.02));
REQUIRE(mapbox::util::apply_visitor(v, a, c) == Approx(0.2));
REQUIRE(mapbox::util::apply_visitor(v, a, d) == Approx(0.4));
REQUIRE(v.sum == Approx(6.62));
REQUIRE(mapbox::util::apply_visitor(v, b, a) == Approx(6));
REQUIRE(mapbox::util::apply_visitor(v, d, c) == Approx(0.02));
REQUIRE(mapbox::util::apply_visitor(v, c, a) == Approx(0.2));
REQUIRE(mapbox::util::apply_visitor(v, d, a) == Approx(0.4));
}
struct swap_visitor
{
swap_visitor(){};
template <typename A, typename B>
void operator()(A& a, B& b) const
{
using T = typename std::common_type<A, B>::type;
T tmp = a;
a = static_cast<A>(b);
b = static_cast<B>(tmp);
}
};
TEST_CASE("static mutating visitor on mutable variants works" NAME_EXT, "[visitor][binary visitor]")
{
variant_type a = 2;
variant_type b = 3;
variant_type c = 0.1;
variant_type d = 0.2;
const swap_visitor v;
SECTION("swap a and b")
{
mapbox::util::apply_visitor(v, a, b);
REQUIRE(a.get<int>() == 3);
REQUIRE(b.get<int>() == 2);
}
SECTION("swap c and d")
{
mapbox::util::apply_visitor(v, c, d);
REQUIRE(c.get<double>() == Approx(0.2));
REQUIRE(d.get<double>() == Approx(0.1));
}
SECTION("swap a and c")
{
mapbox::util::apply_visitor(v, a, c);
REQUIRE(a.get<int>() == 0);
REQUIRE(c.get<double>() == Approx(2.0));
}
SECTION("swap c and a")
{
mapbox::util::apply_visitor(v, c, a);
REQUIRE(a.get<int>() == 0);
REQUIRE(c.get<double>() == Approx(2.0));
}
}

View File

@ -1,20 +0,0 @@
#include "catch.hpp"
#include <mapbox/variant.hpp>
#include <mapbox/variant_io.hpp>
// https://github.com/mapbox/variant/issues/122
struct X
{
template <typename ValueType>
X(const ValueType&) {}
};
TEST_CASE("Correctly choose appropriate constructor", "[variant]")
{
mapbox::util::variant<X, int> a{123};
decltype(a) b(a);
REQUIRE(a.which() == b.which());
}

View File

@ -1,52 +0,0 @@
#include "catch.hpp"
#include <mapbox/variant.hpp>
#include <mapbox/variant_io.hpp>
// https://github.com/mapbox/variant/issues/21
static int count;
struct t1
{
int value;
t1(t1 const& rhs)
: value(rhs.value)
{
++count;
}
t1(int v) : value(v)
{
++count;
}
~t1()
{
--count;
}
};
struct t2
{
int value;
t2(int v) : value(v)
{ // constructor fails
throw std::runtime_error("fail");
}
};
TEST_CASE("set() works cleanly even if the constructor throws ", "[variant]")
{
using variant_type = mapbox::util::variant<t1, t2>;
count = 0;
{
t1 obj{42};
variant_type v = obj;
REQUIRE(v.is<t1>());
REQUIRE(v.get<t1>().value == 42);
REQUIRE_THROWS(v.set<t2>(13));
}
REQUIRE(count == 0);
}

View File

@ -1,36 +0,0 @@
#include "catch.hpp"
#include <mapbox/variant.hpp>
#include <mapbox/variant_io.hpp>
#include <string>
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 visitation", "[visitor][unary visitor]")
{
mapbox::util::variant<int, double, std::string> var(123);
REQUIRE(var.get<int>() == 123);
int val = 456;
const mutating_visitor<int> visitor(val);
mapbox::util::apply_visitor(visitor, var);
REQUIRE(var.get<int>() == 456);
}

View File

@ -1,66 +0,0 @@
#include <typeinfo>
#include <utility>
#include <mapbox/variant.hpp>
using namespace mapbox;
namespace test {
struct t_noexcept_true_1 {
t_noexcept_true_1(t_noexcept_true_1&&) noexcept = default;
t_noexcept_true_1& operator=(t_noexcept_true_1&&) noexcept = default;
};
struct t_noexcept_true_2 {
t_noexcept_true_2(t_noexcept_true_2&&) noexcept = default;
t_noexcept_true_2& operator=(t_noexcept_true_2&&) noexcept = default;
};
struct t_noexcept_false_1 {
t_noexcept_false_1(t_noexcept_false_1&&) noexcept(false) {}
t_noexcept_false_1& operator=(t_noexcept_false_1&&) noexcept(false) { return *this; }
};
using should_be_no_throw_copyable = util::variant<t_noexcept_true_1, t_noexcept_true_2>;
static_assert(std::is_nothrow_move_assignable<should_be_no_throw_copyable>::value,
"variants with no-throw move assignable types should be "
"no-throw move nothrow assignable");
using should_be_no_throw_assignable = util::variant<t_noexcept_true_1, t_noexcept_true_2>;
static_assert(std::is_nothrow_move_constructible<should_be_no_throw_assignable>::value,
"variants with no-throw move assignable types should be "
"no-throw move nothrow assignable");
using should_not_be_no_throw_copyable = util::variant<t_noexcept_true_1, t_noexcept_false_1>;
static_assert(not std::is_nothrow_move_assignable<should_not_be_no_throw_copyable>::value,
"variants with no-throw move assignable types should be "
"no-throw move nothrow assignable");
using should_not_be_no_throw_assignable = util::variant<t_noexcept_true_1, t_noexcept_false_1>;
static_assert(not std::is_nothrow_move_constructible<should_not_be_no_throw_assignable>::value,
"variants with no-throw move assignable types should be "
"no-throw move nothrow assignable");
// this type cannot be nothrow converted from either of its types, even the nothrow moveable one,
// because the conversion operator moves the whole variant.
using convertable_test_type = util::variant<t_noexcept_true_1, t_noexcept_false_1>;
// this type can be nothrow converted from either of its types.
using convertable_test_type_2 = util::variant<t_noexcept_true_1, t_noexcept_true_2>;
static_assert(not std::is_nothrow_assignable<convertable_test_type, t_noexcept_true_1>::value,
"variants with noexcept(true) move constructible types should be nothrow-convertible "
"from those types only IF the variant itself is nothrow_move_assignable");
static_assert(not std::is_nothrow_assignable<convertable_test_type, t_noexcept_false_1>::value,
"variants with noexcept(false) move constructible types should not be nothrow-convertible "
"from those types");
static_assert(std::is_nothrow_assignable<convertable_test_type_2, t_noexcept_true_2>::value,
"variants with noexcept(true) move constructible types should be nothrow-convertible "
"from those types only IF the variant itself is nothrow_move_assignable");
} // namespace test

View File

@ -1,103 +0,0 @@
#include "catch.hpp"
#include <mapbox/optional.hpp>
struct dummy
{
dummy(int _m_1, int _m_2) : m_1(_m_1), m_2(_m_2) {}
int m_1;
int m_2;
};
TEST_CASE("optional can be instantiated with a POD type", "[optional]")
{
mapbox::util::optional<int> dbl_opt;
REQUIRE(!dbl_opt);
dbl_opt = 3;
REQUIRE(dbl_opt);
REQUIRE(dbl_opt.get() == 3);
REQUIRE(*dbl_opt == 3);
}
TEST_CASE("copy c'tor", "[optional]")
{
mapbox::util::optional<int> dbl_opt;
REQUIRE(!dbl_opt);
dbl_opt = 3;
REQUIRE(dbl_opt);
mapbox::util::optional<int> other = dbl_opt;
REQUIRE(other.get() == 3);
REQUIRE(*other == 3);
}
TEST_CASE("const operator*, const get()", "[optional]")
{
const mapbox::util::optional<int> dbl_opt = 3;
REQUIRE(dbl_opt);
auto pi1 = dbl_opt.get();
auto pi2 = *dbl_opt;
REQUIRE(pi1 == 3);
REQUIRE(pi2 == 3);
}
TEST_CASE("non-const operator*, non-const get()", "[optional]")
{
mapbox::util::optional<int> dbl_opt = 3;
REQUIRE(dbl_opt);
auto pi1 = dbl_opt.get();
auto pi2 = *dbl_opt;
REQUIRE(pi1 == 3);
REQUIRE(pi2 == 3);
}
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);
}
TEST_CASE("self assignment", "[optional]")
{
mapbox::util::optional<int> a;
a = 1;
REQUIRE(a.get() == 1);
#if !defined(__clang__)
a = a;
REQUIRE(a.get() == 1);
#endif
}

View File

@ -1,185 +0,0 @@
#include "catch.hpp"
#include <mapbox/variant.hpp>
#include <mapbox/recursive_wrapper.hpp>
#include <type_traits>
#include <utility>
using rwi = mapbox::util::recursive_wrapper<int>;
using rwp = mapbox::util::recursive_wrapper<std::pair<int, int>>;
static_assert(std::is_same<rwi::type, int>::value, "type check failed");
TEST_CASE("recursive wrapper of int")
{
SECTION("construct with value")
{
rwi a{7};
REQUIRE(a.get() == 7);
REQUIRE(*a.get_pointer() == 7);
a = 8;
REQUIRE(a.get() == 8);
rwi b{a};
REQUIRE(b.get() == 8);
rwi c;
c = b;
REQUIRE(b.get() == 8);
REQUIRE(c.get() == 8);
c = 9;
REQUIRE(c.get() == 9);
int x = 10;
c = x;
REQUIRE(c.get() == 10);
b = std::move(c);
REQUIRE(b.get() == 10);
}
SECTION("construct with const reference")
{
int i = 7;
rwi a{i};
REQUIRE(a.get() == 7);
}
SECTION("implicit conversion to reference of underlying type")
{
SECTION("const")
{
rwi const a{7};
REQUIRE(a.get() == 7);
REQUIRE(*a.get_pointer() == 7);
rwi::type const& underlying = a;
REQUIRE(underlying == 7);
}
SECTION("non const")
{
rwi a{7};
REQUIRE(a.get() == 7);
REQUIRE(*a.get_pointer() == 7);
rwi::type& underlying = a;
REQUIRE(underlying == 7);
a = 8;
REQUIRE(underlying == 8);
}
}
}
TEST_CASE("move of recursive wrapper")
{
rwi a{1};
SECTION("move constructor")
{
rwi b{std::move(a)};
REQUIRE(b.get() == 1);
}
SECTION("operator= on rvalue")
{
rwi b{2};
b = std::move(a);
REQUIRE(b.get() == 1);
}
}
TEST_CASE("swap")
{
rwi a{1};
rwi b{2};
REQUIRE(a.get() == 1);
REQUIRE(b.get() == 2);
using std::swap;
swap(a, b);
REQUIRE(a.get() == 2);
REQUIRE(b.get() == 1);
}
TEST_CASE("recursive wrapper of pair<int, int>")
{
SECTION("default constructed")
{
rwp a;
REQUIRE(a.get().first == 0);
REQUIRE(a.get().second == 0);
}
SECTION("construct with value")
{
rwp a{std::make_pair(1, 2)};
REQUIRE(a.get().first == 1);
REQUIRE(a.get().second == 2);
REQUIRE(a.get_pointer()->first == 1);
REQUIRE(a.get_pointer()->second == 2);
a = {3, 4};
REQUIRE(a.get().first == 3);
REQUIRE(a.get().second == 4);
rwp b{a};
REQUIRE(b.get().first == 3);
REQUIRE(b.get().second == 4);
rwp c;
c = b;
REQUIRE(b.get().first == 3);
REQUIRE(b.get().second == 4);
REQUIRE(c.get().first == 3);
REQUIRE(c.get().second == 4);
c = {5, 6};
REQUIRE(c.get().first == 5);
REQUIRE(c.get().second == 6);
b = std::move(c);
REQUIRE(b.get().first == 5);
REQUIRE(b.get().second == 6);
//REQUIRE(c.get_pointer() == nullptr);
}
SECTION("Multiple recurssive wrappers of polymorphic types")
{
// https://github.com/mapbox/variant/issues/146
// (Visual Studio 2015 update 3)
using namespace mapbox::util;
struct Base;
struct Derived;
using Variant = variant<recursive_wrapper<Base>, recursive_wrapper<Derived>>;
struct Base { };
struct Derived : public Base { };
{
Base base;
Derived derived;
Variant v;
v = base;
v = derived; // compile error prior https://github.com/mapbox/variant/pull/147
CHECK(v.is<Derived>());
}
{
Derived derived;
Variant v(derived); // compile error prior https://github.com/mapbox/variant/pull/147
CHECK(v.is<Derived>());
}
}
}

View File

@ -1,51 +0,0 @@
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include "catch.hpp"
#include <mapbox/variant.hpp>
#include <mapbox/variant_io.hpp>
struct some_struct
{
int a;
bool b;
std::string c;
};
using variant_internal_index_type = mapbox::util::type_index_t;
TEST_CASE("size of variants")
{
constexpr const auto min_overhead = sizeof(variant_internal_index_type);
using namespace std; // workaround for bug in GCC <= 4.8 where max_align_t is not in std
constexpr const auto max_overhead = alignof(max_align_t) + min_overhead;
using v1 = mapbox::util::variant<int>;
using v2 = mapbox::util::variant<int, bool, int64_t>;
using v3 = mapbox::util::variant<int, std::string>;
using v4 = mapbox::util::variant<std::string, std::string>;
using v5 = mapbox::util::variant<some_struct>;
constexpr const auto si = sizeof(int);
constexpr const auto sb = sizeof(bool);
constexpr const auto si64 = sizeof(int64_t);
constexpr const auto sd = sizeof(double);
constexpr const auto sstr = sizeof(std::string);
constexpr const auto spi = sizeof(std::pair<int, int>);
constexpr const auto ss = sizeof(some_struct);
REQUIRE(sizeof(v1) <= max_overhead + si);
REQUIRE(sizeof(v2) <= max_overhead + std::max({si, sb, si64}));
REQUIRE(sizeof(v3) <= max_overhead + std::max({si, sstr}));
REQUIRE(sizeof(v4) <= max_overhead + sstr);
REQUIRE(sizeof(v5) <= max_overhead + ss);
REQUIRE(sizeof(v1) >= min_overhead + si);
REQUIRE(sizeof(v2) >= min_overhead + std::max({si, sb, si64}));
REQUIRE(sizeof(v3) >= min_overhead + std::max({si, sstr}));
REQUIRE(sizeof(v4) >= min_overhead + sstr);
REQUIRE(sizeof(v5) >= min_overhead + ss);
}

View File

@ -1,127 +0,0 @@
#include "catch.hpp"
#include <mapbox/variant.hpp>
#include <mapbox/variant_io.hpp>
#include <string>
struct some_visitor
{
int var_;
some_visitor(int init)
: var_(init) {}
int operator()(int val) const
{
return var_ + val;
}
int operator()(double val) const
{
return var_ + int(val);
}
int operator()(const std::string&) const
{
return 0;
}
};
TEST_CASE("non-const visitor works on const variants", "[visitor][unary visitor]")
{
using variant_type = const mapbox::util::variant<int, double, std::string>;
variant_type var1(123);
variant_type var2(3.2);
variant_type var3("foo");
REQUIRE(var1.get<int>() == 123);
REQUIRE(var2.get<double>() == Approx(3.2));
REQUIRE(var3.get<std::string>() == "foo");
some_visitor visitor{1};
REQUIRE(mapbox::util::apply_visitor(visitor, var1) == 124);
REQUIRE(mapbox::util::apply_visitor(visitor, var2) == 4);
REQUIRE(mapbox::util::apply_visitor(visitor, var3) == 0);
}
TEST_CASE("const visitor works on const variants", "[visitor][unary visitor]")
{
using variant_type = const mapbox::util::variant<int, double, std::string>;
variant_type var1(123);
variant_type var2(3.2);
variant_type var3("foo");
REQUIRE(var1.get<int>() == 123);
REQUIRE(var2.get<double>() == Approx(3.2));
REQUIRE(var3.get<std::string>() == "foo");
const some_visitor visitor{1};
REQUIRE(mapbox::util::apply_visitor(visitor, var1) == 124);
REQUIRE(mapbox::util::apply_visitor(visitor, var2) == 4);
REQUIRE(mapbox::util::apply_visitor(visitor, var3) == 0);
}
TEST_CASE("rvalue visitor works on const variants", "[visitor][unary visitor]")
{
using variant_type = const mapbox::util::variant<int, double, std::string>;
variant_type var1(123);
variant_type var2(3.2);
variant_type var3("foo");
REQUIRE(var1.get<int>() == 123);
REQUIRE(var2.get<double>() == Approx(3.2));
REQUIRE(var3.get<std::string>() == "foo");
REQUIRE(mapbox::util::apply_visitor(some_visitor{1}, var1) == 124);
REQUIRE(mapbox::util::apply_visitor(some_visitor{1}, var2) == 4);
REQUIRE(mapbox::util::apply_visitor(some_visitor{1}, var3) == 0);
}
TEST_CASE("visitor works on rvalue variants", "[visitor][unary visitor]")
{
using variant_type = const mapbox::util::variant<int, double, std::string>;
REQUIRE(mapbox::util::apply_visitor(some_visitor{1}, variant_type{123}) == 124);
REQUIRE(mapbox::util::apply_visitor(some_visitor{1}, variant_type{3.2}) == 4);
REQUIRE(mapbox::util::apply_visitor(some_visitor{1}, variant_type{"foo"}) == 0);
}
struct total_sizeof
{
total_sizeof() : total_(0) {}
template <class Value>
int operator()(const Value&) const
{
total_ += int(sizeof(Value));
return total_;
}
int result() const
{
return total_;
}
mutable int total_;
}; // total_sizeof
TEST_CASE("changes in visitor should be visible", "[visitor][unary visitor]")
{
using variant_type = mapbox::util::variant<int, std::string, double>;
variant_type v;
total_sizeof ts;
v = 5.9;
REQUIRE(mapbox::util::apply_visitor(ts, v) == sizeof(double));
REQUIRE(ts.result() == sizeof(double));
}
TEST_CASE("changes in const visitor (with mutable internals) should be visible", "[visitor][unary visitor]")
{
using variant_type = const mapbox::util::variant<int, std::string, double>;
variant_type v{"foo"};
const total_sizeof ts;
REQUIRE(mapbox::util::apply_visitor(ts, v) == sizeof(std::string));
REQUIRE(ts.result() == sizeof(std::string));
}

Some files were not shown because too many files have changed in this diff Show More