Merge pull request #1104 from Project-OSRM/experimental/mapbox_variant
Experimental/mapbox variant
This commit is contained in:
		
						commit
						9d1e21b5ad
					
				@ -30,10 +30,9 @@ 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 <boost/variant.hpp>
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <string>
 | 
			
		||||
@ -42,21 +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;
 | 
			
		||||
 | 
			
		||||
typedef boost::variant<boost::recursive_wrapper<String>,
 | 
			
		||||
                       boost::recursive_wrapper<Number>,
 | 
			
		||||
                       boost::recursive_wrapper<Object>,
 | 
			
		||||
                       boost::recursive_wrapper<Array>,
 | 
			
		||||
                       boost::recursive_wrapper<True>,
 | 
			
		||||
                       boost::recursive_wrapper<False>,
 | 
			
		||||
                       boost::recursive_wrapper<Null> > Value;
 | 
			
		||||
 | 
			
		||||
struct String
 | 
			
		||||
{
 | 
			
		||||
@ -73,16 +59,6 @@ struct Number
 | 
			
		||||
    double value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Object
 | 
			
		||||
{
 | 
			
		||||
    std::unordered_map<std::string, Value> values;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Array
 | 
			
		||||
{
 | 
			
		||||
    std::vector<Value> values;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct True
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
@ -95,7 +71,25 @@ struct Null
 | 
			
		||||
{
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Renderer : boost::static_visitor<>
 | 
			
		||||
typedef mapbox::util::variant<String,
 | 
			
		||||
                       Number,
 | 
			
		||||
                       mapbox::util::recursive_wrapper<Object>,
 | 
			
		||||
                       mapbox::util::recursive_wrapper<Array>,
 | 
			
		||||
                       True,
 | 
			
		||||
                       False,
 | 
			
		||||
                       Null > Value;
 | 
			
		||||
 | 
			
		||||
struct Object
 | 
			
		||||
{
 | 
			
		||||
    std::unordered_map<std::string, Value> values;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Array
 | 
			
		||||
{
 | 
			
		||||
    std::vector<Value> values;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct Renderer : mapbox::util::static_visitor<>
 | 
			
		||||
{
 | 
			
		||||
    Renderer(std::ostream &_out) : out(_out) {}
 | 
			
		||||
 | 
			
		||||
@ -114,7 +108,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 +124,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 +143,7 @@ struct Renderer : boost::static_visitor<>
 | 
			
		||||
    std::ostream &out;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct ArrayRenderer : boost::static_visitor<>
 | 
			
		||||
struct ArrayRenderer : mapbox::util::static_visitor<>
 | 
			
		||||
{
 | 
			
		||||
    ArrayRenderer(std::vector<char> &_out) : out(_out) {}
 | 
			
		||||
 | 
			
		||||
@ -176,7 +170,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 +186,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 +217,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<char> &out, const Object &object)
 | 
			
		||||
{
 | 
			
		||||
    Value value = object;
 | 
			
		||||
    boost::apply_visitor(ArrayRenderer(out), value);
 | 
			
		||||
    mapbox::util::apply_visitor(ArrayRenderer(out), value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace JSON
 | 
			
		||||
 | 
			
		||||
@ -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,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
#include <boost/filesystem.hpp>
 | 
			
		||||
#include <boost/filesystem/fstream.hpp>
 | 
			
		||||
#include <boost/thread.hpp>
 | 
			
		||||
#include <boost/variant.hpp>
 | 
			
		||||
 | 
			
		||||
#include <tbb/parallel_for.h>
 | 
			
		||||
#include <tbb/parallel_sort.h>
 | 
			
		||||
@ -307,7 +307,7 @@ class StaticRTree
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    typedef boost::variant<TreeNode, EdgeDataT> IncrementalQueryNodeType;
 | 
			
		||||
    typedef mapbox::util::variant<TreeNode, EdgeDataT> IncrementalQueryNodeType;
 | 
			
		||||
    struct IncrementalQueryCandidate
 | 
			
		||||
    {
 | 
			
		||||
        explicit IncrementalQueryCandidate(const float dist, const IncrementalQueryNodeType &node)
 | 
			
		||||
@ -323,23 +323,8 @@ class StaticRTree
 | 
			
		||||
            return other.min_dist < min_dist;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline bool RepresentsTreeNode() const
 | 
			
		||||
        {
 | 
			
		||||
            return boost::apply_visitor(decide_type_visitor(), node);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        float min_dist;
 | 
			
		||||
        IncrementalQueryNodeType node;
 | 
			
		||||
 | 
			
		||||
      private:
 | 
			
		||||
        class decide_type_visitor : public boost::static_visitor<bool>
 | 
			
		||||
        {
 | 
			
		||||
          public:
 | 
			
		||||
            bool operator()(const TreeNode &) const { return true; }
 | 
			
		||||
 | 
			
		||||
            template<typename AnotherType>
 | 
			
		||||
            bool operator()(const AnotherType &) const { return false; }
 | 
			
		||||
        };
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    typename ShM<TreeNode, UseSharedMemory>::vector m_search_tree;
 | 
			
		||||
@ -700,9 +685,9 @@ class StaticRTree
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (current_query_node.RepresentsTreeNode())
 | 
			
		||||
            if (current_query_node.node.template is<TreeNode>())
 | 
			
		||||
            {
 | 
			
		||||
                const TreeNode & current_tree_node = boost::get<TreeNode>(current_query_node.node);
 | 
			
		||||
                const TreeNode & current_tree_node = current_query_node.node.template get<TreeNode>();
 | 
			
		||||
                if (current_tree_node.child_is_on_disk)
 | 
			
		||||
                {
 | 
			
		||||
                    ++loaded_leafs;
 | 
			
		||||
@ -775,7 +760,7 @@ class StaticRTree
 | 
			
		||||
            {
 | 
			
		||||
                ++inspected_segments;
 | 
			
		||||
                // inspecting an actual road segment
 | 
			
		||||
                const EdgeDataT & current_segment = boost::get<EdgeDataT>(current_query_node.node);
 | 
			
		||||
                const EdgeDataT & current_segment = current_query_node.node.template get<EdgeDataT>();
 | 
			
		||||
 | 
			
		||||
                // 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)
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
#include <array>
 | 
			
		||||
 | 
			
		||||
// Added at the start and end of each block as sanity check
 | 
			
		||||
constexpr char CANARY[] = "OSRM";
 | 
			
		||||
static const char CANARY[] = "OSRM";
 | 
			
		||||
 | 
			
		||||
struct SharedDataLayout
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										127
									
								
								ThirdParty/variant/recursive_wrapper.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								ThirdParty/variant/recursive_wrapper.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,127 @@
 | 
			
		||||
#ifndef MAPBOX_UTIL_VARIANT_RECURSIVE_WRAPPER_HPP
 | 
			
		||||
#define MAPBOX_UTIL_VARIANT_RECURSIVE_WRAPPER_HPP
 | 
			
		||||
 | 
			
		||||
#include <utility>
 | 
			
		||||
 | 
			
		||||
namespace mapbox { namespace util {
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
class recursive_wrapper
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    using type = T;
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    T* p_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    ~recursive_wrapper();
 | 
			
		||||
    recursive_wrapper();
 | 
			
		||||
 | 
			
		||||
    recursive_wrapper(recursive_wrapper const& operand);
 | 
			
		||||
    recursive_wrapper(T const& operand);
 | 
			
		||||
    recursive_wrapper(recursive_wrapper&& operand);
 | 
			
		||||
    recursive_wrapper(T&& operand);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    void assign(const T& rhs);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    inline recursive_wrapper& operator=(recursive_wrapper const& rhs)
 | 
			
		||||
    {
 | 
			
		||||
        assign( rhs.get() );
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inline recursive_wrapper& operator=(T const& rhs)
 | 
			
		||||
    {
 | 
			
		||||
        assign( rhs );
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inline void swap(recursive_wrapper& operand) noexcept
 | 
			
		||||
    {
 | 
			
		||||
        T* temp = operand.p_;
 | 
			
		||||
        operand.p_ = p_;
 | 
			
		||||
        p_ = temp;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    recursive_wrapper& operator=(recursive_wrapper&& rhs) noexcept
 | 
			
		||||
    {
 | 
			
		||||
        swap(rhs);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    recursive_wrapper& operator=(T&& rhs)
 | 
			
		||||
    {
 | 
			
		||||
        get() = std::move(rhs);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
    T& get() { return *get_pointer(); }
 | 
			
		||||
    const T& get() const { return *get_pointer(); }
 | 
			
		||||
    T* get_pointer() { return p_; }
 | 
			
		||||
    const T* get_pointer() const { return p_; }
 | 
			
		||||
    operator T const&() const { return this->get(); }
 | 
			
		||||
    operator T&() { return this->get(); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
recursive_wrapper<T>::~recursive_wrapper()
 | 
			
		||||
{
 | 
			
		||||
    delete p_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
recursive_wrapper<T>::recursive_wrapper()
 | 
			
		||||
    : p_(new T)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
recursive_wrapper<T>::recursive_wrapper(recursive_wrapper const& operand)
 | 
			
		||||
    : p_(new T( operand.get() ))
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
recursive_wrapper<T>::recursive_wrapper(T const& operand)
 | 
			
		||||
    : p_(new T(operand))
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
recursive_wrapper<T>::recursive_wrapper(recursive_wrapper&& operand)
 | 
			
		||||
    : p_(operand.p_)
 | 
			
		||||
{
 | 
			
		||||
    operand.p_ = nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
recursive_wrapper<T>::recursive_wrapper(T&& operand)
 | 
			
		||||
    : p_(new T( std::move(operand) ))
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
void recursive_wrapper<T>::assign(const T& rhs)
 | 
			
		||||
{
 | 
			
		||||
    this->get() = rhs;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
inline void swap(recursive_wrapper<T>& lhs, recursive_wrapper<T>& rhs) noexcept
 | 
			
		||||
{
 | 
			
		||||
    lhs.swap(rhs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}}
 | 
			
		||||
 | 
			
		||||
#endif // MAPBOX_UTIL_VARIANT_RECURSIVE_WRAPPER_HPP
 | 
			
		||||
							
								
								
									
										737
									
								
								ThirdParty/variant/variant.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										737
									
								
								ThirdParty/variant/variant.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,737 @@
 | 
			
		||||
#ifndef MAPBOX_UTIL_VARIANT_HPP
 | 
			
		||||
#define MAPBOX_UTIL_VARIANT_HPP
 | 
			
		||||
 | 
			
		||||
#include <utility>
 | 
			
		||||
#include <typeinfo>
 | 
			
		||||
#include <type_traits>
 | 
			
		||||
#include <algorithm> // std::move/swap
 | 
			
		||||
#include <stdexcept> // runtime_error
 | 
			
		||||
#include <new> // operator new
 | 
			
		||||
#include <cstddef> // size_t
 | 
			
		||||
#include <iosfwd>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "recursive_wrapper.hpp"
 | 
			
		||||
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
 // http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx
 | 
			
		||||
 #ifdef NDEBUG
 | 
			
		||||
  #define VARIANT_INLINE __forceinline
 | 
			
		||||
 #else
 | 
			
		||||
  #define VARIANT_INLINE __declspec(noinline)
 | 
			
		||||
 #endif
 | 
			
		||||
#else
 | 
			
		||||
 #ifdef NDEBUG
 | 
			
		||||
  #define VARIANT_INLINE inline __attribute__((always_inline))
 | 
			
		||||
 #else
 | 
			
		||||
  #define VARIANT_INLINE __attribute__((noinline))
 | 
			
		||||
 #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define VARIANT_MAJOR_VERSION 0
 | 
			
		||||
#define VARIANT_MINOR_VERSION 1
 | 
			
		||||
#define VARIANT_PATCH_VERSION 0
 | 
			
		||||
 | 
			
		||||
// translates to 100
 | 
			
		||||
#define VARIANT_VERSION (VARIANT_MAJOR_VERSION*100000) + (VARIANT_MINOR_VERSION*100) + (VARIANT_PATCH_VERSION)
 | 
			
		||||
 | 
			
		||||
namespace mapbox { namespace util { namespace detail {
 | 
			
		||||
 | 
			
		||||
static constexpr std::size_t invalid_value = std::size_t(-1);
 | 
			
		||||
 | 
			
		||||
template <typename T, typename...Types>
 | 
			
		||||
struct direct_type;
 | 
			
		||||
 | 
			
		||||
template <typename T, typename First, typename...Types>
 | 
			
		||||
struct direct_type<T, First, Types...>
 | 
			
		||||
{
 | 
			
		||||
    static constexpr std::size_t index = std::is_same<T, First>::value
 | 
			
		||||
        ? sizeof...(Types) : direct_type<T, Types...>::index;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct direct_type<T>
 | 
			
		||||
{
 | 
			
		||||
    static constexpr std::size_t index = invalid_value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T, typename...Types>
 | 
			
		||||
struct convertible_type;
 | 
			
		||||
 | 
			
		||||
template <typename T, typename First, typename...Types>
 | 
			
		||||
struct convertible_type<T, First, Types...>
 | 
			
		||||
{
 | 
			
		||||
    static constexpr std::size_t index = std::is_convertible<T, First>::value
 | 
			
		||||
        ? sizeof...(Types) : convertible_type<T, Types...>::index;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct convertible_type<T>
 | 
			
		||||
{
 | 
			
		||||
    static constexpr std::size_t index = invalid_value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T, typename...Types>
 | 
			
		||||
struct value_traits
 | 
			
		||||
{
 | 
			
		||||
    static constexpr std::size_t direct_index = direct_type<T, Types...>::index;
 | 
			
		||||
    static constexpr std::size_t index =
 | 
			
		||||
        (direct_index == invalid_value) ? convertible_type<T, Types...>::index : direct_index;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T, typename...Types>
 | 
			
		||||
struct is_valid_type;
 | 
			
		||||
 | 
			
		||||
template <typename T, typename First, typename... Types>
 | 
			
		||||
struct is_valid_type<T, First, Types...>
 | 
			
		||||
{
 | 
			
		||||
    static constexpr bool value = std::is_convertible<T, First>::value
 | 
			
		||||
        || is_valid_type<T, Types...>::value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct is_valid_type<T> : std::false_type {};
 | 
			
		||||
 | 
			
		||||
template <std::size_t N, typename ... Types>
 | 
			
		||||
struct select_type
 | 
			
		||||
{
 | 
			
		||||
    static_assert(N < sizeof...(Types), "index out of bounds");
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <std::size_t N, typename T, typename ... Types>
 | 
			
		||||
struct select_type<N, T, Types...>
 | 
			
		||||
{
 | 
			
		||||
    using type = typename select_type<N - 1, Types...>::type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename T, typename ... Types>
 | 
			
		||||
struct select_type<0, T, Types...>
 | 
			
		||||
{
 | 
			
		||||
    using type = T;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
// static visitor
 | 
			
		||||
template <typename R = void>
 | 
			
		||||
struct static_visitor
 | 
			
		||||
{
 | 
			
		||||
    using result_type = R;
 | 
			
		||||
protected:
 | 
			
		||||
    static_visitor() {}
 | 
			
		||||
    ~static_visitor() {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template <std::size_t arg1, std::size_t ... others>
 | 
			
		||||
struct static_max;
 | 
			
		||||
 | 
			
		||||
template <std::size_t arg>
 | 
			
		||||
struct static_max<arg>
 | 
			
		||||
{
 | 
			
		||||
    static const std::size_t value = arg;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <std::size_t arg1, std::size_t arg2, std::size_t ... others>
 | 
			
		||||
struct static_max<arg1, arg2, others...>
 | 
			
		||||
{
 | 
			
		||||
    static const std::size_t value = arg1 >= arg2 ? static_max<arg1, others...>::value :
 | 
			
		||||
        static_max<arg2, others...>::value;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename... Types>
 | 
			
		||||
struct variant_helper;
 | 
			
		||||
 | 
			
		||||
template<typename T, typename... Types>
 | 
			
		||||
struct variant_helper<T, Types...>
 | 
			
		||||
{
 | 
			
		||||
    VARIANT_INLINE static void destroy(const std::size_t id, void * data)
 | 
			
		||||
    {
 | 
			
		||||
        if (id == sizeof...(Types))
 | 
			
		||||
        {
 | 
			
		||||
            reinterpret_cast<T*>(data)->~T();
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            variant_helper<Types...>::destroy(id, data);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    VARIANT_INLINE static void move(const std::size_t old_id, void * old_value, void * new_value)
 | 
			
		||||
    {
 | 
			
		||||
        if (old_id == sizeof...(Types))
 | 
			
		||||
        {
 | 
			
		||||
            new (new_value) T(std::move(*reinterpret_cast<T*>(old_value)));
 | 
			
		||||
            //std::memcpy(new_value, old_value, sizeof(T));
 | 
			
		||||
            // ^^  DANGER: this should only be considered for relocatable types e.g built-in types
 | 
			
		||||
            // Also, I don't see any measurable performance benefit just yet
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            variant_helper<Types...>::move(old_id, old_value, new_value);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    VARIANT_INLINE static void copy(const std::size_t old_id, const void * old_value, void * new_value)
 | 
			
		||||
    {
 | 
			
		||||
        if (old_id == sizeof...(Types))
 | 
			
		||||
        {
 | 
			
		||||
            new (new_value) T(*reinterpret_cast<const T*>(old_value));
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            variant_helper<Types...>::copy(old_id, old_value, new_value);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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 <typename T>
 | 
			
		||||
struct unwrapper
 | 
			
		||||
{
 | 
			
		||||
    T const& operator() (T const& obj) const
 | 
			
		||||
    {
 | 
			
		||||
        return obj;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    T& operator() (T & obj) const
 | 
			
		||||
    {
 | 
			
		||||
        return obj;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
struct unwrapper<recursive_wrapper<T>>
 | 
			
		||||
{
 | 
			
		||||
    auto operator() (recursive_wrapper<T> const& obj) const
 | 
			
		||||
        -> typename recursive_wrapper<T>::type const&
 | 
			
		||||
    {
 | 
			
		||||
        return obj.get();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template <typename F, typename V, typename...Types>
 | 
			
		||||
struct dispatcher;
 | 
			
		||||
 | 
			
		||||
template <typename F, typename V, typename T, typename...Types>
 | 
			
		||||
struct dispatcher<F, V, T, Types...>
 | 
			
		||||
{
 | 
			
		||||
    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<T>()(v. template get<T>()));
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            return dispatcher<F, V, Types...>::apply_const(v, f);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    VARIANT_INLINE static result_type apply(V & v, F f)
 | 
			
		||||
    {
 | 
			
		||||
        if (v.get_type_index() == sizeof...(Types))
 | 
			
		||||
        {
 | 
			
		||||
            return f(unwrapper<T>()(v. template get<T>()));
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            return dispatcher<F, V, Types...>::apply(v, f);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename F, typename V>
 | 
			
		||||
struct dispatcher<F, V>
 | 
			
		||||
{
 | 
			
		||||
    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 <typename F, typename V, typename T, typename...Types>
 | 
			
		||||
struct binary_dispatcher_rhs;
 | 
			
		||||
 | 
			
		||||
template <typename F, typename V, typename T0, typename T1, typename...Types>
 | 
			
		||||
struct binary_dispatcher_rhs<F, V, T0, T1, Types...>
 | 
			
		||||
{
 | 
			
		||||
    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<T0>()(lhs. template get<T0>()),
 | 
			
		||||
                     unwrapper<T1>()(rhs. template get<T1>()));
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            return binary_dispatcher_rhs<F, V, T0, Types...>::apply_const(lhs, rhs, f);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    VARIANT_INLINE static result_type apply(V & lhs, V & rhs, F f)
 | 
			
		||||
    {
 | 
			
		||||
        if (rhs.get_type_index() == sizeof...(Types)) // call binary functor
 | 
			
		||||
        {
 | 
			
		||||
            return f(unwrapper<T0>()(lhs. template get<T0>()),
 | 
			
		||||
                     unwrapper<T1>()(rhs. template get<T1>()));
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            return binary_dispatcher_rhs<F, V, T0, Types...>::apply(lhs, rhs, f);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename F, typename V, typename T>
 | 
			
		||||
struct binary_dispatcher_rhs<F, V, T>
 | 
			
		||||
{
 | 
			
		||||
    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 <typename F, typename V, typename T, typename...Types>
 | 
			
		||||
struct binary_dispatcher_lhs;
 | 
			
		||||
 | 
			
		||||
template <typename F, typename V, typename T0, typename T1, typename...Types>
 | 
			
		||||
struct binary_dispatcher_lhs<F, V, T0, T1, Types...>
 | 
			
		||||
{
 | 
			
		||||
    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<T1>(), rhs. template get<T0>());
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            return binary_dispatcher_lhs<F, V, T0, Types...>::apply_const(lhs, rhs, f);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    VARIANT_INLINE static result_type apply(V & lhs, V & rhs, F f)
 | 
			
		||||
    {
 | 
			
		||||
        if (lhs.get_type_index() == sizeof...(Types)) // call binary functor
 | 
			
		||||
        {
 | 
			
		||||
            return f(lhs. template get<T1>(), rhs. template get<T0>());
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            return binary_dispatcher_lhs<F, V, T0, Types...>::apply(lhs, rhs, f);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename F, typename V, typename T>
 | 
			
		||||
struct binary_dispatcher_lhs<F, V, T>
 | 
			
		||||
{
 | 
			
		||||
    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 <typename F, typename V, typename...Types>
 | 
			
		||||
struct binary_dispatcher;
 | 
			
		||||
 | 
			
		||||
template <typename F, typename V, typename T, typename...Types>
 | 
			
		||||
struct binary_dispatcher<F, V, T, Types...>
 | 
			
		||||
{
 | 
			
		||||
    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<T>(), v1. template get<T>()); // call binary functor
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                return binary_dispatcher_rhs<F, V, T, Types...>::apply_const(v0, v1, f);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (v1.get_type_index() == sizeof...(Types))
 | 
			
		||||
        {
 | 
			
		||||
            return binary_dispatcher_lhs<F, V, T, Types...>::apply_const(v0, v1, f);
 | 
			
		||||
        }
 | 
			
		||||
        return binary_dispatcher<F, V, Types...>::apply_const(v0, v1, f);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    VARIANT_INLINE static result_type apply(V & v0, V & v1, F f)
 | 
			
		||||
    {
 | 
			
		||||
        if (v0.get_type_index() == sizeof...(Types))
 | 
			
		||||
        {
 | 
			
		||||
            if (v0.get_type_index() == v1.get_type_index())
 | 
			
		||||
            {
 | 
			
		||||
                return f(v0. template get<T>(), v1. template get<T>()); // call binary functor
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                return binary_dispatcher_rhs<F, V, T, Types...>::apply(v0, v1, f);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else if (v1.get_type_index() == sizeof...(Types))
 | 
			
		||||
        {
 | 
			
		||||
            return binary_dispatcher_lhs<F, V, T, Types...>::apply(v0, v1, f);
 | 
			
		||||
        }
 | 
			
		||||
        return binary_dispatcher<F, V, Types...>::apply(v0, v1, f);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename F, typename V>
 | 
			
		||||
struct binary_dispatcher<F, V>
 | 
			
		||||
{
 | 
			
		||||
    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 <typename T>
 | 
			
		||||
    bool operator()(T const& lhs, T const& rhs) const
 | 
			
		||||
    {
 | 
			
		||||
        return lhs == rhs;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct less_comp
 | 
			
		||||
{
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    bool operator()(T const& lhs, T const& rhs) const
 | 
			
		||||
    {
 | 
			
		||||
        return lhs < rhs;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <typename Variant, typename Comp>
 | 
			
		||||
class comparer : public static_visitor<bool>
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    explicit comparer(Variant const& lhs) noexcept
 | 
			
		||||
        : lhs_(lhs) {}
 | 
			
		||||
    comparer& operator=(comparer const&) = delete;
 | 
			
		||||
    // visitor
 | 
			
		||||
    template<typename T>
 | 
			
		||||
    bool operator()(T const& rhs_content) const
 | 
			
		||||
    {
 | 
			
		||||
        T const& lhs_content = lhs_.template get<T>();
 | 
			
		||||
        return Comp()(lhs_content, rhs_content);
 | 
			
		||||
    }
 | 
			
		||||
private:
 | 
			
		||||
    Variant const& lhs_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// operator<< helper
 | 
			
		||||
template <typename Out>
 | 
			
		||||
class printer : public static_visitor<>
 | 
			
		||||
{
 | 
			
		||||
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_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace detail
 | 
			
		||||
 | 
			
		||||
struct no_init {};
 | 
			
		||||
 | 
			
		||||
template<typename... Types>
 | 
			
		||||
class variant
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    static const std::size_t data_size = static_max<sizeof(Types)...>::value;
 | 
			
		||||
    static const std::size_t data_align = static_max<alignof(Types)...>::value;
 | 
			
		||||
 | 
			
		||||
    using data_type = typename std::aligned_storage<data_size, data_align>::type;
 | 
			
		||||
    using helper_type = variant_helper<Types...>;
 | 
			
		||||
 | 
			
		||||
    std::size_t type_index;
 | 
			
		||||
    data_type data;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    VARIANT_INLINE variant()
 | 
			
		||||
        : type_index(sizeof...(Types) - 1)
 | 
			
		||||
    {
 | 
			
		||||
        new (&data) typename detail::select_type<0, Types...>::type();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    VARIANT_INLINE variant(no_init)
 | 
			
		||||
        : type_index(detail::invalid_value) {}
 | 
			
		||||
 | 
			
		||||
    template <typename T, class = typename std::enable_if<
 | 
			
		||||
                         detail::is_valid_type<T, Types...>::value>::type>
 | 
			
		||||
    VARIANT_INLINE explicit variant(T const& val) noexcept
 | 
			
		||||
        : type_index(detail::value_traits<T, Types...>::index)
 | 
			
		||||
    {
 | 
			
		||||
        constexpr std::size_t index = sizeof...(Types) - detail::value_traits<T, Types...>::index - 1;
 | 
			
		||||
        using target_type = typename detail::select_type<index, Types...>::type;
 | 
			
		||||
        new (&data) target_type(val);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename T, class = typename std::enable_if<
 | 
			
		||||
                          detail::is_valid_type<T, Types...>::value>::type>
 | 
			
		||||
    VARIANT_INLINE variant(T && val) noexcept
 | 
			
		||||
        : type_index(detail::value_traits<T, Types...>::index)
 | 
			
		||||
    {
 | 
			
		||||
        constexpr std::size_t index = sizeof...(Types) - detail::value_traits<T, Types...>::index - 1;
 | 
			
		||||
        using target_type = typename detail::select_type<index, Types...>::type;
 | 
			
		||||
        new (&data) target_type(std::forward<T>(val)); // nothrow
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    VARIANT_INLINE variant(variant<Types...> const& old)
 | 
			
		||||
        : type_index(old.type_index)
 | 
			
		||||
    {
 | 
			
		||||
        helper_type::copy(old.type_index, &old.data, &data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    VARIANT_INLINE variant(variant<Types...>&& old) noexcept
 | 
			
		||||
        : type_index(old.type_index)
 | 
			
		||||
    {
 | 
			
		||||
        helper_type::move(old.type_index, &old.data, &data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    friend void swap(variant<Types...> & first, variant<Types...> & second)
 | 
			
		||||
    {
 | 
			
		||||
        using std::swap; //enable ADL
 | 
			
		||||
        swap(first.type_index, second.type_index);
 | 
			
		||||
        swap(first.data, second.data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    VARIANT_INLINE variant<Types...>& operator=(variant<Types...> other)
 | 
			
		||||
    {
 | 
			
		||||
        swap(*this, other);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // conversions
 | 
			
		||||
    // move-assign
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    VARIANT_INLINE variant<Types...>& operator=(T && rhs) noexcept
 | 
			
		||||
    {
 | 
			
		||||
        variant<Types...> temp(std::move(rhs));
 | 
			
		||||
        swap(*this, temp);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // copy-assign
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    VARIANT_INLINE variant<Types...>& operator=(T const& rhs)
 | 
			
		||||
    {
 | 
			
		||||
        variant<Types...> temp(rhs);
 | 
			
		||||
        swap(*this, temp);
 | 
			
		||||
        return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename T>
 | 
			
		||||
    VARIANT_INLINE bool is() const
 | 
			
		||||
    {
 | 
			
		||||
        return (type_index == detail::direct_type<T, Types...>::index);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    VARIANT_INLINE bool valid() const
 | 
			
		||||
    {
 | 
			
		||||
        return (type_index != detail::invalid_value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename T, typename... Args>
 | 
			
		||||
    VARIANT_INLINE void set(Args&&... args)
 | 
			
		||||
    {
 | 
			
		||||
        helper_type::destroy(type_index, &data);
 | 
			
		||||
        new (&data) T(std::forward<Args>(args)...);
 | 
			
		||||
        type_index = detail::direct_type<T, Types...>::index;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename T>
 | 
			
		||||
    VARIANT_INLINE T& get()
 | 
			
		||||
    {
 | 
			
		||||
        if (type_index == detail::direct_type<T, Types...>::index)
 | 
			
		||||
        {
 | 
			
		||||
            return *reinterpret_cast<T*>(&data);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            throw std::runtime_error("in get()");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename T>
 | 
			
		||||
    VARIANT_INLINE T const& get() const
 | 
			
		||||
    {
 | 
			
		||||
        if (type_index == detail::direct_type<T, Types...>::index)
 | 
			
		||||
        {
 | 
			
		||||
            return *reinterpret_cast<T const*>(&data);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            throw std::runtime_error("in get()");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    VARIANT_INLINE std::size_t get_type_index() const
 | 
			
		||||
    {
 | 
			
		||||
        return type_index;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // visitor
 | 
			
		||||
    // unary
 | 
			
		||||
    template <typename F, typename V>
 | 
			
		||||
    auto VARIANT_INLINE
 | 
			
		||||
    static visit(V const& v, F f)
 | 
			
		||||
        -> decltype(detail::dispatcher<F, V, Types...>::apply_const(v, f))
 | 
			
		||||
    {
 | 
			
		||||
        return detail::dispatcher<F, V, Types...>::apply_const(v, f);
 | 
			
		||||
    }
 | 
			
		||||
    // non-const
 | 
			
		||||
    template <typename F, typename V>
 | 
			
		||||
    auto VARIANT_INLINE
 | 
			
		||||
    static visit(V & v, F f)
 | 
			
		||||
        -> decltype(detail::dispatcher<F, V, Types...>::apply(v, f))
 | 
			
		||||
    {
 | 
			
		||||
        return detail::dispatcher<F, V, Types...>::apply(v, f);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // binary
 | 
			
		||||
    // const
 | 
			
		||||
    template <typename F, typename V>
 | 
			
		||||
    auto VARIANT_INLINE
 | 
			
		||||
    static binary_visit(V const& v0, V const& v1, F f)
 | 
			
		||||
        -> decltype(detail::binary_dispatcher<F, V, Types...>::apply_const(v0, v1, f))
 | 
			
		||||
    {
 | 
			
		||||
        return detail::binary_dispatcher<F, V, Types...>::apply_const(v0, v1, f);
 | 
			
		||||
    }
 | 
			
		||||
    // non-const
 | 
			
		||||
    template <typename F, typename V>
 | 
			
		||||
    auto VARIANT_INLINE
 | 
			
		||||
    static binary_visit(V& v0, V& v1, F f)
 | 
			
		||||
        -> decltype(detail::binary_dispatcher<F, V, Types...>::apply(v0, v1, f))
 | 
			
		||||
    {
 | 
			
		||||
        return detail::binary_dispatcher<F, V, Types...>::apply(v0, v1, f);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~variant() noexcept
 | 
			
		||||
    {
 | 
			
		||||
        helper_type::destroy(type_index, &data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // comparison operators
 | 
			
		||||
    // equality
 | 
			
		||||
    VARIANT_INLINE bool operator==(variant const& rhs) const
 | 
			
		||||
    {
 | 
			
		||||
        if (this->get_type_index() != rhs.get_type_index())
 | 
			
		||||
            return false;
 | 
			
		||||
        detail::comparer<variant, detail::equal_comp> visitor(*this);
 | 
			
		||||
        return visit(rhs, visitor);
 | 
			
		||||
    }
 | 
			
		||||
    // less than
 | 
			
		||||
    VARIANT_INLINE bool operator<(variant const& rhs) const
 | 
			
		||||
    {
 | 
			
		||||
        if (this->get_type_index() != rhs.get_type_index())
 | 
			
		||||
        {
 | 
			
		||||
            return this->get_type_index() < rhs.get_type_index();
 | 
			
		||||
            // ^^ borrowed from boost::variant
 | 
			
		||||
        }
 | 
			
		||||
        detail::comparer<variant, detail::less_comp> visitor(*this);
 | 
			
		||||
        return visit(rhs, visitor);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// unary visitor interface
 | 
			
		||||
 | 
			
		||||
// const
 | 
			
		||||
template <typename V, typename F>
 | 
			
		||||
auto VARIANT_INLINE static apply_visitor(F f, V const& v) -> decltype(V::visit(v, f))
 | 
			
		||||
{
 | 
			
		||||
    return V::visit(v, f);
 | 
			
		||||
}
 | 
			
		||||
// non-const
 | 
			
		||||
template <typename V, typename F>
 | 
			
		||||
auto VARIANT_INLINE static apply_visitor(F f, V & v) -> decltype(V::visit(v, f))
 | 
			
		||||
{
 | 
			
		||||
    return V::visit(v, f);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// binary visitor interface
 | 
			
		||||
// const
 | 
			
		||||
template <typename V, typename F>
 | 
			
		||||
auto VARIANT_INLINE static apply_visitor(F f, V const& v0, V const& v1) -> decltype(V::binary_visit(v0, v1, f))
 | 
			
		||||
{
 | 
			
		||||
    return V::binary_visit(v0, v1, f);
 | 
			
		||||
}
 | 
			
		||||
// non-const
 | 
			
		||||
template <typename V, typename F>
 | 
			
		||||
auto VARIANT_INLINE static apply_visitor(F f, V & v0, V & v1) -> decltype(V::binary_visit(v0, v1, f))
 | 
			
		||||
{
 | 
			
		||||
    return V::binary_visit(v0, v1, f);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// operator<<
 | 
			
		||||
template <typename charT, typename traits, typename Variant>
 | 
			
		||||
VARIANT_INLINE std::basic_ostream<charT, traits>&
 | 
			
		||||
operator<< (std::basic_ostream<charT, traits>& out, Variant const& rhs)
 | 
			
		||||
{
 | 
			
		||||
    detail::printer<std::basic_ostream<charT, traits>> visitor(out);
 | 
			
		||||
    apply_visitor(visitor, rhs);
 | 
			
		||||
    return out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}}
 | 
			
		||||
 | 
			
		||||
#endif  // MAPBOX_UTIL_VARIANT_HPP
 | 
			
		||||
							
								
								
									
										10
									
								
								appveyor.yml
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								appveyor.yml
									
									
									
									
									
								
							@ -33,16 +33,16 @@ 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
 | 
			
		||||
  - nmake
 | 
			
		||||
  - nmake tests
 | 
			
		||||
  - nmake benchmarks
 | 
			
		||||
  - 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 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
 | 
			
		||||
 | 
			
		||||
@ -35,16 +35,15 @@ 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;
 | 
			
		||||
typedef unsigned int EdgeID;
 | 
			
		||||
typedef int EdgeWeight;
 | 
			
		||||
 | 
			
		||||
constexpr NodeID SPECIAL_NODEID = std::numeric_limits<unsigned>::max();
 | 
			
		||||
constexpr EdgeID SPECIAL_EDGEID = std::numeric_limits<unsigned>::max();
 | 
			
		||||
constexpr unsigned INVALID_NAMEID = std::numeric_limits<unsigned>::max();
 | 
			
		||||
constexpr EdgeWeight INVALID_EDGE_WEIGHT = std::numeric_limits<int>::max();
 | 
			
		||||
static const NodeID SPECIAL_NODEID = std::numeric_limits<unsigned>::max();
 | 
			
		||||
static const EdgeID SPECIAL_EDGEID = std::numeric_limits<unsigned>::max();
 | 
			
		||||
static const unsigned INVALID_NAMEID = std::numeric_limits<unsigned>::max();
 | 
			
		||||
static const EdgeWeight INVALID_EDGE_WEIGHT = std::numeric_limits<int>::max();
 | 
			
		||||
 | 
			
		||||
#endif /* TYPEDEFS_H */
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user