root/gilx/trunk/include/i3dea/gil/transform_view.hpp

Revision 6, 8.5 KB (checked in by anonymous, 13 months ago)
  • Property svn:mime-type set to text/plain
Line 
1/*
2 *   Boost Software License - Version 1.0 - August 17th, 2003
3 *
4 *  Permission is hereby granted, free of charge, to any person or organization
5 *  obtaining a copy of the software and accompanying documentation covered by
6 *  this license (the "Software") to use, reproduce, display, distribute,
7 *  execute, and transmit the Software, and to prepare derivative works of the
8 *  Software, and to permit third-parties to whom the Software is furnished to
9 *  do so, all subject to the following:
10 *
11 *  The copyright notices in the Software and this entire statement, including
12 *  the above license grant, this restriction and the following disclaimer,
13 *  must be included in all copies of the Software, in whole or in part, and
14 *  all derivative works of the Software, unless such copies or derivative
15 *  works are solely in the form of machine-executable object code generated by
16 *  a source language processor.
17 *
18 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 *  FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
21 *  SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
22 *  FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
23 *  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 *  DEALINGS IN THE SOFTWARE.
25 */
26
27
28
29///@file transform_view.hpp
30///@since Aug 14, 2008
31///@author yoyohead
32///
33
34#pragma once
35#ifndef I3DEA_TRANSFORM_VIEW_HPP_INCLUDED
36#define I3DEA_TRANSFORM_VIEW_HPP_INCLUDED
37
38#include <boost/mpl/if.hpp>
39#include <boost/mpl/bool.hpp>
40#include <boost/type_traits/add_const.hpp>
41#include <boost/type_traits/add_reference.hpp>
42#include <boost/type_traits/function_traits.hpp>
43#include <boost/utility/result_of.hpp>
44
45#include <boost/gil/pixel_iterator_adaptor.hpp>
46
47#include <boost/iterator/transform_iterator.hpp>
48
49namespace i3dea{
50
51struct use_default;
52
53
54namespace aux_ {
55
56    namespace mpl = boost::mpl;
57
58
59     template<class ArgType, class DefaultType>
60     struct apply_default { typedef ArgType type;};
61
62     template<class DefaultType>
63     struct apply_default<use_default, DefaultType> {
64         typedef DefaultType type;
65     };
66
67    /// The GIL library does not transform views using a unary function,
68    /// so we need to crate an adaptor for the function.
69    template<class Function,
70             class View,
71             class Reference = use_default,
72             class Value = use_default,
73             class ConstReference = use_default
74             >
75    struct deref_from_function
76    {
77        typedef typename View::reference argument_type;
78
79        typedef typename View::const_reference const_argument_type;
80
81        typedef typename boost::result_of<Function(argument_type)>::type
82            result_type;
83
84        typedef typename boost::result_of<Function(const_argument_type)>::type
85            const_result_type;
86
87        typedef typename apply_default<Reference,  result_type>::type
88            reference;
89
90        //The adaptable function should propagate mutability of its argument.
91        typedef typename apply_default<ConstReference,const_result_type>::type
92            const_reference;
93
94
95        //The value type can be const to signal immutability
96        typedef typename apply_default<Value,
97                typename boost::remove_reference<reference>::type
98                >::type
99            value_type;
100
101
102
103        // Mutability is inherited from the mutability of the source view
104        // and from the const-ness of the functions result type.
105        typedef
106            typename mpl::not_<
107            typename mpl::or_<
108            typename boost::is_const<value_type>::type,
109            typename boost::is_const<argument_type>::type,
110            typename mpl::not_<
111                typename boost::gil::iterator_is_mutable<typename View::x_iterator>::type
112            >::type
113            >::type
114            >::type
115        is_mutable_type; //= ! ( is_const(result) || is_const(arg) || !is_mutable(view))
116
117
118        BOOST_STATIC_CONSTANT(bool, is_mutable = is_mutable_type::value );
119
120
121        typedef deref_from_function<Function,View,const_reference,value_type>
122            const_t;
123
124        typedef deref_from_function<Function,View,Reference,Value> this_type;
125
126        deref_from_function(Function f) : _function(f) {}
127
128        //In case Function is a reference, we need a copycon
129        template<class Fn, class Vw, class Rf, class Va, class CR>
130        deref_from_function(deref_from_function<Fn,Vw,Rf,Va,CR> const & other)
131        : _function(other._function)
132        {}
133
134
135        template<class T>
136        result_type operator()(T arg) const {
137            return _function(arg);
138        }
139
140        Function _function;
141    };
142
143
144
145    template<class Arg, class F>
146    deref_from_function<F,Arg> make_deref_from_function(F f) {
147        return deref_from_function<F,Arg>(f);
148    }
149
150
151}//aux_
152
153
154//Change the syntax to match fusion etc.
155// "transform_view"
156namespace result_of {
157
158
159    template<class Function,
160             class ViewOrLoc,
161             class Reference = use_default,
162             class Value = use_default,
163             class ConstReference = use_default>
164    struct transform_view:
165        ViewOrLoc::template add_deref<
166            aux_::deref_from_function<
167                Function,
168                ViewOrLoc,
169                Reference,
170                Value,
171                ConstReference
172                >
173        >
174    {
175    private:
176       typedef  aux_::deref_from_function<  Function,
177                                            ViewOrLoc,
178                                            Reference,
179                                            Value,
180                                            ConstReference
181                                            >
182        deref_type;
183
184        typedef typename ViewOrLoc::template add_deref<deref_type> base_type;
185    public:
186        static typename base_type::type make(Function f, ViewOrLoc v){
187            return base_type::make(v, deref_type(f));
188        }
189    };
190} //namespace result_of
191
192
193
194
195template < class Function,
196           class ViewOrLoc>
197typename result_of::transform_view<Function,
198                                   ViewOrLoc
199                                   >::type
200transform_view( Function fn, ViewOrLoc src) {
201    return result_of::transform_view<Function,
202                                     ViewOrLoc>
203           ::make(fn, src);
204}
205
206
207
208
209template < class Reference,
210           class Function,
211           class ViewOrLoc>
212typename result_of::transform_view<Function,
213                                   ViewOrLoc,
214                                   Reference
215                                   >::type
216transform_view( Function fn, ViewOrLoc src) {
217    return result_of::transform_view<Function,
218                                     ViewOrLoc,
219                                     Reference>
220           ::make(fn, src);
221}
222
223
224
225template <class Reference,
226          class Value,
227          class Function,
228          class ViewOrLoc>
229typename result_of::transform_view<Function,
230                                   ViewOrLoc,
231                                   Reference,
232                                   Value
233                                   >::type
234transform_view( Function fn, ViewOrLoc src) {
235    return result_of::transform_view<Function,
236                                     ViewOrLoc,
237                                     Reference,
238                                     Value>
239           ::make(fn, src);
240}
241
242
243
244
245template <class Reference,
246          class Value,
247          class ConstReference,
248          class Function,   //inferred
249          class ViewOrLoc>  //inferred
250
251typename result_of::transform_view<Function,
252                                   ViewOrLoc,
253                                   Reference,
254                                   Value,
255                                   ConstReference
256                                   >::type
257
258transform_view( Function fn, ViewOrLoc src) {
259    return result_of::transform_view<Function,
260                                     ViewOrLoc,
261                                     Reference,
262                                     Value,
263                                     ConstReference>
264           ::make(fn, src);
265}
266
267
268
269} //::i3dea
270
271#endif //I3DEA_TRANSFORM_VIEW_HPP_INCLUDED
272
273
Note: See TracBrowser for help on using the browser.