From e548b4477d0df01fe579724f3ea28db3f7ea509c Mon Sep 17 00:00:00 2001 From: Lubomir Bourdev Date: Tue, 11 May 2010 01:07:00 +0000 Subject: [PATCH] GIL: Added support for copying between variants of different types [SVN r61899] --- .../gil/extension/dynamic_image/any_image.hpp | 6 ++++-- .../dynamic_image/any_image_view.hpp | 6 ++++-- .../gil/extension/dynamic_image/variant.hpp | 20 ++++++++++++++++--- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/include/boost/gil/extension/dynamic_image/any_image.hpp b/include/boost/gil/extension/dynamic_image/any_image.hpp index dde831994..fe436336c 100644 --- a/include/boost/gil/extension/dynamic_image/any_image.hpp +++ b/include/boost/gil/extension/dynamic_image/any_image.hpp @@ -84,9 +84,11 @@ public: template explicit any_image(const T& obj) : parent_t(obj) {} template explicit any_image(T& obj, bool do_swap) : parent_t(obj,do_swap) {} any_image(const any_image& v) : parent_t((const parent_t&)v) {} + template any_image(const any_image& v) : parent_t((const variant&)v) {} - template any_image& operator=(const T& obj) { parent_t::operator=(obj); return *this; } - any_image& operator=(const any_image& v) { parent_t::operator=((const parent_t&)v); return *this;} + template any_image& operator=(const T& obj) { parent_t::operator=(obj); return *this; } + any_image& operator=(const any_image& v) { parent_t::operator=((const parent_t&)v); return *this;} + template any_image& operator=(const any_image& v) { parent_t::operator=((const variant&)v); return *this;} void recreate(const point_t& dims, unsigned alignment=1) { apply_operation(*this,detail::recreate_image_fnobj(dims,alignment)); } void recreate(x_coord_t width, y_coord_t height, unsigned alignment=1) { recreate(point2(width,height),alignment); } diff --git a/include/boost/gil/extension/dynamic_image/any_image_view.hpp b/include/boost/gil/extension/dynamic_image/any_image_view.hpp index 1b1d5503f..a2cb5e487 100644 --- a/include/boost/gil/extension/dynamic_image/any_image_view.hpp +++ b/include/boost/gil/extension/dynamic_image/any_image_view.hpp @@ -72,9 +72,11 @@ public: any_image_view() : parent_t() {} template explicit any_image_view(const T& obj) : parent_t(obj) {} any_image_view(const any_image_view& v) : parent_t((const parent_t&)v) {} + template any_image_view(const any_image_view& v) : parent_t((const variant&)v) {} - template any_image_view& operator=(const T& obj) { parent_t::operator=(obj); return *this; } - any_image_view& operator=(const any_image_view& v) { parent_t::operator=((const parent_t&)v); return *this;} + template any_image_view& operator=(const T& obj) { parent_t::operator=(obj); return *this; } + any_image_view& operator=(const any_image_view& v) { parent_t::operator=((const parent_t&)v); return *this;} + template any_image_view& operator=(const any_image_view& v) { parent_t::operator=((const variant&)v); return *this;} std::size_t num_channels() const { return apply_operation(*this, detail::any_type_get_num_channels()); } point_t dimensions() const { return apply_operation(*this, detail::any_type_get_dimensions()); } diff --git a/include/boost/gil/extension/dynamic_image/variant.hpp b/include/boost/gil/extension/dynamic_image/variant.hpp index 24460ca6b..1c259cce1 100644 --- a/include/boost/gil/extension/dynamic_image/variant.hpp +++ b/include/boost/gil/extension/dynamic_image/variant.hpp @@ -29,7 +29,8 @@ #include #include #include - +#include +#include #include #include #include @@ -48,6 +49,7 @@ namespace detail { }; template void copy_construct_in_place(const T& t, Bits& bits); template struct copy_construct_in_place_fn; + template struct type_to_index_fn; } /** \brief Represents a concrete instance of a run-time specified type from a set of types @@ -98,7 +100,12 @@ public: virtual ~variant() { apply_operation(*this, detail::destructor_op()); } // Throws std::bad_cast if T is not in Types - template explicit variant(const T& obj){ _index=type_id(); if (_index==NUM_TYPES) throw std::bad_cast(); detail::copy_construct_in_place(obj, _bits); } + template explicit variant(const T& obj){ _index=type_id(); if (_index==NUM_TYPES) throw std::bad_cast(); detail::copy_construct_in_place(obj, _bits); } + + template explicit variant(const variant& obj) : _index(apply_operation(obj,detail::type_to_index_fn())) { + if (_index==NUM_TYPES) throw std::bad_cast(); + apply_operation(obj, detail::copy_construct_in_place_fn(_bits)); + } // When doSwap is true, swaps obj with the contents of the variant. obj will contain default-constructed instance after the call template explicit variant(T& obj, bool do_swap); @@ -125,7 +132,7 @@ public: private: template static std::size_t type_id() { return detail::type_to_index::value; } - template friend void swap(variant& x, variant& y); + template friend void swap(variant& x, variant& y); template friend typename UnaryOp::result_type apply_operation(variant& var, UnaryOp op); template friend typename UnaryOp::result_type apply_operation(const variant& var, UnaryOp op); template friend typename BinaryOp::result_type apply_operation(const variant& arg1, const variant& arg2, BinaryOp op); @@ -161,6 +168,13 @@ namespace detail { return x==*gil_reinterpret_cast_c(&_dst); } }; + + template + struct type_to_index_fn { + typedef std::size_t result_type; + + template result_type operator()(const T&) const { return detail::type_to_index::value; } + }; } // When doSwap is true, swaps obj with the contents of the variant. obj will contain default-constructed instance after the call