Merge branch 'master' into libuv010

This commit is contained in:
Mike Morris
2014-08-19 14:16:01 -04:00
88 changed files with 832 additions and 886 deletions

View File

@@ -62,6 +62,10 @@ public:
}
}
inline GLuint getID() const {
return buffer;
}
protected:
// increase the buffer size by at least /required/ bytes.
inline void *addElement() {
@@ -72,7 +76,7 @@ protected:
while (length < pos + itemSize) length += defaultLength;
array = realloc(array, length);
if (array == nullptr) {
throw std::runtime_error("Buffer reallocation failed¯");
throw std::runtime_error("Buffer reallocation failed");
}
}
pos += itemSize;
@@ -106,7 +110,7 @@ private:
size_t length = 0;
// GL buffer ID
uint32_t buffer = 0;
GLuint buffer = 0;
};
}

View File

@@ -4,10 +4,13 @@
#include <mbgl/geometry/buffer.hpp>
#include <mbgl/geometry/vao.hpp>
#include <array>
namespace mbgl {
template <int count>
struct ElementGroup {
VertexArrayObject array;
std::array<VertexArrayObject, count> array;
uint32_t vertex_length;
uint32_t elements_length;

View File

@@ -32,6 +32,7 @@ public:
const SDFGlyph& glyph);
void removeGlyphs(uint64_t tile_id);
void bind();
void upload();
public:
const uint16_t width = 0;

View File

@@ -41,14 +41,17 @@ public:
// NEVER CALL THIS FUNCTION FROM THE RENDER THREAD! it is blocking.
Rect<dimension> waitForImage(const std::string &name, const Sprite &sprite);
// Binds the image buffer of this sprite atlas to the GPU, and uploads data if it is out
// of date.
// Binds the image buffer of this sprite atlas to the GPU.
void bind(bool linear = false);
// Uploads the image buffer to the GPU if it is out of date.
void upload();
inline float getWidth() const { return width; }
inline float getHeight() const { return height; }
inline float getTextureWidth() const { return width * pixelRatio; }
inline float getTextureHeight() const { return height * pixelRatio; }
inline float getPixelRatio() const { return pixelRatio; }
private:
void allocate();

View File

@@ -0,0 +1,26 @@
#ifndef MBGL_GEOMETRY_STATIC_VERTEX_BUFFER
#define MBGL_GEOMETRY_STATIC_VERTEX_BUFFER
#include <mbgl/geometry/buffer.hpp>
#include <vector>
#include <cstddef>
#include <cstdint>
#include <cmath>
namespace mbgl {
class StaticVertexBuffer : public Buffer<
4, // bytes per vertex (2 * signed short == 4 bytes)
GL_ARRAY_BUFFER,
32 // default length
> {
public:
typedef int16_t vertex_type;
StaticVertexBuffer(std::initializer_list<std::pair<int16_t, int16_t>> init);
};
}
#endif

View File

@@ -1,101 +1,74 @@
#ifndef MBGL_GEOMETRY_VAO
#define MBGL_GEOMETRY_VAO
#include <mbgl/shader/shader.hpp>
#include <mbgl/platform/gl.hpp>
#include <stdexcept>
namespace mbgl {
#if GL_ARB_vertex_array_object
class VertexArrayObject {
public:
template <typename Shader, typename VertexBuffer>
void bind(Shader& shader, VertexBuffer& vertex_buffer, char *offset) {
#ifdef GL_ARB_vertex_array_object
if (!vao) {
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
} else {
// We have been given the correct information.
glBindVertexArray(vao);
}
if (shader_ptr != &shader) {
if (shader_ptr != nullptr) {
fprintf(stderr, "shader rebind!");
}
#endif
vertex_buffer.bind();
inline void bind(Shader& shader, VertexBuffer &vertexBuffer, char *offset) {
bindVertexArrayObject();
if (bound_shader == 0) {
vertexBuffer.bind();
shader.bind(offset);
#ifdef GL_ARB_vertex_array_object
shader_ptr = &shader;
vertex_buffer_ptr = &vertex_buffer;
elements_buffer_ptr = nullptr;
offset_ptr = offset;
} else if (vertex_buffer_ptr != &vertex_buffer) {
throw std::runtime_error("trying to bind VAO to another vertex buffer");
} else if (elements_buffer_ptr != nullptr) {
throw std::runtime_error("trying to bind VAO to another elements buffer");
} else if (offset_ptr != offset) {
throw std::runtime_error("trying to bind VAO to another offset");
storeBinding(shader, vertexBuffer.getID(), 0, offset);
} else {
verifyBinding(shader, vertexBuffer.getID(), 0, offset);
}
#endif
}
template <typename Shader, typename VertexBuffer, typename ElementsBuffer>
void bind(Shader& shader, VertexBuffer& vertex_buffer, ElementsBuffer& elements_buffer, char *offset) {
#ifdef GL_ARB_vertex_array_object
if (!vao) {
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
} else {
// We have been given the correct information.
glBindVertexArray(vao);
}
if (shader_ptr != &shader) {
#endif
vertex_buffer.bind();
elements_buffer.bind();
inline void bind(Shader& shader, VertexBuffer &vertexBuffer, ElementsBuffer &elementsBuffer, char *offset) {
bindVertexArrayObject();
if (bound_shader == 0) {
vertexBuffer.bind();
elementsBuffer.bind();
shader.bind(offset);
#ifdef GL_ARB_vertex_array_object
shader_ptr = &shader;
vertex_buffer_ptr = &vertex_buffer;
elements_buffer_ptr = &elements_buffer;
offset_ptr = offset;
} else if (vertex_buffer_ptr != &vertex_buffer) {
throw std::runtime_error("trying to bind VAO to another vertex buffer");
} else if (elements_buffer_ptr != &elements_buffer) {
throw std::runtime_error("trying to bind VAO to another elements buffer");
} else if (offset_ptr != offset) {
throw std::runtime_error("trying to bind VAO to another offset");
storeBinding(shader, vertexBuffer.getID(), elementsBuffer.getID(), offset);
} else {
verifyBinding(shader, vertexBuffer.getID(), elementsBuffer.getID(), offset);
}
#endif
}
~VertexArrayObject() {
#ifdef GL_ARB_vertex_array_object
if (vao) {
glDeleteVertexArrays(1, &vao);
}
#endif
}
~VertexArrayObject();
private:
#ifdef GL_ARB_vertex_array_object
void bindVertexArrayObject();
void storeBinding(Shader &shader, GLuint vertexBuffer, GLuint elementsBuffer, char *offset);
void verifyBinding(Shader &shader, GLuint vertexBuffer, GLuint elementsBuffer, char *offset);
GLuint vao = 0;
// For debug reasons, we're storing the bind information so that we can
// detect errors and report
void *shader_ptr = nullptr;
void *vertex_buffer_ptr = nullptr;
void *elements_buffer_ptr = nullptr;
char *offset_ptr = 0;
#endif
GLuint bound_shader = 0;
const char *bound_shader_name = "";
GLuint bound_vertex_buffer = 0;
GLuint bound_elements_buffer = 0;
char *bound_offset = 0;
};
#else
class VertexArrayObject {
public:
template <typename Shader, typename Buffers>
void bind(Shader& shader, Buffers& buffers, char *offset) {
for (auto &buffer : buffers) {
buffer.bind();
}
shader.bind(offset);
}
};
#endif
}
#endif

View File

@@ -1,35 +0,0 @@
#ifndef MBGL_GEOMETRY_VERTEX_BUFFER
#define MBGL_GEOMETRY_VERTEX_BUFFER
#include <vector>
#include <cstddef>
#include <cstdint>
#include <cmath>
namespace mbgl {
class VertexBuffer {
public:
typedef int16_t vertex_type;
VertexBuffer(std::initializer_list<vertex_type> init);
~VertexBuffer();
/*
* Returns the number of elements in this buffer. This is not the number of
* bytes, but rather the number of coordinates with associated information.
*/
size_t index() const;
/*
* Transfers this buffer to the GPU and binds the buffer to the GL context.
*/
void bind();
private:
const std::vector<vertex_type> array;
uint32_t buffer = 0;
};
}
#endif

View File

@@ -4,7 +4,6 @@
#include <mbgl/map/vector_tile.hpp>
#include <mbgl/style/filter_expression.hpp>
#include <mbgl/text/glyph.hpp>
#include <mbgl/text/collision.hpp>
#include <cstdint>
#include <iosfwd>
@@ -28,6 +27,7 @@ class StyleBucketLine;
class StyleBucketSymbol;
class StyleLayerGroup;
class VectorTileData;
class Collision;
class TileParser {
public:
@@ -37,6 +37,7 @@ public:
const std::shared_ptr<GlyphStore> &glyphStore,
const std::shared_ptr<SpriteAtlas> &spriteAtlas,
const std::shared_ptr<Sprite> &sprite);
~TileParser();
public:
void parse();
@@ -65,7 +66,7 @@ private:
std::shared_ptr<Sprite> sprite;
std::shared_ptr<Texturepool> texturePool;
Collision collision;
std::unique_ptr<Collision> collision;
};
}

View File

@@ -26,9 +26,12 @@
#elif TARGET_OS_MAC
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl.h>
#define glGenVertexArrays glGenVertexArraysAPPLE
#define glBindVertexArray glBindVertexArrayAPPLE
#define glDeleteVertexArrays glDeleteVertexArraysAPPLE
#if GL_APPLE_vertex_array_object
#define GL_ARB_vertex_array_object 1
#define glGenVertexArrays glGenVertexArraysAPPLE
#define glBindVertexArray glBindVertexArrayAPPLE
#define glDeleteVertexArrays glDeleteVertexArraysAPPLE
#endif
#else
#error Unsupported Apple platform
#endif

View File

@@ -34,9 +34,8 @@ class FillBucket : public Bucket {
static void *realloc(void *data, void *ptr, unsigned int size);
static void free(void *userData, void *ptr);
typedef ElementGroup triangle_group_type;
typedef ElementGroup line_group_type;
typedef ElementGroup<2> triangle_group_type;
typedef ElementGroup<1> line_group_type;
public:
FillBucket(FillVertexBuffer& vertexBuffer,
TriangleElementsBuffer& triangleElementsBuffer,

View File

@@ -20,8 +20,8 @@ class LinejoinShader;
struct pbf;
class LineBucket : public Bucket {
typedef ElementGroup triangle_group_type;
typedef ElementGroup point_group_type;
typedef ElementGroup<1> triangle_group_type;
typedef ElementGroup<1> point_group_type;
public:
LineBucket(LineVertexBuffer& vertexBuffer,
TriangleElementsBuffer& triangleElementsBuffer,

View File

@@ -3,7 +3,7 @@
#include <mbgl/map/tile_data.hpp>
#include <mbgl/geometry/vao.hpp>
#include <mbgl/geometry/vertex_buffer.hpp>
#include <mbgl/geometry/static_vertex_buffer.hpp>
#include <mbgl/util/mat4.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/renderer/frame_history.hpp>
@@ -18,7 +18,6 @@
#include <mbgl/shader/raster_shader.hpp>
#include <mbgl/shader/text_shader.hpp>
#include <mbgl/shader/dot_shader.hpp>
#include <mbgl/shader/composite_shader.hpp>
#include <mbgl/shader/gaussian_shader.hpp>
#include <mbgl/map/transform_state.hpp>
@@ -46,7 +45,6 @@ class PrerenderedTexture;
struct FillProperties;
struct RasterProperties;
struct CompositeProperties;
class LayerDescription;
class RasterTileData;
@@ -111,13 +109,11 @@ public:
void drawClippingMasks(const std::set<std::shared_ptr<StyleSource>> &sources);
void drawClippingMask(const mat4& matrix, const ClipID& clip);
void clearFramebuffers();
void resetFramebuffer();
void bindFramebuffer();
void pushFramebuffer();
GLuint popFramebuffer();
void discardFramebuffers();
void drawComposite(GLuint texture, const CompositeProperties &properties);
bool needsAnimation() const;
private:
@@ -130,6 +126,7 @@ public:
void useProgram(uint32_t program);
void lineWidth(float lineWidth);
void depthMask(bool value);
void depthRange(float near, float far);
public:
mat4 vtxMatrix;
@@ -156,6 +153,7 @@ private:
float gl_lineWidth = 0;
bool gl_depthMask = true;
std::array<uint16_t, 2> gl_viewport = {{ 0, 0 }};
std::array<float, 2> gl_depthRange = {{ 0, 1 }};
float strata = 0;
RenderPass pass = RenderPass::Opaque;
const float strata_epsilon = 1.0f / (1 << 16);
@@ -170,20 +168,19 @@ public:
std::unique_ptr<RasterShader> rasterShader;
std::unique_ptr<TextShader> textShader;
std::unique_ptr<DotShader> dotShader;
std::unique_ptr<CompositeShader> compositeShader;
std::unique_ptr<GaussianShader> gaussianShader;
// Set up the stencil quad we're using to generate the stencil mask.
VertexBuffer tileStencilBuffer = {
StaticVertexBuffer tileStencilBuffer = {
// top left triangle
0, 0,
4096, 0,
0, 4096,
{ 0, 0 },
{ 4096, 0 },
{ 0, 4096 },
// bottom right triangle
4096, 0,
0, 4096,
4096, 4096
{ 4096, 0 },
{ 0, 4096 },
{ 4096, 4096 },
};
VertexArrayObject coveringPlainArray;
@@ -191,16 +188,15 @@ public:
VertexArrayObject coveringRasterArray;
VertexArrayObject coveringGaussianArray;
VertexArrayObject compositeArray;
VertexArrayObject matteArray;
// Set up the tile boundary lines we're using to draw the tile outlines.
VertexBuffer tileBorderBuffer = {
0, 0,
4096, 0,
4096, 4096,
0, 4096,
0, 0
StaticVertexBuffer tileBorderBuffer = {
{ 0, 0 },
{ 4096, 0 },
{ 4096, 4096 },
{ 0, 4096 },
{ 0, 0 },
};
VertexArrayObject tileBorderArray;

View File

@@ -11,7 +11,7 @@
namespace mbgl {
class RasterShader;
class VertexBuffer;
class StaticVertexBuffer;
class VertexArrayObject;
class RasterBucket : public Bucket {
@@ -26,9 +26,9 @@ public:
const StyleBucketRaster &properties;
PrerenderedTexture texture;
void drawRaster(RasterShader& shader, VertexBuffer &vertices, VertexArrayObject &array);
void drawRaster(RasterShader& shader, StaticVertexBuffer &vertices, VertexArrayObject &array);
void drawRaster(RasterShader& shader, VertexBuffer &vertices, VertexArrayObject &array, GLuint texture);
void drawRaster(RasterShader& shader, StaticVertexBuffer &vertices, VertexArrayObject &array, GLuint texture);
Raster raster;

View File

@@ -50,6 +50,9 @@ typedef std::vector<Symbol> Symbols;
class SymbolBucket : public Bucket {
typedef ElementGroup<1> TextElementGroup;
typedef ElementGroup<1> IconElementGroup;
public:
SymbolBucket(const StyleBucketSymbol &properties, Collision &collision);
@@ -94,13 +97,13 @@ private:
struct {
TextVertexBuffer vertices;
TriangleElementsBuffer triangles;
std::vector<ElementGroup> groups;
std::vector<TextElementGroup> groups;
} text;
struct {
IconVertexBuffer vertices;
TriangleElementsBuffer triangles;
std::vector<ElementGroup> groups;
std::vector<IconElementGroup> groups;
} icon;
};

View File

@@ -1,29 +0,0 @@
#ifndef MBGL_SHADER_COMPOSITE_SHADER
#define MBGL_SHADER_COMPOSITE_SHADER
#include <mbgl/shader/shader.hpp>
namespace mbgl {
class CompositeShader : public Shader {
public:
CompositeShader();
void bind(char *offset);
void setImage(int32_t image);
void setOpacity(float opacity);
private:
int32_t a_pos = -1;
int32_t image = 0;
int32_t u_image = -1;
float opacity = 0;
int32_t u_opacity = -1;
};
}
#endif

View File

@@ -11,33 +11,33 @@ public:
void bind(char *offset);
void setColor(const std::array<float, 4>& color);
void setOffset(const std::array<float, 2>& offset);
void setPatternSize(const std::array<float, 2>& pattern_size);
void setPatternTopLeft(const std::array<float, 2>& pattern_tl);
void setPatternBottomRight(const std::array<float, 2>& pattern_br);
void setOpacity(float opacity);
void setImage(int image);
void setMix(float mix);
void setPatternMatrix(const std::array<float, 9> &patternmatrix);
private:
int32_t a_pos = -1;
std::array<float, 4> color = {{}};
int32_t u_color = -1;
std::array<float, 2> offset = {{}};
int32_t u_offset = -1;
std::array<float, 2> pattern_size = {{}};
int32_t u_pattern_size = -1;
std::array<float, 2> pattern_tl = {{}};
int32_t u_pattern_tl = -1;
std::array<float, 2> pattern_br = {{}};
int32_t u_pattern_br = -1;
float opacity = 0;
int32_t u_opacity = -1;
int image = 0;
int32_t u_image = -1;
float mix = 0;
int32_t u_mix = -1;
std::array<float, 9> patternmatrix = {{}};
int32_t u_patternmatrix = -1;
};
}

View File

@@ -9,13 +9,18 @@ namespace mbgl {
class Shader : private util::noncopyable {
public:
Shader(const char *vertex, const char *fragment);
Shader(const char *name, const char *vertex, const char *fragment);
~Shader();
const char *name;
bool valid;
uint32_t program;
void setMatrix(const std::array<float, 16>& matrix);
inline uint32_t getID() const {
return program;
}
private:
bool compileShader(uint32_t *shader, uint32_t type, const char *source);

View File

@@ -10,7 +10,7 @@ namespace mbgl {
class FilterExpression {
public:
typedef util::recursive_wrapper<FilterExpression> Wrapper;
typedef mapbox::util::recursive_wrapper<FilterExpression> Wrapper;
enum class Operator : uint8_t {
And,

View File

@@ -27,7 +27,7 @@ private:
};
template <typename T>
using Function = util::variant<
using Function = mapbox::util::variant<
std::false_type,
ConstantFunction<T>,
StopsFunction<T>

View File

@@ -51,8 +51,6 @@ enum class PropertyKey {
TextTranslateY,
TextTranslateAnchor,
CompositeOpacity,
RasterOpacity,
RasterHueRotate,
RasterBrightness, // for transitions only

View File

@@ -7,7 +7,7 @@
namespace mbgl {
typedef util::variant<
typedef mapbox::util::variant<
std::string,
TranslateAnchorType,
RotateAnchorType,

View File

@@ -40,6 +40,7 @@ public:
PlacementType placement = PlacementType::Point;
float min_distance = 250.0f;
bool avoid_edges = false;
struct {
bool allow_overlap = false;
@@ -88,8 +89,8 @@ public:
float buffer = 0.03125f;
};
typedef util::variant<StyleBucketFill, StyleBucketLine, StyleBucketSymbol,
StyleBucketRaster, std::false_type> StyleBucketRender;
typedef mapbox::util::variant<StyleBucketFill, StyleBucketLine, StyleBucketSymbol,
StyleBucketRaster, std::false_type> StyleBucketRender;
class StyleBucket {

View File

@@ -76,16 +76,6 @@ struct SymbolProperties {
}
};
struct CompositeProperties {
inline CompositeProperties() {}
float opacity = 1.0f;
inline bool isVisible() const {
return opacity > 0;
}
};
struct RasterProperties {
inline RasterProperties() {}
float opacity = 1.0f;
@@ -105,11 +95,10 @@ struct BackgroundProperties {
Color color = {{ 0, 0, 0, 1 }};
};
typedef util::variant<
typedef mapbox::util::variant<
FillProperties,
LineProperties,
SymbolProperties,
CompositeProperties,
RasterProperties,
BackgroundProperties,
std::false_type

View File

@@ -19,7 +19,6 @@ enum class StyleLayerType : uint8_t {
Line,
Symbol,
Raster,
Composite,
Background
};
@@ -29,7 +28,6 @@ MBGL_DEFINE_ENUM_CLASS(StyleLayerTypeClass, StyleLayerType, {
{ StyleLayerType::Line, "line" },
{ StyleLayerType::Symbol, "symbol" },
{ StyleLayerType::Raster, "raster" },
{ StyleLayerType::Composite, "composite" },
{ StyleLayerType::Background, "background" },
{ StyleLayerType(-1), "unknown" },
});

View File

@@ -9,7 +9,7 @@
namespace mbgl {
typedef util::variant<bool, int64_t, uint64_t, double, std::string> Value;
typedef mapbox::util::variant<bool, int64_t, uint64_t, double, std::string> Value;
std::string toString(const Value &value);

View File

@@ -3,23 +3,47 @@
#include <mbgl/text/types.hpp>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wdeprecated-register"
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/index/rtree.hpp>
#pragma GCC diagnostic pop
namespace mbgl {
namespace bg = boost::geometry;
namespace bgm = bg::model;
namespace bgi = bg::index;
typedef bgm::point<float, 2, bg::cs::cartesian> Point;
typedef bgm::box<Point> Box;
typedef std::pair<Box, PlacementBox> PlacementValue;
typedef bgi::rtree<PlacementValue, bgi::rstar<16>> Tree;
class Collision {
public:
Collision(float zoom, float tileExtent, float tileSize, float placementDepth = 1);
~Collision();
float getPlacementScale(const GlyphBoxes &glyphs, float minPlacementScale);
float getPlacementScale(const GlyphBoxes &glyphs, float minPlacementScale, bool avoidEdges);
PlacementRange getPlacementRange(const GlyphBoxes &glyphs, float placementScale,
bool horizontal);
void insert(const GlyphBoxes &glyphs, const CollisionAnchor &anchor, float placementScale,
const PlacementRange &placementRange, bool horizontal);
private:
void *hTree;
void *cTree;
Tree hTree;
Tree cTree;
PlacementValue leftEdge;
PlacementValue topEdge;
PlacementValue rightEdge;
PlacementValue bottomEdge;
public:
const float tilePixelRatio;

View File

@@ -0,0 +1,40 @@
// This is an incomplete port of http://glmatrix.net/
//
// Copyright (c) 2013 Brandon Jones, Colin MacKenzie IV
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the
// use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not claim
// that you wrote the original software. If you use this software in a
// product, an acknowledgment in the product documentation would be
// appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
#ifndef MBGL_UTIL_MAT3
#define MBGL_UTIL_MAT3
#include <array>
namespace mbgl {
typedef std::array<float, 9> mat3;
namespace matrix {
void identity(mat3& out);
void scale(mat3& out, const mat3& a, float x, float y);
}
}
#endif

View File

@@ -3,7 +3,7 @@
#include <utility>
namespace mbgl { namespace util {
namespace mapbox { namespace util {
template <typename T>
class recursive_wrapper

View File

@@ -35,7 +35,7 @@
// translates to 100
#define VARIANT_VERSION (VARIANT_MAJOR_VERSION*100000) + (VARIANT_MINOR_VERSION*100) + (VARIANT_PATCH_VERSION)
namespace mbgl { namespace util { namespace detail {
namespace mapbox { namespace util { namespace detail {
static constexpr std::size_t invalid_value = std::size_t(-1);
@@ -487,6 +487,8 @@ private:
} // namespace detail
struct no_init {};
template<typename... Types>
class variant
{
@@ -503,12 +505,16 @@ private:
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
@@ -715,11 +721,24 @@ auto VARIANT_INLINE static apply_visitor(F f, V & v0, V & v1) -> decltype(V::bin
return V::binary_visit(v0, v1, f);
}
// getter interface
template<typename ResultType, typename T>
ResultType & get(T & var)
{
return var.template get<ResultType>();
}
template<typename ResultType, typename T>
ResultType const& get(T const& var)
{
return var.template get<ResultType>();
}
// operator<<
template <typename charT, typename traits, typename Variant>
template <typename charT, typename traits, typename... Types>
VARIANT_INLINE std::basic_ostream<charT, traits>&
operator<< (std::basic_ostream<charT, traits>& out, Variant const& rhs)
operator<< (std::basic_ostream<charT, traits>& out, variant<Types...> const& rhs)
{
detail::printer<std::basic_ostream<charT, traits>> visitor(out);
apply_visitor(visitor, rhs);