From 7d2c627ad28b130b719fa7c2137ca9308dd40f7c Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Thu, 26 Jun 2014 15:08:52 +0200 Subject: [PATCH 01/15] replace boost::variant w/ mapbox::util::variant --- DataStructures/JSONContainer.h | 60 ++++++++++++++++++---------------- DataStructures/StaticRTree.h | 35 ++++++++++---------- 2 files changed, 49 insertions(+), 46 deletions(-) diff --git a/DataStructures/JSONContainer.h b/DataStructures/JSONContainer.h index 47dc34b279e..db9ac5d6dae 100644 --- a/DataStructures/JSONContainer.h +++ b/DataStructures/JSONContainer.h @@ -30,9 +30,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef JSON_CONTAINER_H #define JSON_CONTAINER_H +#include "../ThirdParty/variant/variant.hpp" #include "../Util/StringUtil.h" -#include +// #include #include #include @@ -42,21 +43,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace JSON { -struct String; -struct Number; +// struct String; +// struct Number; struct Object; struct Array; -struct True; -struct False; -struct Null; - -typedef boost::variant, - boost::recursive_wrapper, - boost::recursive_wrapper, - boost::recursive_wrapper, - boost::recursive_wrapper, - boost::recursive_wrapper, - boost::recursive_wrapper > Value; +// struct True; +// struct False; +// struct Null; + struct String { @@ -73,29 +67,37 @@ struct Number double value; }; -struct Object +struct True { - std::unordered_map values; }; -struct Array +struct False { - std::vector values; }; -struct True +struct Null { }; -struct False +typedef mapbox::util::variant, + mapbox::util::recursive_wrapper, + True, + False, + Null > Value; + +struct Object { + std::unordered_map values; }; -struct Null +struct Array { + std::vector values; }; -struct Renderer : boost::static_visitor<> +struct Renderer : mapbox::util::static_visitor<> { Renderer(std::ostream &_out) : out(_out) {} @@ -114,7 +116,7 @@ struct Renderer : boost::static_visitor<> while (iterator != object.values.end()) { out << "\"" << (*iterator).first << "\":"; - boost::apply_visitor(Renderer(out), (*iterator).second); + mapbox::util::apply_visitor(Renderer(out), (*iterator).second); if (++iterator != object.values.end()) { out << ","; @@ -130,7 +132,7 @@ struct Renderer : boost::static_visitor<> iterator = array.values.begin(); while (iterator != array.values.end()) { - boost::apply_visitor(Renderer(out), *iterator); + mapbox::util::apply_visitor(Renderer(out), *iterator); if (++iterator != array.values.end()) { out << ","; @@ -149,7 +151,7 @@ struct Renderer : boost::static_visitor<> std::ostream &out; }; -struct ArrayRenderer : boost::static_visitor<> +struct ArrayRenderer : mapbox::util::static_visitor<> { ArrayRenderer(std::vector &_out) : out(_out) {} @@ -176,7 +178,7 @@ struct ArrayRenderer : boost::static_visitor<> out.push_back('\"'); out.push_back(':'); - boost::apply_visitor(ArrayRenderer(out), (*iterator).second); + mapbox::util::apply_visitor(ArrayRenderer(out), (*iterator).second); if (++iterator != object.values.end()) { out.push_back(','); @@ -192,7 +194,7 @@ struct ArrayRenderer : boost::static_visitor<> iterator = array.values.begin(); while (iterator != array.values.end()) { - boost::apply_visitor(ArrayRenderer(out), *iterator); + mapbox::util::apply_visitor(ArrayRenderer(out), *iterator); if (++iterator != array.values.end()) { out.push_back(','); @@ -223,13 +225,13 @@ struct ArrayRenderer : boost::static_visitor<> inline void render(std::ostream &out, const Object &object) { Value value = object; - boost::apply_visitor(Renderer(out), value); + mapbox::util::apply_visitor(Renderer(out), value); } inline void render(std::vector &out, const Object &object) { Value value = object; - boost::apply_visitor(ArrayRenderer(out), value); + mapbox::util::apply_visitor(ArrayRenderer(out), value); } } // namespace JSON diff --git a/DataStructures/StaticRTree.h b/DataStructures/StaticRTree.h index 1e7eba625d4..425be3a6b6f 100644 --- a/DataStructures/StaticRTree.h +++ b/DataStructures/StaticRTree.h @@ -35,6 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "SharedMemoryFactory.h" #include "SharedMemoryVectorWrapper.h" +#include "../ThirdParty/variant/variant.hpp" #include "../Util/MercatorUtil.h" #include "../Util/NumericUtil.h" #include "../Util/OSRMException.h" @@ -48,7 +49,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include -#include +// #include #include #include @@ -307,7 +308,7 @@ class StaticRTree } }; - typedef boost::variant IncrementalQueryNodeType; + typedef mapbox::util::variant IncrementalQueryNodeType; struct IncrementalQueryCandidate { explicit IncrementalQueryCandidate(const float dist, const IncrementalQueryNodeType &node) @@ -323,23 +324,23 @@ class StaticRTree return other.min_dist < min_dist; } - inline bool RepresentsTreeNode() const - { - return boost::apply_visitor(decide_type_visitor(), node); - } + // inline bool RepresentsTreeNode() const + // { + // return mapbox::util::apply_visitor(decide_type_visitor(), node); + // } float min_dist; IncrementalQueryNodeType node; - private: - class decide_type_visitor : public boost::static_visitor - { - public: - bool operator()(const TreeNode &) const { return true; } + // private: + // class decide_type_visitor : public mapbox::util::static_visitor + // { + // public: + // bool operator()(const TreeNode &) const { return true; } - template - bool operator()(const AnotherType &) const { return false; } - }; + // template + // bool operator()(const AnotherType &) const { return false; } + // }; }; typename ShM::vector m_search_tree; @@ -700,9 +701,9 @@ class StaticRTree continue; } - if (current_query_node.RepresentsTreeNode()) + if (current_query_node.node.template is()) { - const TreeNode & current_tree_node = boost::get(current_query_node.node); + const TreeNode & current_tree_node = current_query_node.node.template get(); if (current_tree_node.child_is_on_disk) { ++loaded_leafs; @@ -775,7 +776,7 @@ class StaticRTree { ++inspected_segments; // inspecting an actual road segment - const EdgeDataT & current_segment = boost::get(current_query_node.node); + const EdgeDataT & current_segment = current_query_node.node.template get(); // don't collect too many results from small components if (number_of_results_found_in_big_cc == number_of_results && !current_segment.is_in_tiny_cc) From e2794e9f06e6440aa890ac33dfd1299d1b775787 Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Thu, 26 Jun 2014 15:16:47 +0200 Subject: [PATCH 02/15] initial checkin of mapbox::util::variant --- ThirdParty/variant/recursive_wrapper.hpp | 127 ++++ ThirdParty/variant/variant.hpp | 731 +++++++++++++++++++++++ 2 files changed, 858 insertions(+) create mode 100644 ThirdParty/variant/recursive_wrapper.hpp create mode 100644 ThirdParty/variant/variant.hpp diff --git a/ThirdParty/variant/recursive_wrapper.hpp b/ThirdParty/variant/recursive_wrapper.hpp new file mode 100644 index 00000000000..54b27634a30 --- /dev/null +++ b/ThirdParty/variant/recursive_wrapper.hpp @@ -0,0 +1,127 @@ +#ifndef MAPBOX_UTIL_VARIANT_RECURSIVE_WRAPPER_HPP +#define MAPBOX_UTIL_VARIANT_RECURSIVE_WRAPPER_HPP + +#include + +namespace mapbox { namespace util { + +template +class recursive_wrapper +{ +public: + using type = T; +private: + + T* p_; + +public: + + ~recursive_wrapper(); + recursive_wrapper(); + + recursive_wrapper(recursive_wrapper const& operand); + recursive_wrapper(T const& operand); + recursive_wrapper(recursive_wrapper&& operand); + recursive_wrapper(T&& operand); + +private: + + void assign(const T& rhs); + +public: + + inline recursive_wrapper& operator=(recursive_wrapper const& rhs) + { + assign( rhs.get() ); + return *this; + } + + inline recursive_wrapper& operator=(T const& rhs) + { + assign( rhs ); + return *this; + } + + inline void swap(recursive_wrapper& operand) noexcept + { + T* temp = operand.p_; + operand.p_ = p_; + p_ = temp; + } + + + recursive_wrapper& operator=(recursive_wrapper&& rhs) noexcept + { + swap(rhs); + return *this; + } + + recursive_wrapper& operator=(T&& rhs) + { + get() = std::move(rhs); + return *this; + } + + +public: + + T& get() { return *get_pointer(); } + const T& get() const { return *get_pointer(); } + T* get_pointer() { return p_; } + const T* get_pointer() const { return p_; } + operator T const&() const { return this->get(); } + operator T&() { return this->get(); } +}; + +template +recursive_wrapper::~recursive_wrapper() +{ + delete p_; +} + +template +recursive_wrapper::recursive_wrapper() + : p_(new T) +{ +} + +template +recursive_wrapper::recursive_wrapper(recursive_wrapper const& operand) + : p_(new T( operand.get() )) +{ +} + +template +recursive_wrapper::recursive_wrapper(T const& operand) + : p_(new T(operand)) +{ +} + +template +recursive_wrapper::recursive_wrapper(recursive_wrapper&& operand) + : p_(operand.p_) +{ + operand.p_ = nullptr; +} + +template +recursive_wrapper::recursive_wrapper(T&& operand) + : p_(new T( std::move(operand) )) +{ +} + +template +void recursive_wrapper::assign(const T& rhs) +{ + this->get() = rhs; +} + +template +inline void swap(recursive_wrapper& lhs, recursive_wrapper& rhs) noexcept +{ + lhs.swap(rhs); +} + +}} + +#endif // MAPBOX_UTIL_VARIANT_RECURSIVE_WRAPPER_HPP diff --git a/ThirdParty/variant/variant.hpp b/ThirdParty/variant/variant.hpp new file mode 100644 index 00000000000..0b05cb5c634 --- /dev/null +++ b/ThirdParty/variant/variant.hpp @@ -0,0 +1,731 @@ +#ifndef MAPBOX_UTIL_VARIANT_HPP +#define MAPBOX_UTIL_VARIANT_HPP + +#include +#include +#include +#include // std::move/swap +#include // runtime_error +#include // operator new +#include // size_t +#include +#include + +#include "recursive_wrapper.hpp" + +#ifdef _MSC_VER + // http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx + #ifdef NDEBUG + #define VARIANT_INLINE __forceinline + #else + #define VARIANT_INLINE __declspec(noinline) + #endif +#else + #ifdef NDEBUG + #define VARIANT_INLINE inline __attribute__((always_inline)) + #else + #define VARIANT_INLINE __attribute__((noinline)) + #endif +#endif + +#define VARIANT_MAJOR_VERSION 0 +#define VARIANT_MINOR_VERSION 1 +#define VARIANT_PATCH_VERSION 0 + +// translates to 100 +#define VARIANT_VERSION (VARIANT_MAJOR_VERSION*100000) + (VARIANT_MINOR_VERSION*100) + (VARIANT_PATCH_VERSION) + +namespace mapbox { namespace util { namespace detail { + +static constexpr std::size_t invalid_value = std::size_t(-1); + +template +struct direct_type; + +template +struct direct_type +{ + static constexpr std::size_t index = std::is_same::value + ? sizeof...(Types) : direct_type::index; +}; + +template +struct direct_type +{ + static constexpr std::size_t index = invalid_value; +}; + +template +struct convertible_type; + +template +struct convertible_type +{ + static constexpr std::size_t index = std::is_convertible::value + ? sizeof...(Types) : convertible_type::index; +}; + +template +struct convertible_type +{ + static constexpr std::size_t index = invalid_value; +}; + +template +struct value_traits +{ + static constexpr std::size_t direct_index = direct_type::index; + static constexpr std::size_t index = + (direct_index == invalid_value) ? convertible_type::index : direct_index; +}; + +template +struct is_valid_type; + +template +struct is_valid_type +{ + static constexpr bool value = std::is_convertible::value + || is_valid_type::value; +}; + +template +struct is_valid_type : std::false_type {}; + +template +struct select_type +{ + static_assert(N < sizeof...(Types), "index out of bounds"); +}; + +template +struct select_type +{ + using type = typename select_type::type; +}; + +template +struct select_type<0, T, Types...> +{ + using type = T; +}; + +} // namespace detail + +// static visitor +template +struct static_visitor +{ + using result_type = R; +protected: + static_visitor() {} + ~static_visitor() {} +}; + + +template +struct static_max; + +template +struct static_max +{ + static const std::size_t value = arg; +}; + +template +struct static_max +{ + static const std::size_t value = arg1 >= arg2 ? static_max::value : + static_max::value; +}; + +template +struct variant_helper; + +template +struct variant_helper +{ + VARIANT_INLINE static void destroy(const std::size_t id, void * data) + { + if (id == sizeof...(Types)) + { + reinterpret_cast(data)->~T(); + } + else + { + variant_helper::destroy(id, data); + } + } + + VARIANT_INLINE static void move(const std::size_t old_id, void * old_value, void * new_value) + { + if (old_id == sizeof...(Types)) + { + new (new_value) T(std::move(*reinterpret_cast(old_value))); + //std::memcpy(new_value, old_value, sizeof(T)); + // ^^ DANGER: this should only be considered for relocatable types e.g built-in types + // Also, I don't see any measurable performance benefit just yet + } + else + { + variant_helper::move(old_id, old_value, new_value); + } + } + + VARIANT_INLINE static void copy(const std::size_t old_id, const void * old_value, void * new_value) + { + if (old_id == sizeof...(Types)) + { + new (new_value) T(*reinterpret_cast(old_value)); + } + else + { + variant_helper::copy(old_id, old_value, new_value); + } + } +}; + +template<> struct variant_helper<> +{ + VARIANT_INLINE static void destroy(const std::size_t, void *) {} + VARIANT_INLINE static void move(const std::size_t, void *, void *) {} + VARIANT_INLINE static void copy(const std::size_t, const void *, void *) {} +}; + +namespace detail { + +template +struct unwrapper +{ + T const& operator() (T const& obj) const + { + return obj; + } + + T& operator() (T & obj) const + { + return obj; + } +}; + + +template +struct unwrapper> +{ + auto operator() (recursive_wrapper const& obj) const + -> typename recursive_wrapper::type const& + { + return obj.get(); + } +}; + + +template +struct dispatcher; + +template +struct dispatcher +{ + using result_type = typename F::result_type; + VARIANT_INLINE static result_type apply_const(V const& v, F f) + { + if (v.get_type_index() == sizeof...(Types)) + { + return f(unwrapper()(v. template get())); + } + else + { + return dispatcher::apply_const(v, f); + } + } + + VARIANT_INLINE static result_type apply(V & v, F f) + { + if (v.get_type_index() == sizeof...(Types)) + { + return f(unwrapper()(v. template get())); + } + else + { + return dispatcher::apply(v, f); + } + } +}; + +template +struct dispatcher +{ + using result_type = typename F::result_type; + VARIANT_INLINE static result_type apply_const(V const&, F) + { + throw std::runtime_error(std::string("unary dispatch: FAIL ") + typeid(V).name()); + } + + VARIANT_INLINE static result_type apply(V &, F) + { + throw std::runtime_error(std::string("unary dispatch: FAIL ") + typeid(V).name()); + } +}; + + +template +struct binary_dispatcher_rhs; + +template +struct binary_dispatcher_rhs +{ + using result_type = typename F::result_type; + VARIANT_INLINE static result_type apply_const(V const& lhs, V const& rhs, F f) + { + if (rhs.get_type_index() == sizeof...(Types)) // call binary functor + { + return f(unwrapper()(lhs. template get()), + unwrapper()(rhs. template get())); + } + else + { + return binary_dispatcher_rhs::apply_const(lhs, rhs, f); + } + } + + VARIANT_INLINE static result_type apply(V & lhs, V & rhs, F f) + { + if (rhs.get_type_index() == sizeof...(Types)) // call binary functor + { + return f(unwrapper()(lhs. template get()), + unwrapper()(rhs. template get())); + } + else + { + return binary_dispatcher_rhs::apply(lhs, rhs, f); + } + } + +}; + +template +struct binary_dispatcher_rhs +{ + using result_type = typename F::result_type; + VARIANT_INLINE static result_type apply_const(V const&, V const&, F) + { + throw std::runtime_error("binary dispatch: FAIL"); + } + VARIANT_INLINE static result_type apply(V &, V &, F) + { + throw std::runtime_error("binary dispatch: FAIL"); + } +}; + + +template +struct binary_dispatcher_lhs; + +template +struct binary_dispatcher_lhs +{ + using result_type = typename F::result_type; + VARIANT_INLINE static result_type apply_const(V const& lhs, V const& rhs, F f) + { + if (lhs.get_type_index() == sizeof...(Types)) // call binary functor + { + return f(lhs. template get(), rhs. template get()); + } + else + { + return binary_dispatcher_lhs::apply_const(lhs, rhs, f); + } + } + + VARIANT_INLINE static result_type apply(V & lhs, V & rhs, F f) + { + if (lhs.get_type_index() == sizeof...(Types)) // call binary functor + { + return f(lhs. template get(), rhs. template get()); + } + else + { + return binary_dispatcher_lhs::apply(lhs, rhs, f); + } + } + +}; + +template +struct binary_dispatcher_lhs +{ + using result_type = typename F::result_type; + VARIANT_INLINE static result_type apply_const(V const&, V const&, F) + { + throw std::runtime_error("binary dispatch: FAIL"); + } + + VARIANT_INLINE static result_type apply(V &, V &, F) + { + throw std::runtime_error("binary dispatch: FAIL"); + } +}; + +template +struct binary_dispatcher; + +template +struct binary_dispatcher +{ + using result_type = typename F::result_type; + VARIANT_INLINE static result_type apply_const(V const& v0, V const& v1, F f) + { + if (v0.get_type_index() == sizeof...(Types)) + { + if (v0.get_type_index() == v1.get_type_index()) + { + return f(v0. template get(), v1. template get()); // call binary functor + } + else + { + return binary_dispatcher_rhs::apply_const(v0, v1, f); + } + } + else if (v1.get_type_index() == sizeof...(Types)) + { + return binary_dispatcher_lhs::apply_const(v0, v1, f); + } + return binary_dispatcher::apply_const(v0, v1, f); + } + + VARIANT_INLINE static result_type apply(V & v0, V & v1, F f) + { + if (v0.get_type_index() == sizeof...(Types)) + { + if (v0.get_type_index() == v1.get_type_index()) + { + return f(v0. template get(), v1. template get()); // call binary functor + } + else + { + return binary_dispatcher_rhs::apply(v0, v1, f); + } + } + else if (v1.get_type_index() == sizeof...(Types)) + { + return binary_dispatcher_lhs::apply(v0, v1, f); + } + return binary_dispatcher::apply(v0, v1, f); + } +}; + +template +struct binary_dispatcher +{ + using result_type = typename F::result_type; + VARIANT_INLINE static result_type apply_const(V const&, V const&, F) + { + throw std::runtime_error("binary dispatch: FAIL"); + } + + VARIANT_INLINE static result_type apply(V &, V &, F) + { + throw std::runtime_error("binary dispatch: FAIL"); + } +}; + +// comparator functors +struct equal_comp +{ + template + bool operator()(T const& lhs, T const& rhs) const + { + return lhs == rhs; + } +}; + +struct less_comp +{ + template + bool operator()(T const& lhs, T const& rhs) const + { + return lhs < rhs; + } +}; + +template +class comparer : public static_visitor +{ +public: + explicit comparer(Variant const& lhs) noexcept + : lhs_(lhs) {} + comparer& operator=(comparer const&) = delete; + // visitor + template + bool operator()(T const& rhs_content) const + { + T const& lhs_content = lhs_.template get(); + return Comp()(lhs_content, rhs_content); + } +private: + Variant const& lhs_; +}; + +// operator<< helper +template +class printer : public static_visitor<> +{ +public: + explicit printer(Out & out) + : out_(out) {} + printer& operator=(printer const&) = delete; + +// visitor + template + void operator()(T const& operand) const + { + out_ << operand; + } +private: + Out & out_; +}; + +} // namespace detail + +template +class variant +{ +private: + + static const std::size_t data_size = static_max::value; + static const std::size_t data_align = static_max::value; + + using data_type = typename std::aligned_storage::type; + using helper_type = variant_helper; + + std::size_t type_index; + data_type data; + +public: + + VARIANT_INLINE variant() + : type_index(sizeof...(Types) - 1) + { + new (&data) typename detail::select_type<0, Types...>::type(); + } + + template ::value>::type> + VARIANT_INLINE explicit variant(T const& val) noexcept + : type_index(detail::value_traits::index) + { + constexpr std::size_t index = sizeof...(Types) - detail::value_traits::index - 1; + using target_type = typename detail::select_type::type; + new (&data) target_type(val); + } + + template ::value>::type> + VARIANT_INLINE variant(T && val) noexcept + : type_index(detail::value_traits::index) + { + constexpr std::size_t index = sizeof...(Types) - detail::value_traits::index - 1; + using target_type = typename detail::select_type::type; + new (&data) target_type(std::forward(val)); // nothrow + } + + VARIANT_INLINE variant(variant const& old) + : type_index(old.type_index) + { + helper_type::copy(old.type_index, &old.data, &data); + } + + VARIANT_INLINE variant(variant&& old) noexcept + : type_index(old.type_index) + { + helper_type::move(old.type_index, &old.data, &data); + } + + friend void swap(variant & first, variant & second) + { + using std::swap; //enable ADL + swap(first.type_index, second.type_index); + swap(first.data, second.data); + } + + VARIANT_INLINE variant& operator=(variant other) + { + swap(*this, other); + return *this; + } + + // conversions + // move-assign + template + VARIANT_INLINE variant& operator=(T && rhs) noexcept + { + variant temp(std::move(rhs)); + swap(*this, temp); + return *this; + } + + // copy-assign + template + VARIANT_INLINE variant& operator=(T const& rhs) + { + variant temp(rhs); + swap(*this, temp); + return *this; + } + + template + VARIANT_INLINE bool is() const + { + return (type_index == detail::direct_type::index); + } + + VARIANT_INLINE bool valid() const + { + return (type_index != detail::invalid_value); + } + + template + VARIANT_INLINE void set(Args&&... args) + { + helper_type::destroy(type_index, &data); + new (&data) T(std::forward(args)...); + type_index = detail::direct_type::index; + } + + template + VARIANT_INLINE T& get() + { + if (type_index == detail::direct_type::index) + { + return *reinterpret_cast(&data); + } + else + { + throw std::runtime_error("in get()"); + } + } + + template + VARIANT_INLINE T const& get() const + { + if (type_index == detail::direct_type::index) + { + return *reinterpret_cast(&data); + } + else + { + throw std::runtime_error("in get()"); + } + } + + VARIANT_INLINE std::size_t get_type_index() const + { + return type_index; + } + + // visitor + // unary + template + auto VARIANT_INLINE + static visit(V const& v, F f) + -> decltype(detail::dispatcher::apply_const(v, f)) + { + return detail::dispatcher::apply_const(v, f); + } + // non-const + template + auto VARIANT_INLINE + static visit(V & v, F f) + -> decltype(detail::dispatcher::apply(v, f)) + { + return detail::dispatcher::apply(v, f); + } + + // binary + // const + template + auto VARIANT_INLINE + static binary_visit(V const& v0, V const& v1, F f) + -> decltype(detail::binary_dispatcher::apply_const(v0, v1, f)) + { + return detail::binary_dispatcher::apply_const(v0, v1, f); + } + // non-const + template + auto VARIANT_INLINE + static binary_visit(V& v0, V& v1, F f) + -> decltype(detail::binary_dispatcher::apply(v0, v1, f)) + { + return detail::binary_dispatcher::apply(v0, v1, f); + } + + ~variant() noexcept + { + helper_type::destroy(type_index, &data); + } + + // comparison operators + // equality + VARIANT_INLINE bool operator==(variant const& rhs) const + { + if (this->get_type_index() != rhs.get_type_index()) + return false; + detail::comparer visitor(*this); + return visit(rhs, visitor); + } + // less than + VARIANT_INLINE bool operator<(variant const& rhs) const + { + if (this->get_type_index() != rhs.get_type_index()) + { + return this->get_type_index() < rhs.get_type_index(); + // ^^ borrowed from boost::variant + } + detail::comparer visitor(*this); + return visit(rhs, visitor); + } +}; + +// unary visitor interface + +// const +template +auto VARIANT_INLINE static apply_visitor(F f, V const& v) -> decltype(V::visit(v, f)) +{ + return V::visit(v, f); +} +// non-const +template +auto VARIANT_INLINE static apply_visitor(F f, V & v) -> decltype(V::visit(v, f)) +{ + return V::visit(v, f); +} + +// binary visitor interface +// const +template +auto VARIANT_INLINE static apply_visitor(F f, V const& v0, V const& v1) -> decltype(V::binary_visit(v0, v1, f)) +{ + return V::binary_visit(v0, v1, f); +} +// non-const +template +auto VARIANT_INLINE static apply_visitor(F f, V & v0, V & v1) -> decltype(V::binary_visit(v0, v1, f)) +{ + return V::binary_visit(v0, v1, f); +} + + +// operator<< +template +VARIANT_INLINE std::basic_ostream& +operator<< (std::basic_ostream& out, Variant const& rhs) +{ + detail::printer> visitor(out); + apply_visitor(visitor, rhs); + return out; +} + +}} + +#endif // MAPBOX_UTIL_VARIANT_HPP From 4c3cb76cedaa11209113711b47c0d213459db91c Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Thu, 26 Jun 2014 16:03:48 +0200 Subject: [PATCH 03/15] remove remnants of boost::variant --- DataStructures/JSONContainer.h | 8 -------- DataStructures/StaticRTree.h | 16 ---------------- 2 files changed, 24 deletions(-) diff --git a/DataStructures/JSONContainer.h b/DataStructures/JSONContainer.h index db9ac5d6dae..7476b4eae3b 100644 --- a/DataStructures/JSONContainer.h +++ b/DataStructures/JSONContainer.h @@ -33,8 +33,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "../ThirdParty/variant/variant.hpp" #include "../Util/StringUtil.h" -// #include - #include #include #include @@ -43,14 +41,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace JSON { -// struct String; -// struct Number; struct Object; struct Array; -// struct True; -// struct False; -// struct Null; - struct String { diff --git a/DataStructures/StaticRTree.h b/DataStructures/StaticRTree.h index 425be3a6b6f..a5814b050a0 100644 --- a/DataStructures/StaticRTree.h +++ b/DataStructures/StaticRTree.h @@ -49,7 +49,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include -// #include #include #include @@ -324,23 +323,8 @@ class StaticRTree return other.min_dist < min_dist; } - // inline bool RepresentsTreeNode() const - // { - // return mapbox::util::apply_visitor(decide_type_visitor(), node); - // } - float min_dist; IncrementalQueryNodeType node; - - // private: - // class decide_type_visitor : public mapbox::util::static_visitor - // { - // public: - // bool operator()(const TreeNode &) const { return true; } - - // template - // bool operator()(const AnotherType &) const { return false; } - // }; }; typename ShM::vector m_search_tree; From 4a1a10fde87ae68e3a1c8669865bcfba29a3c24a Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Thu, 26 Jun 2014 17:09:38 +0200 Subject: [PATCH 04/15] use Nov 2013 CTP to build --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 6635c5117b3..b42c5fded13 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -36,7 +36,7 @@ build_script: - SET P=c:/projects/osrm - set TBB_INSTALL_DIR=%P%/tbb - set TBB_ARCH_PLATFORM=intel64/vc12 - - cmake .. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=%Configuration% -DBZIP2_INCLUDE_DIR=%P%/libs/include -DBZIP2_LIBRARIES=%P%/libs/lib/libbz2.lib -DCMAKE_INSTALL_PREFIX=%P%/libs -DBOOST_ROOT=%P%/boost_min -DBoost_USE_STATIC_LIBS=ON + - cmake .. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=%Configuration% -DBZIP2_INCLUDE_DIR=%P%/libs/include -DBZIP2_LIBRARIES=%P%/libs/lib/libbz2.lib -DCMAKE_INSTALL_PREFIX=%P%/libs -DBOOST_ROOT=%P%/boost_min -DBoost_USE_STATIC_LIBS=ON -T "Visual C++ Compiler Nov 2013 CTP (CTP_Nov2013)" - nmake - nmake tests - nmake benchmarks From 1bfd9abda3e972c341a0be03da21f58b6a31f483 Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Thu, 26 Jun 2014 17:25:51 +0200 Subject: [PATCH 05/15] replace nmake by msbuild --- appveyor.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index b42c5fded13..c2381043f70 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -33,13 +33,12 @@ build_script: - cd build - echo Running cmake... - call "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64 + - SET PATH=C:\Program Files (x86)\MSBuild\12.0\bin\;%PATH% - SET P=c:/projects/osrm - set TBB_INSTALL_DIR=%P%/tbb - set TBB_ARCH_PLATFORM=intel64/vc12 - - cmake .. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=%Configuration% -DBZIP2_INCLUDE_DIR=%P%/libs/include -DBZIP2_LIBRARIES=%P%/libs/lib/libbz2.lib -DCMAKE_INSTALL_PREFIX=%P%/libs -DBOOST_ROOT=%P%/boost_min -DBoost_USE_STATIC_LIBS=ON -T "Visual C++ Compiler Nov 2013 CTP (CTP_Nov2013)" - - nmake - - nmake tests - - nmake benchmarks + - cmake .. -G "Visual Studio 12" -DCMAKE_BUILD_TYPE=%Configuration% -DBZIP2_INCLUDE_DIR=%P%/libs/include -DBZIP2_LIBRARIES=%P%/libs/lib/libbz2.lib -DCMAKE_INSTALL_PREFIX=%P%/libs -DBOOST_ROOT=%P%/boost_min -DBoost_USE_STATIC_LIBS=ON -T CTP_Nov2013 + - msbuild - if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip *.exe *.pdb %P%/libs/bin/*.dll -tzip) - set PATH=%PATH%;c:/projects/osrm/libs/bin - cd c:/projects/osrm/build From e10f36d5f0c7aab83137ba2ec7f6377b4bb8e51e Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Thu, 26 Jun 2014 21:11:02 +0200 Subject: [PATCH 06/15] use explicit OSRM.sln filename --- CMakeLists.txt | 1 + appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4fa213df620..0b0f7f023c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -149,6 +149,7 @@ elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") add_definitions(-DNOMINMAX) # avoid min and max macros that can break compilation add_definitions(-D_USE_MATH_DEFINES) # define M_PI add_definitions(-D_WIN32_WINNT=0x0501) + set_target_properties(OSRM PROPERTIES STATIC_LIBRARY_FLAGS "/machine:x64") endif() # disable partitioning of LTO process when possible (fixes Debian issues) diff --git a/appveyor.yml b/appveyor.yml index c2381043f70..21d56ffa405 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -38,7 +38,7 @@ build_script: - set TBB_INSTALL_DIR=%P%/tbb - set TBB_ARCH_PLATFORM=intel64/vc12 - cmake .. -G "Visual Studio 12" -DCMAKE_BUILD_TYPE=%Configuration% -DBZIP2_INCLUDE_DIR=%P%/libs/include -DBZIP2_LIBRARIES=%P%/libs/lib/libbz2.lib -DCMAKE_INSTALL_PREFIX=%P%/libs -DBOOST_ROOT=%P%/boost_min -DBoost_USE_STATIC_LIBS=ON -T CTP_Nov2013 - - msbuild + - msbuild OSRM.sln - if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip *.exe *.pdb %P%/libs/bin/*.dll -tzip) - set PATH=%PATH%;c:/projects/osrm/libs/bin - cd c:/projects/osrm/build From 7e3f47640781ec2b0dfdc7c8ab504c70edb3cd6b Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Fri, 27 Jun 2014 09:49:37 +0200 Subject: [PATCH 07/15] use 64bit cmake generator --- appveyor.yml | 2 +- typedefs.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 21d56ffa405..16f2bf863af 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -37,7 +37,7 @@ build_script: - SET P=c:/projects/osrm - set TBB_INSTALL_DIR=%P%/tbb - set TBB_ARCH_PLATFORM=intel64/vc12 - - cmake .. -G "Visual Studio 12" -DCMAKE_BUILD_TYPE=%Configuration% -DBZIP2_INCLUDE_DIR=%P%/libs/include -DBZIP2_LIBRARIES=%P%/libs/lib/libbz2.lib -DCMAKE_INSTALL_PREFIX=%P%/libs -DBOOST_ROOT=%P%/boost_min -DBoost_USE_STATIC_LIBS=ON -T CTP_Nov2013 + - cmake .. -G "Visual Studio 12 Win64" -DCMAKE_BUILD_TYPE=%Configuration% -DBZIP2_INCLUDE_DIR=%P%/libs/include -DBZIP2_LIBRARIES=%P%/libs/lib/libbz2.lib -DCMAKE_INSTALL_PREFIX=%P%/libs -DBOOST_ROOT=%P%/boost_min -DBoost_USE_STATIC_LIBS=ON -T CTP_Nov2013 - msbuild OSRM.sln - if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip *.exe *.pdb %P%/libs/bin/*.dll -tzip) - set PATH=%PATH%;c:/projects/osrm/libs/bin diff --git a/typedefs.h b/typedefs.h index ff1d2a15797..3934a161d21 100644 --- a/typedefs.h +++ b/typedefs.h @@ -35,7 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef M_PI #define M_PI 3.14159265358979323846 #endif -#define constexpr const static +// #define constexpr const static #endif typedef unsigned int NodeID; From eda8f4ccec667694c53c23667adaf9d279e2171b Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Fri, 27 Jun 2014 10:22:10 +0200 Subject: [PATCH 08/15] make integer literals static const instead of constexpr --- CMakeLists.txt | 1 - typedefs.h | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b0f7f023c9..4fa213df620 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -149,7 +149,6 @@ elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") add_definitions(-DNOMINMAX) # avoid min and max macros that can break compilation add_definitions(-D_USE_MATH_DEFINES) # define M_PI add_definitions(-D_WIN32_WINNT=0x0501) - set_target_properties(OSRM PROPERTIES STATIC_LIBRARY_FLAGS "/machine:x64") endif() # disable partitioning of LTO process when possible (fixes Debian issues) diff --git a/typedefs.h b/typedefs.h index 3934a161d21..db6e7fbc512 100644 --- a/typedefs.h +++ b/typedefs.h @@ -42,9 +42,9 @@ typedef unsigned int NodeID; typedef unsigned int EdgeID; typedef int EdgeWeight; -constexpr NodeID SPECIAL_NODEID = std::numeric_limits::max(); -constexpr EdgeID SPECIAL_EDGEID = std::numeric_limits::max(); -constexpr unsigned INVALID_NAMEID = std::numeric_limits::max(); -constexpr EdgeWeight INVALID_EDGE_WEIGHT = std::numeric_limits::max(); +static const NodeID SPECIAL_NODEID = std::numeric_limits::max(); +static const EdgeID SPECIAL_EDGEID = std::numeric_limits::max(); +static const unsigned INVALID_NAMEID = std::numeric_limits::max(); +static const EdgeWeight INVALID_EDGE_WEIGHT = std::numeric_limits::max(); #endif /* TYPEDEFS_H */ From d6b27120702643e2f4108708c6123aea44b1d91b Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Fri, 27 Jun 2014 10:22:52 +0200 Subject: [PATCH 09/15] make msbuild less verbose --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 16f2bf863af..c334c758ded 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -38,7 +38,7 @@ build_script: - set TBB_INSTALL_DIR=%P%/tbb - set TBB_ARCH_PLATFORM=intel64/vc12 - cmake .. -G "Visual Studio 12 Win64" -DCMAKE_BUILD_TYPE=%Configuration% -DBZIP2_INCLUDE_DIR=%P%/libs/include -DBZIP2_LIBRARIES=%P%/libs/lib/libbz2.lib -DCMAKE_INSTALL_PREFIX=%P%/libs -DBOOST_ROOT=%P%/boost_min -DBoost_USE_STATIC_LIBS=ON -T CTP_Nov2013 - - msbuild OSRM.sln + - msbuild /clp:Verbosity=minimal /nologo OSRM.sln - if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip *.exe *.pdb %P%/libs/bin/*.dll -tzip) - set PATH=%PATH%;c:/projects/osrm/libs/bin - cd c:/projects/osrm/build From 1de736019db5aefb6aab76f57a5a14030a0def2e Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Fri, 27 Jun 2014 10:28:42 +0200 Subject: [PATCH 10/15] make canary static const instead of constexpr --- Server/DataStructures/SharedDataType.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Server/DataStructures/SharedDataType.h b/Server/DataStructures/SharedDataType.h index 98bdfd5deba..e2351d8e98c 100644 --- a/Server/DataStructures/SharedDataType.h +++ b/Server/DataStructures/SharedDataType.h @@ -36,7 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include // Added at the start and end of each block as sanity check -constexpr char CANARY[] = "OSRM"; +static const char CANARY[] = "OSRM"; struct SharedDataLayout { From a5e99a95a3459c2a957772fb223d0558dcf57c54 Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Fri, 27 Jun 2014 10:32:17 +0200 Subject: [PATCH 11/15] remove constexpr workaround as minimum req. is now Nov 2013 CTP --- typedefs.h | 1 - 1 file changed, 1 deletion(-) diff --git a/typedefs.h b/typedefs.h index db6e7fbc512..3243ac62292 100644 --- a/typedefs.h +++ b/typedefs.h @@ -35,7 +35,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef M_PI #define M_PI 3.14159265358979323846 #endif -// #define constexpr const static #endif typedef unsigned int NodeID; From cdd72c7e567f36037e1e98a40767c4293bf9866e Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Tue, 8 Jul 2014 10:45:43 +0200 Subject: [PATCH 12/15] fast forward variant lib --- ThirdParty/variant/variant.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ThirdParty/variant/variant.hpp b/ThirdParty/variant/variant.hpp index 0b05cb5c634..3eac9b82c70 100644 --- a/ThirdParty/variant/variant.hpp +++ b/ThirdParty/variant/variant.hpp @@ -487,6 +487,8 @@ class printer : public static_visitor<> } // namespace detail +struct no_init {}; + template class variant { @@ -503,12 +505,16 @@ class variant public: + VARIANT_INLINE variant() : type_index(sizeof...(Types) - 1) { new (&data) typename detail::select_type<0, Types...>::type(); } + VARIANT_INLINE variant(no_init) + : type_index(detail::invalid_value) {} + template ::value>::type> VARIANT_INLINE explicit variant(T const& val) noexcept From 074e1e992cea95fb0d0ad84f8271333fda2e1e9e Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Wed, 23 Jul 2014 15:03:51 +0200 Subject: [PATCH 13/15] build test target explicitly on AppVeyor --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index c334c758ded..964a47bb6cc 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -38,7 +38,7 @@ build_script: - set TBB_INSTALL_DIR=%P%/tbb - set TBB_ARCH_PLATFORM=intel64/vc12 - cmake .. -G "Visual Studio 12 Win64" -DCMAKE_BUILD_TYPE=%Configuration% -DBZIP2_INCLUDE_DIR=%P%/libs/include -DBZIP2_LIBRARIES=%P%/libs/lib/libbz2.lib -DCMAKE_INSTALL_PREFIX=%P%/libs -DBOOST_ROOT=%P%/boost_min -DBoost_USE_STATIC_LIBS=ON -T CTP_Nov2013 - - msbuild /clp:Verbosity=minimal /nologo OSRM.sln + - msbuild /clp:Verbosity=minimal /nologo /t:ALL_Build /t:tests OSRM.sln - if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip *.exe *.pdb %P%/libs/bin/*.dll -tzip) - set PATH=%PATH%;c:/projects/osrm/libs/bin - cd c:/projects/osrm/build From ffa0ace2a7b3bdf938d4fa4263e3f12ea0362b0e Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Wed, 23 Jul 2014 15:57:22 +0200 Subject: [PATCH 14/15] build tests by running msbuild on tests project file --- appveyor.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 964a47bb6cc..3cbf880d5a4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -38,7 +38,8 @@ build_script: - set TBB_INSTALL_DIR=%P%/tbb - set TBB_ARCH_PLATFORM=intel64/vc12 - cmake .. -G "Visual Studio 12 Win64" -DCMAKE_BUILD_TYPE=%Configuration% -DBZIP2_INCLUDE_DIR=%P%/libs/include -DBZIP2_LIBRARIES=%P%/libs/lib/libbz2.lib -DCMAKE_INSTALL_PREFIX=%P%/libs -DBOOST_ROOT=%P%/boost_min -DBoost_USE_STATIC_LIBS=ON -T CTP_Nov2013 - - msbuild /clp:Verbosity=minimal /nologo /t:ALL_Build /t:tests OSRM.sln + - msbuild /clp:Verbosity=minimal /nologo OSRM.sln + - msbuild /clp:Verbosity=minimal /nologo tests.vcxproj - if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip *.exe *.pdb %P%/libs/bin/*.dll -tzip) - set PATH=%PATH%;c:/projects/osrm/libs/bin - cd c:/projects/osrm/build From 27a367c733fe08415ce530c2e6b266071648b522 Mon Sep 17 00:00:00 2001 From: Dennis Luxen Date: Wed, 23 Jul 2014 16:20:56 +0200 Subject: [PATCH 15/15] enter build directory before calling tests --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 3cbf880d5a4..d4a59f6120a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -42,7 +42,7 @@ build_script: - msbuild /clp:Verbosity=minimal /nologo tests.vcxproj - if "%APPVEYOR_REPO_BRANCH%"=="develop" (7z a %P%/osrm_%Configuration%.zip *.exe *.pdb %P%/libs/bin/*.dll -tzip) - set PATH=%PATH%;c:/projects/osrm/libs/bin - - cd c:/projects/osrm/build + - cd c:/projects/osrm/build/%Configuration% - datastructure-tests.exe test: off