annotate DEPENDENCIES/generic/include/boost/gil/gil_concept.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 /*
Chris@16 2 Copyright 2005-2007 Adobe Systems Incorporated
Chris@16 3
Chris@16 4 Use, modification and distribution are subject to the Boost Software License,
Chris@16 5 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 6 http://www.boost.org/LICENSE_1_0.txt).
Chris@16 7
Chris@16 8 See http://opensource.adobe.com/gil for most recent version including documentation.
Chris@16 9 */
Chris@16 10
Chris@16 11 /*************************************************************************************************/
Chris@16 12
Chris@16 13 #ifndef GIL_CONCEPT_H
Chris@16 14 #define GIL_CONCEPT_H
Chris@16 15
Chris@16 16 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 17 /// \file
Chris@16 18 /// \brief Concept check classes for GIL concepts
Chris@16 19 /// \author Lubomir Bourdev and Hailin Jin \n
Chris@16 20 /// Adobe Systems Incorporated
Chris@16 21 /// \date 2005-2007 \n Last updated on February 12, 2007
Chris@16 22 ///
Chris@16 23 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 24
Chris@16 25 #include <functional>
Chris@16 26 #include "gil_config.hpp"
Chris@16 27 #include <boost/type_traits.hpp>
Chris@16 28 #include <boost/utility/enable_if.hpp>
Chris@16 29 #include <boost/concept_check.hpp>
Chris@16 30 #include <boost/iterator/iterator_concepts.hpp>
Chris@16 31 #include <boost/mpl/and.hpp>
Chris@16 32 #include <boost/mpl/size.hpp>
Chris@16 33
Chris@16 34 namespace boost { namespace gil {
Chris@16 35 template <typename T> struct channel_traits;
Chris@16 36 template <typename P> struct is_pixel;
Chris@16 37 template <typename dstT, typename srcT>
Chris@16 38 typename channel_traits<dstT>::value_type channel_convert(const srcT& val);
Chris@16 39 template <typename T> class point2;
Chris@16 40 template <std::size_t K, typename T> const T& axis_value(const point2<T>& p);
Chris@16 41 template <std::size_t K, typename T> T& axis_value( point2<T>& p);
Chris@16 42 template <typename ColorBase, int K> struct kth_element_type;
Chris@16 43 template <typename ColorBase, int K> struct kth_element_reference_type;
Chris@16 44 template <typename ColorBase, int K> struct kth_element_const_reference_type;
Chris@16 45 template <typename ColorBase, int K> struct kth_semantic_element_reference_type;
Chris@16 46 template <typename ColorBase, int K> struct kth_semantic_element_const_reference_type;
Chris@16 47 template <typename ColorBase> struct size;
Chris@16 48 template <typename ColorBase> struct element_type;
Chris@16 49 template <typename T> struct channel_type;
Chris@16 50 template <typename T> struct color_space_type;
Chris@16 51 template <typename T> struct channel_mapping_type;
Chris@16 52 template <typename T> struct is_planar;
Chris@16 53 template <typename T> struct num_channels;
Chris@16 54
Chris@16 55 template <typename It> struct const_iterator_type;
Chris@16 56 template <typename It> struct iterator_is_mutable;
Chris@16 57 template <typename It> struct is_iterator_adaptor;
Chris@16 58 template <typename It, typename NewBaseIt> struct iterator_adaptor_rebind;
Chris@16 59 template <typename It> struct iterator_adaptor_get_base;
Chris@16 60
Chris@16 61
Chris@16 62 // forward-declare at_c
Chris@16 63 namespace detail { template <typename Element, typename Layout, int K> struct homogeneous_color_base; }
Chris@16 64 template <int K, typename E, typename L, int N>
Chris@16 65 typename add_reference<E>::type at_c( detail::homogeneous_color_base<E,L,N>& p);
Chris@16 66
Chris@16 67 template <int K, typename E, typename L, int N>
Chris@16 68 typename add_reference<typename add_const<E>::type>::type at_c(const detail::homogeneous_color_base<E,L,N>& p);
Chris@16 69
Chris@16 70 #if !defined(_MSC_VER) || _MSC_VER > 1310
Chris@16 71 template <typename P, typename C, typename L> struct packed_pixel;
Chris@16 72 template <int K, typename P, typename C, typename L>
Chris@16 73 typename kth_element_reference_type<packed_pixel<P,C,L>, K>::type
Chris@16 74 at_c(packed_pixel<P,C,L>& p);
Chris@16 75
Chris@16 76 template <int K, typename P, typename C, typename L>
Chris@16 77 typename kth_element_const_reference_type<packed_pixel<P,C,L>,K>::type
Chris@16 78 at_c(const packed_pixel<P,C,L>& p);
Chris@16 79
Chris@16 80 template <typename B, typename C, typename L, bool M> struct bit_aligned_pixel_reference;
Chris@16 81
Chris@16 82 template <int K, typename B, typename C, typename L, bool M> inline
Chris@16 83 typename kth_element_reference_type<bit_aligned_pixel_reference<B,C,L,M>, K>::type
Chris@16 84 at_c(const bit_aligned_pixel_reference<B,C,L,M>& p);
Chris@16 85 #endif
Chris@16 86
Chris@16 87 // Forward-declare semantic_at_c
Chris@16 88 template <int K, typename ColorBase>
Chris@16 89 typename disable_if<is_const<ColorBase>,typename kth_semantic_element_reference_type<ColorBase,K>::type>::type semantic_at_c(ColorBase& p);
Chris@16 90 template <int K, typename ColorBase>
Chris@16 91 typename kth_semantic_element_const_reference_type<ColorBase,K>::type semantic_at_c(const ColorBase& p);
Chris@16 92
Chris@16 93 template <typename T> struct dynamic_x_step_type;
Chris@16 94 template <typename T> struct dynamic_y_step_type;
Chris@16 95 template <typename T> struct transposed_type;
Chris@16 96
Chris@16 97 namespace detail {
Chris@16 98 template <typename T>
Chris@16 99 void initialize_it(T& x) {}
Chris@16 100 } // namespace detail
Chris@16 101
Chris@16 102 template <typename T>
Chris@16 103 struct remove_const_and_reference : public remove_const<typename remove_reference<T>::type> {};
Chris@16 104
Chris@16 105 #ifdef BOOST_GIL_USE_CONCEPT_CHECK
Chris@16 106 #define GIL_CLASS_REQUIRE(type_var, ns, concept) BOOST_CLASS_REQUIRE(type_var, ns, concept);
Chris@16 107 template <typename C> void gil_function_requires() { function_requires<C>(); }
Chris@16 108 #else
Chris@16 109 #define GIL_CLASS_REQUIRE(T,NS,C)
Chris@16 110 template <typename C> void gil_function_requires() {}
Chris@16 111 #endif
Chris@16 112
Chris@16 113 /// \ingroup BasicConcepts
Chris@16 114 /**
Chris@16 115 \code
Chris@16 116 auto concept DefaultConstructible<typename T> {
Chris@16 117 T::T();
Chris@16 118 };
Chris@16 119 \endcode
Chris@16 120 */
Chris@16 121 template <typename T>
Chris@16 122 struct DefaultConstructible {
Chris@16 123 void constraints() {
Chris@16 124 function_requires<boost::DefaultConstructibleConcept<T> >();
Chris@16 125 }
Chris@16 126 };
Chris@16 127
Chris@16 128 /// \ingroup BasicConcepts
Chris@16 129 /**
Chris@16 130 \codeauto concept CopyConstructible<typename T> {
Chris@16 131 T::T(T);
Chris@16 132 T::~T();
Chris@16 133 };
Chris@16 134 \endcode
Chris@16 135 */
Chris@16 136 template <typename T>
Chris@16 137 struct CopyConstructible {
Chris@16 138 void constraints() {
Chris@16 139 function_requires<boost::CopyConstructibleConcept<T> >();
Chris@16 140 }
Chris@16 141 };
Chris@16 142
Chris@16 143 /// \ingroup BasicConcepts
Chris@16 144 /**
Chris@16 145 \code
Chris@16 146 auto concept Assignable<typename T, typename U = T> {
Chris@16 147 typename result_type;
Chris@16 148 result_type operator=(T&, U);
Chris@16 149 };
Chris@16 150 \endcode
Chris@16 151 */
Chris@16 152 template <typename T>
Chris@16 153 struct Assignable {
Chris@16 154 void constraints() {
Chris@16 155 function_requires<boost::AssignableConcept<T> >();
Chris@16 156 }
Chris@16 157 };
Chris@16 158 /// \ingroup BasicConcepts
Chris@16 159 /**
Chris@16 160 \code
Chris@16 161 auto concept EqualityComparable<typename T, typename U = T> {
Chris@16 162 bool operator==(T x, T y);
Chris@16 163 bool operator!=(T x, T y) { return !(x==y); }
Chris@16 164 };
Chris@16 165 \endcode
Chris@16 166 */
Chris@16 167 template <typename T>
Chris@16 168 struct EqualityComparable {
Chris@16 169 void constraints() {
Chris@16 170 function_requires<boost::EqualityComparableConcept<T> >();
Chris@16 171 }
Chris@16 172 };
Chris@16 173
Chris@16 174 /// \ingroup BasicConcepts
Chris@16 175 /**
Chris@16 176 \code
Chris@16 177 concept SameType<typename T, typename U>;// unspecified
Chris@16 178 \endcode
Chris@16 179 */
Chris@16 180
Chris@16 181 template <typename T, typename U>
Chris@16 182 struct SameType {
Chris@16 183 void constraints() {
Chris@16 184 BOOST_STATIC_ASSERT((boost::is_same<T,U>::value_core));
Chris@16 185 }
Chris@16 186 };
Chris@16 187
Chris@16 188 /// \ingroup BasicConcepts
Chris@16 189 /**
Chris@16 190 \code
Chris@16 191 auto concept Swappable<typename T> {
Chris@16 192 void swap(T&,T&);
Chris@16 193 };
Chris@16 194 \endcode
Chris@16 195 */
Chris@16 196 template <typename T>
Chris@16 197 struct Swappable {
Chris@16 198 void constraints() {
Chris@16 199 using std::swap;
Chris@16 200 swap(x,y);
Chris@16 201 }
Chris@16 202 T x,y;
Chris@16 203 };
Chris@16 204
Chris@16 205 /// \ingroup BasicConcepts
Chris@16 206 /**
Chris@16 207 \code
Chris@16 208 auto concept Regular<typename T> : DefaultConstructible<T>, CopyConstructible<T>, EqualityComparable<T>,
Chris@16 209 Assignable<T>, Swappable<T> {};
Chris@16 210 \endcode
Chris@16 211 */
Chris@16 212
Chris@16 213 template <typename T>
Chris@16 214 struct Regular {
Chris@16 215 void constraints() {
Chris@16 216 gil_function_requires< boost::DefaultConstructibleConcept<T> >();
Chris@16 217 gil_function_requires< boost::CopyConstructibleConcept<T> >();
Chris@16 218 gil_function_requires< boost::EqualityComparableConcept<T> >(); // ==, !=
Chris@16 219 gil_function_requires< boost::AssignableConcept<T> >();
Chris@16 220 gil_function_requires< Swappable<T> >();
Chris@16 221 }
Chris@16 222 };
Chris@16 223
Chris@16 224 /// \ingroup BasicConcepts
Chris@16 225 /**
Chris@16 226 \code
Chris@16 227 auto concept Metafunction<typename T> {
Chris@16 228 typename type;
Chris@16 229 };
Chris@16 230 \endcode
Chris@16 231 */
Chris@16 232 template <typename T>
Chris@16 233 struct Metafunction {
Chris@16 234 void constraints() {
Chris@16 235 typedef typename T::type type;
Chris@16 236 }
Chris@16 237 };
Chris@16 238 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 239 //
Chris@16 240 // POINT CONCEPTS
Chris@16 241 //
Chris@16 242 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 243
Chris@16 244 /// \brief N-dimensional point concept
Chris@16 245 /// \ingroup PointConcept
Chris@16 246 /**
Chris@16 247 \code
Chris@16 248 concept PointNDConcept<typename T> : Regular<T> {
Chris@16 249 // the type of a coordinate along each axis
Chris@16 250 template <size_t K> struct axis; where Metafunction<axis>;
Chris@16 251
Chris@16 252 const size_t num_dimensions;
Chris@16 253
Chris@16 254 // accessor/modifier of the value of each axis.
Chris@16 255 template <size_t K> const typename axis<K>::type& T::axis_value() const;
Chris@16 256 template <size_t K> typename axis<K>::type& T::axis_value();
Chris@16 257 };
Chris@16 258 \endcode
Chris@16 259 */
Chris@16 260
Chris@16 261 template <typename P>
Chris@16 262 struct PointNDConcept {
Chris@16 263 void constraints() {
Chris@16 264 gil_function_requires< Regular<P> >();
Chris@16 265
Chris@16 266 typedef typename P::value_type value_type;
Chris@16 267 static const std::size_t N=P::num_dimensions; ignore_unused_variable_warning(N);
Chris@16 268 typedef typename P::template axis<0>::coord_t FT;
Chris@16 269 typedef typename P::template axis<N-1>::coord_t LT;
Chris@16 270 FT ft=gil::axis_value<0>(point);
Chris@16 271 axis_value<0>(point)=ft;
Chris@16 272 LT lt=axis_value<N-1>(point);
Chris@16 273 axis_value<N-1>(point)=lt;
Chris@16 274
Chris@16 275 value_type v=point[0]; ignore_unused_variable_warning(v);
Chris@16 276 point[0]=point[0];
Chris@16 277 }
Chris@16 278 P point;
Chris@16 279 };
Chris@16 280
Chris@16 281 /// \brief 2-dimensional point concept
Chris@16 282 /// \ingroup PointConcept
Chris@16 283 /**
Chris@16 284 \code
Chris@16 285 concept Point2DConcept<typename T> : PointNDConcept<T> {
Chris@16 286 where num_dimensions == 2;
Chris@16 287 where SameType<axis<0>::type, axis<1>::type>;
Chris@16 288
Chris@16 289 typename value_type = axis<0>::type;
Chris@16 290
Chris@16 291 const value_type& operator[](const T&, size_t i);
Chris@16 292 value_type& operator[]( T&, size_t i);
Chris@16 293
Chris@16 294 value_type x,y;
Chris@16 295 };
Chris@16 296 \endcode
Chris@16 297 */
Chris@16 298
Chris@16 299 template <typename P>
Chris@16 300 struct Point2DConcept {
Chris@16 301 void constraints() {
Chris@16 302 gil_function_requires< PointNDConcept<P> >();
Chris@16 303 BOOST_STATIC_ASSERT(P::num_dimensions == 2);
Chris@16 304 point.x=point.y;
Chris@16 305 point[0]=point[1];
Chris@16 306 }
Chris@16 307 P point;
Chris@16 308 };
Chris@16 309
Chris@16 310 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 311 //
Chris@16 312 // ITERATOR MUTABILITY CONCEPTS
Chris@16 313 //
Chris@16 314 // Taken from boost's concept_check.hpp. Isolating mutability to result in faster compile time
Chris@16 315 //
Chris@16 316 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 317
Chris@16 318 namespace detail {
Chris@16 319 template <class TT> // Preconditions: TT Models boost_concepts::ForwardTraversalConcept
Chris@16 320 struct ForwardIteratorIsMutableConcept {
Chris@16 321 void constraints() {
Chris@16 322 *i++ = *i; // require postincrement and assignment
Chris@16 323 }
Chris@16 324 TT i;
Chris@16 325 };
Chris@16 326
Chris@16 327 template <class TT> // Preconditions: TT Models boost::BidirectionalIteratorConcept
Chris@16 328 struct BidirectionalIteratorIsMutableConcept {
Chris@16 329 void constraints() {
Chris@16 330 gil_function_requires< ForwardIteratorIsMutableConcept<TT> >();
Chris@16 331 *i-- = *i; // require postdecrement and assignment
Chris@16 332 }
Chris@16 333 TT i;
Chris@16 334 };
Chris@16 335
Chris@16 336 template <class TT> // Preconditions: TT Models boost_concepts::RandomAccessTraversalConcept
Chris@16 337 struct RandomAccessIteratorIsMutableConcept {
Chris@16 338 void constraints() {
Chris@16 339 gil_function_requires< BidirectionalIteratorIsMutableConcept<TT> >();
Chris@16 340 typename std::iterator_traits<TT>::difference_type n=0; ignore_unused_variable_warning(n);
Chris@16 341 i[n] = *i; // require element access and assignment
Chris@16 342 }
Chris@16 343 TT i;
Chris@16 344 };
Chris@16 345 } // namespace detail
Chris@16 346
Chris@16 347 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 348 //
Chris@16 349 // COLOR SPACE CONCEPTS
Chris@16 350 //
Chris@16 351 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 352
Chris@16 353 /// \brief Color space type concept
Chris@16 354 /// \ingroup ColorSpaceAndLayoutConcept
Chris@16 355 /**
Chris@16 356 \code
Chris@16 357 concept ColorSpaceConcept<MPLRandomAccessSequence Cs> {
Chris@16 358 // An MPL Random Access Sequence, whose elements are color tags
Chris@16 359 };
Chris@16 360 \endcode
Chris@16 361 */
Chris@16 362 template <typename Cs>
Chris@16 363 struct ColorSpaceConcept {
Chris@16 364 void constraints() {
Chris@16 365 // An MPL Random Access Sequence, whose elements are color tags
Chris@16 366 }
Chris@16 367 };
Chris@16 368
Chris@16 369 template <typename ColorSpace1, typename ColorSpace2> // Models ColorSpaceConcept
Chris@16 370 struct color_spaces_are_compatible : public is_same<ColorSpace1,ColorSpace2> {};
Chris@16 371
Chris@16 372 /// \brief Two color spaces are compatible if they are the same
Chris@16 373 /// \ingroup ColorSpaceAndLayoutConcept
Chris@16 374 /**
Chris@16 375 \code
Chris@16 376 concept ColorSpacesCompatibleConcept<ColorSpaceConcept Cs1, ColorSpaceConcept Cs2> {
Chris@16 377 where SameType<Cs1,Cs2>;
Chris@16 378 };
Chris@16 379 \endcode
Chris@16 380 */
Chris@16 381 template <typename Cs1, typename Cs2>
Chris@16 382 struct ColorSpacesCompatibleConcept {
Chris@16 383 void constraints() {
Chris@16 384 BOOST_STATIC_ASSERT((color_spaces_are_compatible<Cs1,Cs2>::value));
Chris@16 385 }
Chris@16 386 };
Chris@16 387
Chris@16 388 /// \brief Channel mapping concept
Chris@16 389 /// \ingroup ColorSpaceAndLayoutConcept
Chris@16 390 /**
Chris@16 391 \code
Chris@16 392 concept ChannelMappingConcept<MPLRandomAccessSequence CM> {
Chris@16 393 // An MPL Random Access Sequence, whose elements model MPLIntegralConstant representing a permutation
Chris@16 394 };
Chris@16 395 \endcode
Chris@16 396 */
Chris@16 397 template <typename CM>
Chris@16 398 struct ChannelMappingConcept {
Chris@16 399 void constraints() {
Chris@16 400 // An MPL Random Access Sequence, whose elements model MPLIntegralConstant representing a permutation
Chris@16 401 }
Chris@16 402 };
Chris@16 403
Chris@16 404
Chris@16 405
Chris@16 406 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 407 ///
Chris@16 408 /// Channel CONCEPTS
Chris@16 409 ///
Chris@16 410 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 411
Chris@16 412 /// \ingroup ChannelConcept
Chris@16 413 /// \brief A channel is the building block of a color. Color is defined as a mixture of primary colors and a channel defines the degree to which each primary color is used in the mixture.
Chris@16 414 /**
Chris@16 415 For example, in the RGB color space, using 8-bit unsigned channels, the color red is defined as [255 0 0], which means maximum of Red, and no Green and Blue.
Chris@16 416
Chris@16 417 Built-in scalar types, such as \p int and \p float, are valid GIL channels. In more complex scenarios, channels may be represented as bit ranges or even individual bits.
Chris@16 418 In such cases special classes are needed to represent the value and reference to a channel.
Chris@16 419
Chris@16 420 Channels have a traits class, \p channel_traits, which defines their associated types as well as their operating ranges.
Chris@16 421
Chris@16 422 \code
Chris@16 423 concept ChannelConcept<typename T> : EqualityComparable<T> {
Chris@16 424 typename value_type = T; // use channel_traits<T>::value_type to access it
Chris@16 425 typename reference = T&; // use channel_traits<T>::reference to access it
Chris@16 426 typename pointer = T*; // use channel_traits<T>::pointer to access it
Chris@16 427 typename const_reference = const T&; // use channel_traits<T>::const_reference to access it
Chris@16 428 typename const_pointer = const T*; // use channel_traits<T>::const_pointer to access it
Chris@16 429 static const bool is_mutable; // use channel_traits<T>::is_mutable to access it
Chris@16 430
Chris@16 431 static T min_value(); // use channel_traits<T>::min_value to access it
Chris@16 432 static T max_value(); // use channel_traits<T>::min_value to access it
Chris@16 433 };
Chris@16 434 \endcode
Chris@16 435 */
Chris@16 436 template <typename T>
Chris@16 437 struct ChannelConcept {
Chris@16 438 void constraints() {
Chris@16 439 gil_function_requires< boost::EqualityComparableConcept<T> >();
Chris@16 440
Chris@16 441 typedef typename channel_traits<T>::value_type v;
Chris@16 442 typedef typename channel_traits<T>::reference r;
Chris@16 443 typedef typename channel_traits<T>::pointer p;
Chris@16 444 typedef typename channel_traits<T>::const_reference cr;
Chris@16 445 typedef typename channel_traits<T>::const_pointer cp;
Chris@16 446
Chris@16 447 channel_traits<T>::min_value();
Chris@16 448 channel_traits<T>::max_value();
Chris@16 449 }
Chris@16 450
Chris@16 451 T c;
Chris@16 452 };
Chris@16 453
Chris@16 454 namespace detail {
Chris@16 455 // Preconditions: T models ChannelConcept
Chris@16 456 template <typename T>
Chris@16 457 struct ChannelIsMutableConcept {
Chris@16 458 void constraints() {
Chris@16 459 c=c;
Chris@16 460 using std::swap;
Chris@16 461 swap(c,c);
Chris@16 462 }
Chris@16 463 T c;
Chris@16 464 };
Chris@16 465 }
Chris@16 466
Chris@16 467 /// \brief A channel that allows for modifying its value
Chris@16 468 /// \ingroup ChannelConcept
Chris@16 469 /**
Chris@16 470 \code
Chris@16 471 concept MutableChannelConcept<ChannelConcept T> : Assignable<T>, Swappable<T> {};
Chris@16 472 \endcode
Chris@16 473 */
Chris@16 474 template <typename T>
Chris@16 475 struct MutableChannelConcept {
Chris@16 476 void constraints() {
Chris@16 477 gil_function_requires<ChannelConcept<T> >();
Chris@16 478 gil_function_requires<detail::ChannelIsMutableConcept<T> >();
Chris@16 479 }
Chris@16 480 };
Chris@16 481
Chris@16 482 /// \brief A channel that supports default construction.
Chris@16 483 /// \ingroup ChannelConcept
Chris@16 484 /**
Chris@16 485 \code
Chris@16 486 concept ChannelValueConcept<ChannelConcept T> : Regular<T> {};
Chris@16 487 \endcode
Chris@16 488 */
Chris@16 489 template <typename T>
Chris@16 490 struct ChannelValueConcept {
Chris@16 491 void constraints() {
Chris@16 492 gil_function_requires<ChannelConcept<T> >();
Chris@16 493 gil_function_requires<Regular<T> >();
Chris@16 494 }
Chris@16 495 };
Chris@16 496
Chris@16 497
Chris@16 498 /// \brief Predicate metafunction returning whether two channels are compatible
Chris@16 499 /// \ingroup ChannelAlgorithm
Chris@16 500 ///
Chris@16 501 /// Channels are considered compatible if their value types (ignoring constness and references) are the same.
Chris@16 502 /**
Chris@16 503 Example:
Chris@16 504
Chris@16 505 \code
Chris@16 506 BOOST_STATIC_ASSERT((channels_are_compatible<bits8, const bits8&>::value));
Chris@16 507 \endcode
Chris@16 508 */
Chris@16 509 template <typename T1, typename T2> // Models GIL Pixel
Chris@16 510 struct channels_are_compatible
Chris@16 511 : public is_same<typename channel_traits<T1>::value_type, typename channel_traits<T2>::value_type> {};
Chris@16 512
Chris@16 513 /// \brief Channels are compatible if their associated value types (ignoring constness and references) are the same
Chris@16 514 /// \ingroup ChannelConcept
Chris@16 515 /**
Chris@16 516 \code
Chris@16 517 concept ChannelsCompatibleConcept<ChannelConcept T1, ChannelConcept T2> {
Chris@16 518 where SameType<T1::value_type, T2::value_type>;
Chris@16 519 };
Chris@16 520 \endcode
Chris@16 521 */
Chris@16 522 template <typename T1, typename T2>
Chris@16 523 struct ChannelsCompatibleConcept {
Chris@16 524 void constraints() {
Chris@16 525 BOOST_STATIC_ASSERT((channels_are_compatible<T1,T2>::value));
Chris@16 526 }
Chris@16 527 };
Chris@16 528
Chris@16 529 /// \brief A channel is convertible to another one if the \p channel_convert algorithm is defined for the two channels
Chris@16 530 ///
Chris@16 531 /// Convertibility is non-symmetric and implies that one channel can be converted to another. Conversion is explicit and often lossy operation.
Chris@16 532 /// \ingroup ChannelConcept
Chris@16 533 /**
Chris@16 534 \code
Chris@16 535 concept ChannelConvertibleConcept<ChannelConcept SrcChannel, ChannelValueConcept DstChannel> {
Chris@16 536 DstChannel channel_convert(const SrcChannel&);
Chris@16 537 };
Chris@16 538 \endcode
Chris@16 539 */
Chris@16 540 template <typename SrcChannel, typename DstChannel>
Chris@16 541 struct ChannelConvertibleConcept {
Chris@16 542 void constraints() {
Chris@16 543 gil_function_requires<ChannelConcept<SrcChannel> >();
Chris@16 544 gil_function_requires<MutableChannelConcept<DstChannel> >();
Chris@16 545 dst=channel_convert<DstChannel,SrcChannel>(src); ignore_unused_variable_warning(dst);
Chris@16 546 }
Chris@16 547 SrcChannel src;
Chris@16 548 DstChannel dst;
Chris@16 549 };
Chris@16 550
Chris@16 551
Chris@16 552
Chris@16 553
Chris@16 554
Chris@16 555 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 556 ///
Chris@16 557 /// COLOR BASE CONCEPTS
Chris@16 558 ///
Chris@16 559 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 560
Chris@16 561 /// \ingroup ColorBaseConcept
Chris@16 562 /// \brief A color base is a container of color elements (such as channels, channel references or channel pointers)
Chris@16 563 /**
Chris@16 564 The most common use of color base is in the implementation of a pixel, in which case the color
Chris@16 565 elements are channel values. The color base concept, however, can be used in other scenarios. For example, a planar pixel has channels that are not
Chris@16 566 contiguous in memory. Its reference is a proxy class that uses a color base whose elements are channel references. Its iterator uses a color base
Chris@16 567 whose elements are channel iterators.
Chris@16 568
Chris@16 569 A color base must have an associated layout (which consists of a color space, as well as an ordering of the channels).
Chris@16 570 There are two ways to index the elements of a color base: A physical index corresponds to the way they are ordered in memory, and
Chris@16 571 a semantic index corresponds to the way the elements are ordered in their color space.
Chris@16 572 For example, in the RGB color space the elements are ordered as {red_t, green_t, blue_t}. For a color base with a BGR layout, the first element
Chris@16 573 in physical ordering is the blue element, whereas the first semantic element is the red one.
Chris@16 574 Models of \p ColorBaseConcept are required to provide the \p at_c<K>(ColorBase) function, which allows for accessing the elements based on their
Chris@16 575 physical order. GIL provides a \p semantic_at_c<K>(ColorBase) function (described later) which can operate on any model of ColorBaseConcept and returns
Chris@16 576 the corresponding semantic element.
Chris@16 577
Chris@16 578 \code
Chris@16 579 concept ColorBaseConcept<typename T> : CopyConstructible<T>, EqualityComparable<T> {
Chris@16 580 // a GIL layout (the color space and element permutation)
Chris@16 581 typename layout_t;
Chris@16 582
Chris@16 583 // The type of K-th element
Chris@16 584 template <int K> struct kth_element_type; where Metafunction<kth_element_type>;
Chris@16 585
Chris@16 586 // The result of at_c
Chris@16 587 template <int K> struct kth_element_const_reference_type; where Metafunction<kth_element_const_reference_type>;
Chris@16 588
Chris@16 589 template <int K> kth_element_const_reference_type<T,K>::type at_c(T);
Chris@16 590
Chris@16 591 // Copy-constructible and equality comparable with other compatible color bases
Chris@16 592 template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
Chris@16 593 T::T(T2);
Chris@16 594 template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
Chris@16 595 bool operator==(const T&, const T2&);
Chris@16 596 template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
Chris@16 597 bool operator!=(const T&, const T2&);
Chris@16 598
Chris@16 599 };
Chris@16 600 \endcode
Chris@16 601 */
Chris@16 602
Chris@16 603 template <typename ColorBase>
Chris@16 604 struct ColorBaseConcept {
Chris@16 605 void constraints() {
Chris@16 606 gil_function_requires< CopyConstructible<ColorBase> >();
Chris@16 607 gil_function_requires< EqualityComparable<ColorBase> >();
Chris@16 608
Chris@16 609 typedef typename ColorBase::layout_t::color_space_t color_space_t;
Chris@16 610 gil_function_requires<ColorSpaceConcept<color_space_t> >();
Chris@16 611
Chris@16 612 typedef typename ColorBase::layout_t::channel_mapping_t channel_mapping_t;
Chris@16 613 // TODO: channel_mapping_t must be an MPL RandomAccessSequence
Chris@16 614
Chris@16 615 static const std::size_t num_elements = size<ColorBase>::value;
Chris@16 616
Chris@16 617 typedef typename kth_element_type<ColorBase,num_elements-1>::type TN;
Chris@16 618 typedef typename kth_element_const_reference_type<ColorBase,num_elements-1>::type CR;
Chris@16 619
Chris@16 620 #if !defined(_MSC_VER) || _MSC_VER > 1310
Chris@16 621 CR cr=at_c<num_elements-1>(cb); ignore_unused_variable_warning(cr);
Chris@16 622 #endif
Chris@16 623
Chris@16 624 // functions that work for every pixel (no need to require them)
Chris@16 625 semantic_at_c<0>(cb);
Chris@16 626 semantic_at_c<num_elements-1>(cb);
Chris@16 627 // also static_max(cb), static_min(cb), static_fill(cb,value), and all variations of static_for_each(), static_generate(), static_transform()
Chris@16 628 }
Chris@16 629
Chris@16 630 ColorBase cb;
Chris@16 631 };
Chris@16 632
Chris@16 633 /// \ingroup ColorBaseConcept
Chris@16 634 /// \brief Color base which allows for modifying its elements
Chris@16 635 /**
Chris@16 636
Chris@16 637 \code
Chris@16 638 concept MutableColorBaseConcept<ColorBaseConcept T> : Assignable<T>, Swappable<T> {
Chris@16 639 template <int K> struct kth_element_reference_type; where Metafunction<kth_element_reference_type>;
Chris@16 640
Chris@16 641 template <int K> kth_element_reference_type<kth_element_type<T,K>::type>::type at_c(T);
Chris@16 642
Chris@16 643 template <ColorBaseConcept T2> where { ColorBasesCompatibleConcept<T,T2> }
Chris@16 644 T& operator=(T&, const T2&);
Chris@16 645 };
Chris@16 646 \endcode
Chris@16 647 */
Chris@16 648 template <typename ColorBase>
Chris@16 649 struct MutableColorBaseConcept {
Chris@16 650 void constraints() {
Chris@16 651 gil_function_requires< ColorBaseConcept<ColorBase> >();
Chris@16 652 gil_function_requires< Assignable<ColorBase> >();
Chris@16 653 gil_function_requires< Swappable<ColorBase> >();
Chris@16 654
Chris@16 655 typedef typename kth_element_reference_type<ColorBase, 0>::type CR;
Chris@16 656
Chris@16 657 #if !defined(_MSC_VER) || _MSC_VER > 1310
Chris@16 658 CR r=at_c<0>(cb);
Chris@16 659 at_c<0>(cb)=r;
Chris@16 660 #endif
Chris@16 661 }
Chris@16 662
Chris@16 663 ColorBase cb;
Chris@16 664 };
Chris@16 665
Chris@16 666 /// \ingroup ColorBaseConcept
Chris@16 667 /// \brief Color base that also has a default-constructor. Refines Regular
Chris@16 668 /**
Chris@16 669 \code
Chris@16 670 concept ColorBaseValueConcept<typename T> : MutableColorBaseConcept<T>, Regular<T> {
Chris@16 671 };
Chris@16 672 \endcode
Chris@16 673 */
Chris@16 674 template <typename ColorBase>
Chris@16 675 struct ColorBaseValueConcept {
Chris@16 676 void constraints() {
Chris@16 677 gil_function_requires< MutableColorBaseConcept<ColorBase> >();
Chris@16 678 gil_function_requires< Regular<ColorBase> >();
Chris@16 679 }
Chris@16 680 };
Chris@16 681
Chris@16 682 /// \ingroup ColorBaseConcept
Chris@16 683 /// \brief Color base whose elements all have the same type
Chris@16 684 /**
Chris@16 685 \code
Chris@16 686 concept HomogeneousColorBaseConcept<ColorBaseConcept CB> {
Chris@16 687 // For all K in [0 ... size<C1>::value-1):
Chris@16 688 // where SameType<kth_element_type<CB,K>::type, kth_element_type<CB,K+1>::type>;
Chris@16 689 kth_element_const_reference_type<CB,0>::type dynamic_at_c(const CB&, std::size_t n) const;
Chris@16 690 };
Chris@16 691 \endcode
Chris@16 692 */
Chris@16 693
Chris@16 694 template <typename ColorBase>
Chris@16 695 struct HomogeneousColorBaseConcept {
Chris@16 696 void constraints() {
Chris@16 697 gil_function_requires< ColorBaseConcept<ColorBase> >();
Chris@16 698
Chris@16 699 static const std::size_t num_elements = size<ColorBase>::value;
Chris@16 700
Chris@16 701 typedef typename kth_element_type<ColorBase,0>::type T0;
Chris@16 702 typedef typename kth_element_type<ColorBase,num_elements-1>::type TN;
Chris@16 703
Chris@16 704 BOOST_STATIC_ASSERT((is_same<T0,TN>::value)); // better than nothing
Chris@16 705 typedef typename kth_element_const_reference_type<ColorBase,0>::type CRef0;
Chris@16 706 CRef0 e0=dynamic_at_c(cb,0);
Chris@16 707 }
Chris@16 708 ColorBase cb;
Chris@16 709 };
Chris@16 710
Chris@16 711 /// \ingroup ColorBaseConcept
Chris@16 712 /// \brief Homogeneous color base that allows for modifying its elements
Chris@16 713 /**
Chris@16 714
Chris@16 715 \code
Chris@16 716 concept MutableHomogeneousColorBaseConcept<ColorBaseConcept CB> : HomogeneousColorBaseConcept<CB> {
Chris@16 717 kth_element_reference_type<CB,0>::type dynamic_at_c(CB&, std::size_t n);
Chris@16 718 };
Chris@16 719 \endcode
Chris@16 720 */
Chris@16 721
Chris@16 722 template <typename ColorBase>
Chris@16 723 struct MutableHomogeneousColorBaseConcept {
Chris@16 724 void constraints() {
Chris@16 725 gil_function_requires< ColorBaseConcept<ColorBase> >();
Chris@16 726 gil_function_requires< HomogeneousColorBaseConcept<ColorBase> >();
Chris@16 727 typedef typename kth_element_reference_type<ColorBase, 0>::type R0;
Chris@16 728 R0 x=dynamic_at_c(cb,0);
Chris@16 729 dynamic_at_c(cb,0) = dynamic_at_c(cb,0);
Chris@16 730 }
Chris@16 731 ColorBase cb;
Chris@16 732 };
Chris@16 733
Chris@16 734 /// \ingroup ColorBaseConcept
Chris@16 735 /// \brief Homogeneous color base that also has a default constructor. Refines Regular.
Chris@16 736 /**
Chris@16 737
Chris@16 738 \code
Chris@16 739 concept HomogeneousColorBaseValueConcept<typename T> : MutableHomogeneousColorBaseConcept<T>, Regular<T> {
Chris@16 740 };
Chris@16 741 \endcode
Chris@16 742 */
Chris@16 743
Chris@16 744 template <typename ColorBase>
Chris@16 745 struct HomogeneousColorBaseValueConcept {
Chris@16 746 void constraints() {
Chris@16 747 gil_function_requires< MutableHomogeneousColorBaseConcept<ColorBase> >();
Chris@16 748 gil_function_requires< Regular<ColorBase> >();
Chris@16 749 }
Chris@16 750 };
Chris@16 751
Chris@16 752
Chris@16 753 /// \ingroup ColorBaseConcept
Chris@16 754 /// \brief Two color bases are compatible if they have the same color space and their elements are compatible, semantic-pairwise.
Chris@16 755 /**
Chris@16 756
Chris@16 757 \code
Chris@16 758 concept ColorBasesCompatibleConcept<ColorBaseConcept C1, ColorBaseConcept C2> {
Chris@16 759 where SameType<C1::layout_t::color_space_t, C2::layout_t::color_space_t>;
Chris@16 760 // also, for all K in [0 ... size<C1>::value):
Chris@16 761 // where Convertible<kth_semantic_element_type<C1,K>::type, kth_semantic_element_type<C2,K>::type>;
Chris@16 762 // where Convertible<kth_semantic_element_type<C2,K>::type, kth_semantic_element_type<C1,K>::type>;
Chris@16 763 };
Chris@16 764 \endcode
Chris@16 765 */
Chris@16 766 template <typename ColorBase1, typename ColorBase2>
Chris@16 767 struct ColorBasesCompatibleConcept {
Chris@16 768 void constraints() {
Chris@16 769 BOOST_STATIC_ASSERT((is_same<typename ColorBase1::layout_t::color_space_t,
Chris@16 770 typename ColorBase2::layout_t::color_space_t>::value));
Chris@16 771 // typedef typename kth_semantic_element_type<ColorBase1,0>::type e1;
Chris@16 772 // typedef typename kth_semantic_element_type<ColorBase2,0>::type e2;
Chris@16 773 // "e1 is convertible to e2"
Chris@16 774 }
Chris@16 775 };
Chris@16 776
Chris@16 777
Chris@16 778
Chris@16 779
Chris@16 780
Chris@16 781
Chris@16 782
Chris@16 783
Chris@16 784
Chris@16 785
Chris@16 786
Chris@16 787
Chris@16 788
Chris@16 789
Chris@16 790
Chris@16 791
Chris@16 792
Chris@16 793
Chris@16 794
Chris@16 795
Chris@16 796
Chris@16 797
Chris@16 798 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 799 ///
Chris@16 800 /// PIXEL CONCEPTS
Chris@16 801 ///
Chris@16 802 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 803
Chris@16 804 /// \brief Concept for all pixel-based GIL constructs, such as pixels, iterators, locators, views and images whose value type is a pixel
Chris@16 805 /// \ingroup PixelBasedConcept
Chris@16 806 /**
Chris@16 807 \code
Chris@16 808 concept PixelBasedConcept<typename T> {
Chris@16 809 typename color_space_type<T>;
Chris@16 810 where Metafunction<color_space_type<T> >;
Chris@16 811 where ColorSpaceConcept<color_space_type<T>::type>;
Chris@16 812 typename channel_mapping_type<T>;
Chris@16 813 where Metafunction<channel_mapping_type<T> >;
Chris@16 814 where ChannelMappingConcept<channel_mapping_type<T>::type>;
Chris@16 815 typename is_planar<T>;
Chris@16 816 where Metafunction<is_planar<T> >;
Chris@16 817 where SameType<is_planar<T>::type, bool>;
Chris@16 818 };
Chris@16 819 \endcode
Chris@16 820 */
Chris@16 821 template <typename P>
Chris@16 822 struct PixelBasedConcept {
Chris@16 823 void constraints() {
Chris@16 824 typedef typename color_space_type<P>::type color_space_t;
Chris@16 825 gil_function_requires<ColorSpaceConcept<color_space_t> >();
Chris@16 826 typedef typename channel_mapping_type<P>::type channel_mapping_t;
Chris@16 827 gil_function_requires<ChannelMappingConcept<channel_mapping_t> >();
Chris@16 828
Chris@16 829 static const bool planar = is_planar<P>::type::value; ignore_unused_variable_warning(planar);
Chris@16 830
Chris@16 831
Chris@16 832 // This is not part of the concept, but should still work
Chris@16 833 static const std::size_t nc = num_channels<P>::value;
Chris@16 834 ignore_unused_variable_warning(nc);
Chris@16 835 }
Chris@16 836 };
Chris@16 837
Chris@16 838 /// \brief Concept for homogeneous pixel-based GIL constructs
Chris@16 839 /// \ingroup PixelBasedConcept
Chris@16 840 /**
Chris@16 841 \code
Chris@16 842 concept HomogeneousPixelBasedConcept<PixelBasedConcept T> {
Chris@16 843 typename channel_type<T>;
Chris@16 844 where Metafunction<channel_type<T> >;
Chris@16 845 where ChannelConcept<channel_type<T>::type>;
Chris@16 846 };
Chris@16 847 \endcode
Chris@16 848 */
Chris@16 849 template <typename P>
Chris@16 850 struct HomogeneousPixelBasedConcept {
Chris@16 851 void constraints() {
Chris@16 852 gil_function_requires<PixelBasedConcept<P> >();
Chris@16 853 typedef typename channel_type<P>::type channel_t;
Chris@16 854 gil_function_requires<ChannelConcept<channel_t> >();
Chris@16 855 }
Chris@16 856 };
Chris@16 857
Chris@16 858
Chris@16 859 /// \brief Pixel concept - A color base whose elements are channels
Chris@16 860 /// \ingroup PixelConcept
Chris@16 861 /**
Chris@16 862 \code
Chris@16 863 concept PixelConcept<typename P> : ColorBaseConcept<P>, PixelBasedConcept<P> {
Chris@16 864 where is_pixel<P>::type::value==true;
Chris@16 865 // where for each K [0..size<P>::value-1]:
Chris@16 866 // ChannelConcept<kth_element_type<P,K> >;
Chris@16 867
Chris@16 868 typename P::value_type; where PixelValueConcept<value_type>;
Chris@16 869 typename P::reference; where PixelConcept<reference>;
Chris@16 870 typename P::const_reference; where PixelConcept<const_reference>;
Chris@16 871 static const bool P::is_mutable;
Chris@16 872
Chris@16 873 template <PixelConcept P2> where { PixelConcept<P,P2> }
Chris@16 874 P::P(P2);
Chris@16 875 template <PixelConcept P2> where { PixelConcept<P,P2> }
Chris@16 876 bool operator==(const P&, const P2&);
Chris@16 877 template <PixelConcept P2> where { PixelConcept<P,P2> }
Chris@16 878 bool operator!=(const P&, const P2&);
Chris@16 879 };
Chris@16 880 \endcode
Chris@16 881 */
Chris@16 882
Chris@16 883 template <typename P>
Chris@16 884 struct PixelConcept {
Chris@16 885 void constraints() {
Chris@16 886 gil_function_requires<ColorBaseConcept<P> >();
Chris@16 887 gil_function_requires<PixelBasedConcept<P> >();
Chris@16 888
Chris@16 889 BOOST_STATIC_ASSERT((is_pixel<P>::value));
Chris@16 890 static const bool is_mutable = P::is_mutable; ignore_unused_variable_warning(is_mutable);
Chris@16 891
Chris@16 892 typedef typename P::value_type value_type;
Chris@16 893 // gil_function_requires<PixelValueConcept<value_type> >();
Chris@16 894
Chris@16 895 typedef typename P::reference reference;
Chris@16 896 gil_function_requires<PixelConcept<typename remove_const_and_reference<reference>::type> >();
Chris@16 897
Chris@16 898 typedef typename P::const_reference const_reference;
Chris@16 899 gil_function_requires<PixelConcept<typename remove_const_and_reference<const_reference>::type> >();
Chris@16 900 }
Chris@16 901 };
Chris@16 902
Chris@16 903
Chris@16 904 /// \brief Pixel concept that allows for changing its channels
Chris@16 905 /// \ingroup PixelConcept
Chris@16 906 /**
Chris@16 907 \code
Chris@16 908 concept MutablePixelConcept<PixelConcept P> : MutableColorBaseConcept<P> {
Chris@16 909 where is_mutable==true;
Chris@16 910 };
Chris@16 911 \endcode
Chris@16 912 */
Chris@16 913 template <typename P>
Chris@16 914 struct MutablePixelConcept {
Chris@16 915 void constraints() {
Chris@16 916 gil_function_requires<PixelConcept<P> >();
Chris@16 917 BOOST_STATIC_ASSERT(P::is_mutable);
Chris@16 918 }
Chris@16 919 };
Chris@16 920 /// \brief Homogeneous pixel concept
Chris@16 921 /// \ingroup PixelConcept
Chris@16 922 /**
Chris@16 923 \code
Chris@16 924 concept HomogeneousPixelConcept<PixelConcept P> : HomogeneousColorBaseConcept<P>, HomogeneousPixelBasedConcept<P> {
Chris@16 925 P::template element_const_reference_type<P>::type operator[](P p, std::size_t i) const { return dynamic_at_c(p,i); }
Chris@16 926 };
Chris@16 927 \endcode
Chris@16 928 */
Chris@16 929 template <typename P>
Chris@16 930 struct HomogeneousPixelConcept {
Chris@16 931 void constraints() {
Chris@16 932 gil_function_requires<PixelConcept<P> >();
Chris@16 933 gil_function_requires<HomogeneousColorBaseConcept<P> >();
Chris@16 934 gil_function_requires<HomogeneousPixelBasedConcept<P> >();
Chris@16 935 p[0];
Chris@16 936 }
Chris@16 937 P p;
Chris@16 938 };
Chris@16 939
Chris@16 940 /// \brief Homogeneous pixel concept that allows for changing its channels
Chris@16 941 /// \ingroup PixelConcept
Chris@16 942 /**
Chris@16 943 \code
Chris@16 944 concept MutableHomogeneousPixelConcept<HomogeneousPixelConcept P> : MutableHomogeneousColorBaseConcept<P> {
Chris@16 945 P::template element_reference_type<P>::type operator[](P p, std::size_t i) { return dynamic_at_c(p,i); }
Chris@16 946 };
Chris@16 947 \endcode
Chris@16 948 */
Chris@16 949 template <typename P>
Chris@16 950 struct MutableHomogeneousPixelConcept {
Chris@16 951 void constraints() {
Chris@16 952 gil_function_requires<HomogeneousPixelConcept<P> >();
Chris@16 953 gil_function_requires<MutableHomogeneousColorBaseConcept<P> >();
Chris@16 954 p[0]=p[0];
Chris@16 955 }
Chris@16 956 P p;
Chris@16 957 };
Chris@16 958
Chris@16 959 /// \brief Pixel concept that is a Regular type
Chris@16 960 /// \ingroup PixelConcept
Chris@16 961 /**
Chris@16 962 \code
Chris@16 963 concept PixelValueConcept<PixelConcept P> : Regular<P> {
Chris@16 964 where SameType<value_type,P>;
Chris@16 965 };
Chris@16 966 \endcode
Chris@16 967 */
Chris@16 968 template <typename P>
Chris@16 969 struct PixelValueConcept {
Chris@16 970 void constraints() {
Chris@16 971 gil_function_requires<PixelConcept<P> >();
Chris@16 972 gil_function_requires<Regular<P> >();
Chris@16 973 }
Chris@16 974 };
Chris@16 975
Chris@16 976 /// \brief Homogeneous pixel concept that is a Regular type
Chris@16 977 /// \ingroup PixelConcept
Chris@16 978 /**
Chris@16 979 \code
Chris@16 980 concept HomogeneousPixelValueConcept<HomogeneousPixelConcept P> : Regular<P> {
Chris@16 981 where SameType<value_type,P>;
Chris@16 982 };
Chris@16 983 \endcode
Chris@16 984 */
Chris@16 985 template <typename P>
Chris@16 986 struct HomogeneousPixelValueConcept {
Chris@16 987 void constraints() {
Chris@16 988 gil_function_requires<HomogeneousPixelConcept<P> >();
Chris@16 989 gil_function_requires<Regular<P> >();
Chris@16 990 BOOST_STATIC_ASSERT((is_same<P, typename P::value_type>::value));
Chris@16 991 }
Chris@16 992 };
Chris@16 993
Chris@16 994 namespace detail {
Chris@16 995 template <typename P1, typename P2, int K>
Chris@16 996 struct channels_are_pairwise_compatible : public
Chris@16 997 mpl::and_<channels_are_pairwise_compatible<P1,P2,K-1>,
Chris@16 998 channels_are_compatible<typename kth_semantic_element_reference_type<P1,K>::type,
Chris@16 999 typename kth_semantic_element_reference_type<P2,K>::type> > {};
Chris@16 1000
Chris@16 1001 template <typename P1, typename P2>
Chris@16 1002 struct channels_are_pairwise_compatible<P1,P2,-1> : public mpl::true_ {};
Chris@16 1003 }
Chris@16 1004
Chris@16 1005 /// \brief Returns whether two pixels are compatible
Chris@16 1006 ///
Chris@16 1007 /// Pixels are compatible if their channels and color space types are compatible. Compatible pixels can be assigned and copy constructed from one another.
Chris@16 1008 /// \ingroup PixelAlgorithm
Chris@16 1009 template <typename P1, typename P2> // Models GIL Pixel
Chris@16 1010 struct pixels_are_compatible
Chris@16 1011 : public mpl::and_<typename color_spaces_are_compatible<typename color_space_type<P1>::type,
Chris@16 1012 typename color_space_type<P2>::type>::type,
Chris@16 1013 detail::channels_are_pairwise_compatible<P1,P2,num_channels<P1>::value-1> > {};
Chris@16 1014
Chris@16 1015 /// \brief Concept for pixel compatibility
Chris@16 1016 /// Pixels are compatible if their channels and color space types are compatible. Compatible pixels can be assigned and copy constructed from one another.
Chris@16 1017 /// \ingroup PixelConcept
Chris@16 1018 /**
Chris@16 1019 \code
Chris@16 1020 concept PixelsCompatibleConcept<PixelConcept P1, PixelConcept P2> : ColorBasesCompatibleConcept<P1,P2> {
Chris@16 1021 // where for each K [0..size<P1>::value):
Chris@16 1022 // ChannelsCompatibleConcept<kth_semantic_element_type<P1,K>::type, kth_semantic_element_type<P2,K>::type>;
Chris@16 1023 };
Chris@16 1024 \endcode
Chris@16 1025 */
Chris@16 1026 template <typename P1, typename P2> // precondition: P1 and P2 model PixelConcept
Chris@16 1027 struct PixelsCompatibleConcept {
Chris@16 1028 void constraints() {
Chris@16 1029 BOOST_STATIC_ASSERT((pixels_are_compatible<P1,P2>::value));
Chris@16 1030 }
Chris@16 1031 };
Chris@16 1032
Chris@16 1033 /// \brief Pixel convertible concept
Chris@16 1034 ///
Chris@16 1035 /// Convertibility is non-symmetric and implies that one pixel can be converted to another, approximating the color. Conversion is explicit and sometimes lossy.
Chris@16 1036 /// \ingroup PixelConcept
Chris@16 1037 /**
Chris@16 1038 \code
Chris@16 1039 template <PixelConcept SrcPixel, MutablePixelConcept DstPixel>
Chris@16 1040 concept PixelConvertibleConcept {
Chris@16 1041 void color_convert(const SrcPixel&, DstPixel&);
Chris@16 1042 };
Chris@16 1043 \endcode
Chris@16 1044 */
Chris@16 1045 template <typename SrcP, typename DstP>
Chris@16 1046 struct PixelConvertibleConcept {
Chris@16 1047 void constraints() {
Chris@16 1048 gil_function_requires<PixelConcept<SrcP> >();
Chris@16 1049 gil_function_requires<MutablePixelConcept<DstP> >();
Chris@16 1050 color_convert(src,dst);
Chris@16 1051 }
Chris@16 1052 SrcP src;
Chris@16 1053 DstP dst;
Chris@16 1054 };
Chris@16 1055
Chris@16 1056 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 1057 ///
Chris@16 1058 /// DEREFERENCE ADAPTOR CONCEPTS
Chris@16 1059 ///
Chris@16 1060 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 1061
Chris@16 1062 /// \ingroup PixelDereferenceAdaptorConcept
Chris@16 1063
Chris@16 1064 /// \brief Represents a unary function object that can be invoked upon dereferencing a pixel iterator.
Chris@16 1065 ///
Chris@16 1066 /// This can perform an arbitrary computation, such as color conversion or table lookup
Chris@16 1067 /**
Chris@16 1068 \code
Chris@16 1069 concept PixelDereferenceAdaptorConcept<boost::UnaryFunctionConcept D>
Chris@16 1070 : DefaultConstructibleConcept<D>, CopyConstructibleConcept<D>, AssignableConcept<D> {
Chris@16 1071 typename const_t; where PixelDereferenceAdaptorConcept<const_t>;
Chris@16 1072 typename value_type; where PixelValueConcept<value_type>;
Chris@16 1073 typename reference; // may be mutable
Chris@16 1074 typename const_reference; // must not be mutable
Chris@16 1075 static const bool D::is_mutable;
Chris@16 1076
Chris@16 1077 where Convertible<value_type,result_type>;
Chris@16 1078 };
Chris@16 1079 \endcode
Chris@16 1080 */
Chris@16 1081
Chris@16 1082 template <typename D>
Chris@16 1083 struct PixelDereferenceAdaptorConcept {
Chris@16 1084 void constraints() {
Chris@16 1085 gil_function_requires< boost::UnaryFunctionConcept<D,
Chris@16 1086 typename remove_const_and_reference<typename D::result_type>::type,
Chris@16 1087 typename D::argument_type> >();
Chris@16 1088 gil_function_requires< boost::DefaultConstructibleConcept<D> >();
Chris@16 1089 gil_function_requires< boost::CopyConstructibleConcept<D> >();
Chris@16 1090 gil_function_requires< boost::AssignableConcept<D> >();
Chris@16 1091
Chris@16 1092 gil_function_requires<PixelConcept<typename remove_const_and_reference<typename D::result_type>::type> >();
Chris@16 1093
Chris@16 1094 typedef typename D::const_t const_t;
Chris@16 1095 gil_function_requires<PixelDereferenceAdaptorConcept<const_t> >();
Chris@16 1096 typedef typename D::value_type value_type;
Chris@16 1097 gil_function_requires<PixelValueConcept<value_type> >();
Chris@16 1098 typedef typename D::reference reference; // == PixelConcept (if you remove const and reference)
Chris@16 1099 typedef typename D::const_reference const_reference; // == PixelConcept (if you remove const and reference)
Chris@16 1100
Chris@16 1101 const bool is_mutable=D::is_mutable; ignore_unused_variable_warning(is_mutable);
Chris@16 1102 }
Chris@16 1103 D d;
Chris@16 1104 };
Chris@16 1105
Chris@16 1106 template <typename P>
Chris@16 1107 struct PixelDereferenceAdaptorArchetype : public std::unary_function<P, P> {
Chris@16 1108 typedef PixelDereferenceAdaptorArchetype const_t;
Chris@16 1109 typedef typename remove_reference<P>::type value_type;
Chris@16 1110 typedef typename add_reference<P>::type reference;
Chris@16 1111 typedef reference const_reference;
Chris@16 1112 static const bool is_mutable=false;
Chris@16 1113 P operator()(P x) const { throw; }
Chris@16 1114 };
Chris@16 1115
Chris@16 1116 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 1117 ///
Chris@16 1118 /// Pixel ITERATOR CONCEPTS
Chris@16 1119 ///
Chris@16 1120 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 1121
Chris@16 1122 /// \brief Concept for iterators, locators and views that can define a type just like the given iterator/locator/view, except it supports runtime specified step along the X navigation
Chris@16 1123 /// \ingroup PixelIteratorConcept
Chris@16 1124 /**
Chris@16 1125 \code
Chris@16 1126 concept HasDynamicXStepTypeConcept<typename T> {
Chris@16 1127 typename dynamic_x_step_type<T>;
Chris@16 1128 where Metafunction<dynamic_x_step_type<T> >;
Chris@16 1129 };
Chris@16 1130 \endcode
Chris@16 1131 */
Chris@16 1132 template <typename T>
Chris@16 1133 struct HasDynamicXStepTypeConcept {
Chris@16 1134 void constraints() {
Chris@16 1135 typedef typename dynamic_x_step_type<T>::type type;
Chris@16 1136 }
Chris@16 1137 };
Chris@16 1138
Chris@16 1139 /// \brief Concept for locators and views that can define a type just like the given locator or view, except it supports runtime specified step along the Y navigation
Chris@16 1140 /// \ingroup PixelLocatorConcept
Chris@16 1141 /**
Chris@16 1142 \code
Chris@16 1143 concept HasDynamicYStepTypeConcept<typename T> {
Chris@16 1144 typename dynamic_y_step_type<T>;
Chris@16 1145 where Metafunction<dynamic_y_step_type<T> >;
Chris@16 1146 };
Chris@16 1147 \endcode
Chris@16 1148 */
Chris@16 1149 template <typename T>
Chris@16 1150 struct HasDynamicYStepTypeConcept {
Chris@16 1151 void constraints() {
Chris@16 1152 typedef typename dynamic_y_step_type<T>::type type;
Chris@16 1153 }
Chris@16 1154 };
Chris@16 1155
Chris@16 1156
Chris@16 1157 /// \brief Concept for locators and views that can define a type just like the given locator or view, except X and Y is swapped
Chris@16 1158 /// \ingroup PixelLocatorConcept
Chris@16 1159 /**
Chris@16 1160 \code
Chris@16 1161 concept HasTransposedTypeConcept<typename T> {
Chris@16 1162 typename transposed_type<T>;
Chris@16 1163 where Metafunction<transposed_type<T> >;
Chris@16 1164 };
Chris@16 1165 \endcode
Chris@16 1166 */
Chris@16 1167 template <typename T>
Chris@16 1168 struct HasTransposedTypeConcept {
Chris@16 1169 void constraints() {
Chris@16 1170 typedef typename transposed_type<T>::type type;
Chris@16 1171 }
Chris@16 1172 };
Chris@16 1173
Chris@16 1174 /// \defgroup PixelIteratorConceptPixelIterator PixelIteratorConcept
Chris@16 1175 /// \ingroup PixelIteratorConcept
Chris@16 1176 /// \brief STL iterator over pixels
Chris@16 1177
Chris@16 1178 /// \ingroup PixelIteratorConceptPixelIterator
Chris@16 1179 /// \brief An STL random access traversal iterator over a model of PixelConcept.
Chris@16 1180 /**
Chris@16 1181 GIL's iterators must also provide the following metafunctions:
Chris@16 1182 - \p const_iterator_type<Iterator>: Returns a read-only equivalent of \p Iterator
Chris@16 1183 - \p iterator_is_mutable<Iterator>: Returns whether the given iterator is read-only or mutable
Chris@16 1184 - \p is_iterator_adaptor<Iterator>: Returns whether the given iterator is an adaptor over another iterator. See IteratorAdaptorConcept for additional requirements of adaptors.
Chris@16 1185
Chris@16 1186 \code
Chris@16 1187 concept PixelIteratorConcept<typename Iterator> : boost_concepts::RandomAccessTraversalConcept<Iterator>, PixelBasedConcept<Iterator> {
Chris@16 1188 where PixelValueConcept<value_type>;
Chris@16 1189 typename const_iterator_type<It>::type;
Chris@16 1190 where PixelIteratorConcept<const_iterator_type<It>::type>;
Chris@16 1191 static const bool iterator_is_mutable<It>::type::value;
Chris@16 1192 static const bool is_iterator_adaptor<It>::type::value; // is it an iterator adaptor
Chris@16 1193 };
Chris@16 1194 \endcode
Chris@16 1195 */
Chris@16 1196 template <typename Iterator>
Chris@16 1197 struct PixelIteratorConcept {
Chris@16 1198 void constraints() {
Chris@16 1199 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<Iterator> >();
Chris@16 1200 gil_function_requires<PixelBasedConcept<Iterator> >();
Chris@16 1201
Chris@16 1202 typedef typename std::iterator_traits<Iterator>::value_type value_type;
Chris@16 1203 gil_function_requires<PixelValueConcept<value_type> >();
Chris@16 1204
Chris@16 1205 typedef typename const_iterator_type<Iterator>::type const_t;
Chris@16 1206 static const bool is_mut = iterator_is_mutable<Iterator>::type::value; ignore_unused_variable_warning(is_mut);
Chris@16 1207
Chris@16 1208 const_t const_it(it); ignore_unused_variable_warning(const_it); // immutable iterator must be constructible from (possibly mutable) iterator
Chris@16 1209
Chris@16 1210 check_base(typename is_iterator_adaptor<Iterator>::type());
Chris@16 1211 }
Chris@16 1212 void check_base(mpl::false_) {}
Chris@16 1213 void check_base(mpl::true_) {
Chris@16 1214 typedef typename iterator_adaptor_get_base<Iterator>::type base_t;
Chris@16 1215 gil_function_requires<PixelIteratorConcept<base_t> >();
Chris@16 1216 }
Chris@16 1217
Chris@16 1218 Iterator it;
Chris@16 1219 };
Chris@16 1220
Chris@16 1221 namespace detail {
Chris@16 1222 template <typename Iterator> // Preconditions: Iterator Models PixelIteratorConcept
Chris@16 1223 struct PixelIteratorIsMutableConcept {
Chris@16 1224 void constraints() {
Chris@16 1225 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<Iterator> >();
Chris@16 1226 typedef typename remove_reference<typename std::iterator_traits<Iterator>::reference>::type ref;
Chris@16 1227 typedef typename element_type<ref>::type channel_t;
Chris@16 1228 gil_function_requires<detail::ChannelIsMutableConcept<channel_t> >();
Chris@16 1229 }
Chris@16 1230 };
Chris@16 1231 }
Chris@16 1232
Chris@16 1233 /// \brief Pixel iterator that allows for changing its pixel
Chris@16 1234 /// \ingroup PixelIteratorConceptPixelIterator
Chris@16 1235 /**
Chris@16 1236 \code
Chris@16 1237 concept MutablePixelIteratorConcept<PixelIteratorConcept Iterator> : MutableRandomAccessIteratorConcept<Iterator> {};
Chris@16 1238
Chris@16 1239 \endcode
Chris@16 1240 */
Chris@16 1241 template <typename Iterator>
Chris@16 1242 struct MutablePixelIteratorConcept {
Chris@16 1243 void constraints() {
Chris@16 1244 gil_function_requires<PixelIteratorConcept<Iterator> >();
Chris@16 1245 gil_function_requires<detail::PixelIteratorIsMutableConcept<Iterator> >();
Chris@16 1246 }
Chris@16 1247 };
Chris@16 1248
Chris@16 1249 namespace detail {
Chris@16 1250 // Iterators that can be used as the base of memory_based_step_iterator require some additional functions
Chris@16 1251 template <typename Iterator> // Preconditions: Iterator Models boost_concepts::RandomAccessTraversalConcept
Chris@16 1252 struct RandomAccessIteratorIsMemoryBasedConcept {
Chris@16 1253 void constraints() {
Chris@16 1254 std::ptrdiff_t bs=memunit_step(it); ignore_unused_variable_warning(bs);
Chris@16 1255 it=memunit_advanced(it,3);
Chris@16 1256 std::ptrdiff_t bd=memunit_distance(it,it); ignore_unused_variable_warning(bd);
Chris@16 1257 memunit_advance(it,3);
Chris@16 1258 // for performace you may also provide a customized implementation of memunit_advanced_ref
Chris@16 1259 }
Chris@16 1260 Iterator it;
Chris@16 1261 };
Chris@16 1262 }
Chris@16 1263
Chris@16 1264 /// \defgroup PixelIteratorConceptStepIterator StepIteratorConcept
Chris@16 1265 /// \ingroup PixelIteratorConcept
Chris@16 1266 /// \brief Iterator that advances by a specified step
Chris@16 1267
Chris@16 1268 /// \brief Concept of a random-access iterator that can be advanced in memory units (bytes or bits)
Chris@16 1269 /// \ingroup PixelIteratorConceptStepIterator
Chris@16 1270 /**
Chris@16 1271 \code
Chris@16 1272 concept MemoryBasedIteratorConcept<boost_concepts::RandomAccessTraversalConcept Iterator> {
Chris@16 1273 typename byte_to_memunit<Iterator>; where metafunction<byte_to_memunit<Iterator> >;
Chris@16 1274 std::ptrdiff_t memunit_step(const Iterator&);
Chris@16 1275 std::ptrdiff_t memunit_distance(const Iterator& , const Iterator&);
Chris@16 1276 void memunit_advance(Iterator&, std::ptrdiff_t diff);
Chris@16 1277 Iterator memunit_advanced(const Iterator& p, std::ptrdiff_t diff) { Iterator tmp; memunit_advance(tmp,diff); return tmp; }
Chris@16 1278 Iterator::reference memunit_advanced_ref(const Iterator& p, std::ptrdiff_t diff) { return *memunit_advanced(p,diff); }
Chris@16 1279 };
Chris@16 1280 \endcode
Chris@16 1281 */
Chris@16 1282 template <typename Iterator>
Chris@16 1283 struct MemoryBasedIteratorConcept {
Chris@16 1284 void constraints() {
Chris@16 1285 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<Iterator> >();
Chris@16 1286 gil_function_requires<detail::RandomAccessIteratorIsMemoryBasedConcept<Iterator> >();
Chris@16 1287 }
Chris@16 1288 };
Chris@16 1289
Chris@16 1290 /// \brief Step iterator concept
Chris@16 1291 ///
Chris@16 1292 /// Step iterators are iterators that have a set_step method
Chris@16 1293 /// \ingroup PixelIteratorConceptStepIterator
Chris@16 1294 /**
Chris@16 1295 \code
Chris@16 1296 concept StepIteratorConcept<boost_concepts::ForwardTraversalConcept Iterator> {
Chris@16 1297 template <Integral D> void Iterator::set_step(D step);
Chris@16 1298 };
Chris@16 1299 \endcode
Chris@16 1300 */
Chris@16 1301 template <typename Iterator>
Chris@16 1302 struct StepIteratorConcept {
Chris@16 1303 void constraints() {
Chris@16 1304 gil_function_requires<boost_concepts::ForwardTraversalConcept<Iterator> >();
Chris@16 1305 it.set_step(0);
Chris@16 1306 }
Chris@16 1307 Iterator it;
Chris@16 1308 };
Chris@16 1309
Chris@16 1310
Chris@16 1311 /// \brief Step iterator that allows for modifying its current value
Chris@16 1312 ///
Chris@16 1313 /// \ingroup PixelIteratorConceptStepIterator
Chris@16 1314 /**
Chris@16 1315 \code
Chris@16 1316 concept MutableStepIteratorConcept<Mutable_ForwardIteratorConcept Iterator> : StepIteratorConcept<Iterator> {};
Chris@16 1317 \endcode
Chris@16 1318 */
Chris@16 1319 template <typename Iterator>
Chris@16 1320 struct MutableStepIteratorConcept {
Chris@16 1321 void constraints() {
Chris@16 1322 gil_function_requires<StepIteratorConcept<Iterator> >();
Chris@16 1323 gil_function_requires<detail::ForwardIteratorIsMutableConcept<Iterator> >();
Chris@16 1324 }
Chris@16 1325 };
Chris@16 1326
Chris@16 1327 /// \defgroup PixelIteratorConceptIteratorAdaptor IteratorAdaptorConcept
Chris@16 1328 /// \ingroup PixelIteratorConcept
Chris@16 1329 /// \brief Adaptor over another iterator
Chris@16 1330
Chris@16 1331 /// \ingroup PixelIteratorConceptIteratorAdaptor
Chris@16 1332 /// \brief Iterator adaptor is a forward iterator adapting another forward iterator.
Chris@16 1333 /**
Chris@16 1334 In addition to GIL iterator requirements, GIL iterator adaptors must provide the following metafunctions:
Chris@16 1335 - \p is_iterator_adaptor<Iterator>: Returns \p mpl::true_
Chris@16 1336 - \p iterator_adaptor_get_base<Iterator>: Returns the base iterator type
Chris@16 1337 - \p iterator_adaptor_rebind<Iterator,NewBase>: Replaces the base iterator with the new one
Chris@16 1338
Chris@16 1339 The adaptee can be obtained from the iterator via the "base()" method.
Chris@16 1340
Chris@16 1341 \code
Chris@16 1342 concept IteratorAdaptorConcept<boost_concepts::ForwardTraversalConcept Iterator> {
Chris@16 1343 where SameType<is_iterator_adaptor<Iterator>::type, mpl::true_>;
Chris@16 1344
Chris@16 1345 typename iterator_adaptor_get_base<Iterator>;
Chris@16 1346 where Metafunction<iterator_adaptor_get_base<Iterator> >;
Chris@16 1347 where boost_concepts::ForwardTraversalConcept<iterator_adaptor_get_base<Iterator>::type>;
Chris@16 1348
Chris@16 1349 typename another_iterator;
Chris@16 1350 typename iterator_adaptor_rebind<Iterator,another_iterator>::type;
Chris@16 1351 where boost_concepts::ForwardTraversalConcept<another_iterator>;
Chris@16 1352 where IteratorAdaptorConcept<iterator_adaptor_rebind<Iterator,another_iterator>::type>;
Chris@16 1353
Chris@16 1354 const iterator_adaptor_get_base<Iterator>::type& Iterator::base() const;
Chris@16 1355 };
Chris@16 1356 \endcode
Chris@16 1357 */
Chris@16 1358 template <typename Iterator>
Chris@16 1359 struct IteratorAdaptorConcept {
Chris@16 1360 void constraints() {
Chris@16 1361 gil_function_requires<boost_concepts::ForwardTraversalConcept<Iterator> >();
Chris@16 1362
Chris@16 1363 typedef typename iterator_adaptor_get_base<Iterator>::type base_t;
Chris@16 1364 gil_function_requires<boost_concepts::ForwardTraversalConcept<base_t> >();
Chris@16 1365
Chris@16 1366 BOOST_STATIC_ASSERT(is_iterator_adaptor<Iterator>::value);
Chris@16 1367 typedef typename iterator_adaptor_rebind<Iterator, void*>::type rebind_t;
Chris@16 1368
Chris@16 1369 base_t base=it.base(); ignore_unused_variable_warning(base);
Chris@16 1370 }
Chris@16 1371 Iterator it;
Chris@16 1372 };
Chris@16 1373
Chris@16 1374 /// \brief Iterator adaptor that is mutable
Chris@16 1375 /// \ingroup PixelIteratorConceptIteratorAdaptor
Chris@16 1376 /**
Chris@16 1377 \code
Chris@16 1378 concept MutableIteratorAdaptorConcept<Mutable_ForwardIteratorConcept Iterator> : IteratorAdaptorConcept<Iterator> {};
Chris@16 1379 \endcode
Chris@16 1380 */
Chris@16 1381 template <typename Iterator>
Chris@16 1382 struct MutableIteratorAdaptorConcept {
Chris@16 1383 void constraints() {
Chris@16 1384 gil_function_requires<IteratorAdaptorConcept<Iterator> >();
Chris@16 1385 gil_function_requires<detail::ForwardIteratorIsMutableConcept<Iterator> >();
Chris@16 1386 }
Chris@16 1387 };
Chris@16 1388
Chris@16 1389 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 1390 ///
Chris@16 1391 /// LOCATOR CONCEPTS
Chris@16 1392 ///
Chris@16 1393 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 1394
Chris@16 1395 /// \defgroup LocatorNDConcept RandomAccessNDLocatorConcept
Chris@16 1396 /// \ingroup PixelLocatorConcept
Chris@16 1397 /// \brief N-dimensional locator
Chris@16 1398
Chris@16 1399 /// \defgroup Locator2DConcept RandomAccess2DLocatorConcept
Chris@16 1400 /// \ingroup PixelLocatorConcept
Chris@16 1401 /// \brief 2-dimensional locator
Chris@16 1402
Chris@16 1403 /// \defgroup PixelLocator2DConcept PixelLocatorConcept
Chris@16 1404 /// \ingroup PixelLocatorConcept
Chris@16 1405 /// \brief 2-dimensional locator over pixel data
Chris@16 1406
Chris@16 1407 /// \ingroup LocatorNDConcept
Chris@16 1408 /// \brief N-dimensional locator over immutable values
Chris@16 1409 /**
Chris@16 1410 \code
Chris@16 1411 concept RandomAccessNDLocatorConcept<Regular Loc> {
Chris@16 1412 typename value_type; // value over which the locator navigates
Chris@16 1413 typename reference; // result of dereferencing
Chris@16 1414 typename difference_type; where PointNDConcept<difference_type>; // return value of operator-.
Chris@16 1415 typename const_t; // same as Loc, but operating over immutable values
Chris@16 1416 typename cached_location_t; // type to store relative location (for efficient repeated access)
Chris@16 1417 typename point_t = difference_type;
Chris@16 1418
Chris@16 1419 static const size_t num_dimensions; // dimensionality of the locator
Chris@16 1420 where num_dimensions = point_t::num_dimensions;
Chris@16 1421
Chris@16 1422 // The difference_type and iterator type along each dimension. The iterators may only differ in
Chris@16 1423 // difference_type. Their value_type must be the same as Loc::value_type
Chris@16 1424 template <size_t D> struct axis {
Chris@16 1425 typename coord_t = point_t::axis<D>::coord_t;
Chris@16 1426 typename iterator; where RandomAccessTraversalConcept<iterator>; // iterator along D-th axis.
Chris@16 1427 where iterator::value_type == value_type;
Chris@16 1428 };
Chris@16 1429
Chris@16 1430 // Defines the type of a locator similar to this type, except it invokes Deref upon dereferencing
Chris@16 1431 template <PixelDereferenceAdaptorConcept Deref> struct add_deref {
Chris@16 1432 typename type; where RandomAccessNDLocatorConcept<type>;
Chris@16 1433 static type make(const Loc& loc, const Deref& deref);
Chris@16 1434 };
Chris@16 1435
Chris@16 1436 Loc& operator+=(Loc&, const difference_type&);
Chris@16 1437 Loc& operator-=(Loc&, const difference_type&);
Chris@16 1438 Loc operator+(const Loc&, const difference_type&);
Chris@16 1439 Loc operator-(const Loc&, const difference_type&);
Chris@16 1440
Chris@16 1441 reference operator*(const Loc&);
Chris@16 1442 reference operator[](const Loc&, const difference_type&);
Chris@16 1443
Chris@16 1444 // Storing relative location for faster repeated access and accessing it
Chris@16 1445 cached_location_t Loc::cache_location(const difference_type&) const;
Chris@16 1446 reference operator[](const Loc&,const cached_location_t&);
Chris@16 1447
Chris@16 1448 // Accessing iterators along a given dimension at the current location or at a given offset
Chris@16 1449 template <size_t D> axis<D>::iterator& Loc::axis_iterator();
Chris@16 1450 template <size_t D> axis<D>::iterator const& Loc::axis_iterator() const;
Chris@16 1451 template <size_t D> axis<D>::iterator Loc::axis_iterator(const difference_type&) const;
Chris@16 1452 };
Chris@16 1453 \endcode
Chris@16 1454 */
Chris@16 1455 template <typename Loc>
Chris@16 1456 struct RandomAccessNDLocatorConcept {
Chris@16 1457 void constraints() {
Chris@16 1458 gil_function_requires< Regular<Loc> >();
Chris@16 1459
Chris@16 1460 typedef typename Loc::value_type value_type;
Chris@16 1461 typedef typename Loc::reference reference; // result of dereferencing
Chris@16 1462 typedef typename Loc::difference_type difference_type; // result of operator-(pixel_locator, pixel_locator)
Chris@16 1463 typedef typename Loc::cached_location_t cached_location_t; // type used to store relative location (to allow for more efficient repeated access)
Chris@16 1464 typedef typename Loc::const_t const_t; // same as this type, but over const values
Chris@16 1465 typedef typename Loc::point_t point_t; // same as difference_type
Chris@16 1466 static const std::size_t N=Loc::num_dimensions; ignore_unused_variable_warning(N);
Chris@16 1467
Chris@16 1468 typedef typename Loc::template axis<0>::iterator first_it_type;
Chris@16 1469 typedef typename Loc::template axis<N-1>::iterator last_it_type;
Chris@16 1470 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<first_it_type> >();
Chris@16 1471 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<last_it_type> >();
Chris@16 1472
Chris@16 1473 // point_t must be an N-dimensional point, each dimension of which must have the same type as difference_type of the corresponding iterator
Chris@16 1474 gil_function_requires<PointNDConcept<point_t> >();
Chris@16 1475 BOOST_STATIC_ASSERT(point_t::num_dimensions==N);
Chris@16 1476 BOOST_STATIC_ASSERT((is_same<typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value));
Chris@16 1477 BOOST_STATIC_ASSERT((is_same<typename std::iterator_traits<last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value));
Chris@16 1478
Chris@16 1479 difference_type d;
Chris@16 1480 loc+=d;
Chris@16 1481 loc-=d;
Chris@16 1482 loc=loc+d;
Chris@16 1483 loc=loc-d;
Chris@16 1484 reference r1=loc[d]; ignore_unused_variable_warning(r1);
Chris@16 1485 reference r2=*loc; ignore_unused_variable_warning(r2);
Chris@16 1486 cached_location_t cl=loc.cache_location(d); ignore_unused_variable_warning(cl);
Chris@16 1487 reference r3=loc[d]; ignore_unused_variable_warning(r3);
Chris@16 1488
Chris@16 1489 first_it_type fi=loc.template axis_iterator<0>();
Chris@16 1490 fi=loc.template axis_iterator<0>(d);
Chris@16 1491 last_it_type li=loc.template axis_iterator<N-1>();
Chris@16 1492 li=loc.template axis_iterator<N-1>(d);
Chris@16 1493
Chris@16 1494 typedef PixelDereferenceAdaptorArchetype<typename Loc::value_type> deref_t;
Chris@16 1495 typedef typename Loc::template add_deref<deref_t>::type dtype;
Chris@16 1496 //gil_function_requires<RandomAccessNDLocatorConcept<dtype> >(); // infinite recursion
Chris@16 1497 }
Chris@16 1498 Loc loc;
Chris@16 1499 };
Chris@16 1500
Chris@16 1501 /// \ingroup Locator2DConcept
Chris@16 1502 /// \brief 2-dimensional locator over immutable values
Chris@16 1503 /**
Chris@16 1504 \code
Chris@16 1505 concept RandomAccess2DLocatorConcept<RandomAccessNDLocatorConcept Loc> {
Chris@16 1506 where num_dimensions==2;
Chris@16 1507 where Point2DConcept<point_t>;
Chris@16 1508
Chris@16 1509 typename x_iterator = axis<0>::iterator;
Chris@16 1510 typename y_iterator = axis<1>::iterator;
Chris@16 1511 typename x_coord_t = axis<0>::coord_t;
Chris@16 1512 typename y_coord_t = axis<1>::coord_t;
Chris@16 1513
Chris@16 1514 // Only available to locators that have dynamic step in Y
Chris@16 1515 //Loc::Loc(const Loc& loc, y_coord_t);
Chris@16 1516
Chris@16 1517 // Only available to locators that have dynamic step in X and Y
Chris@16 1518 //Loc::Loc(const Loc& loc, x_coord_t, y_coord_t, bool transposed=false);
Chris@16 1519
Chris@16 1520 x_iterator& Loc::x();
Chris@16 1521 x_iterator const& Loc::x() const;
Chris@16 1522 y_iterator& Loc::y();
Chris@16 1523 y_iterator const& Loc::y() const;
Chris@16 1524
Chris@16 1525 x_iterator Loc::x_at(const difference_type&) const;
Chris@16 1526 y_iterator Loc::y_at(const difference_type&) const;
Chris@16 1527 Loc Loc::xy_at(const difference_type&) const;
Chris@16 1528
Chris@16 1529 // x/y versions of all methods that can take difference type
Chris@16 1530 x_iterator Loc::x_at(x_coord_t, y_coord_t) const;
Chris@16 1531 y_iterator Loc::y_at(x_coord_t, y_coord_t) const;
Chris@16 1532 Loc Loc::xy_at(x_coord_t, y_coord_t) const;
Chris@16 1533 reference operator()(const Loc&, x_coord_t, y_coord_t);
Chris@16 1534 cached_location_t Loc::cache_location(x_coord_t, y_coord_t) const;
Chris@16 1535
Chris@16 1536 bool Loc::is_1d_traversable(x_coord_t width) const;
Chris@16 1537 y_coord_t Loc::y_distance_to(const Loc& loc2, x_coord_t x_diff) const;
Chris@16 1538 };
Chris@16 1539 \endcode
Chris@16 1540 */
Chris@16 1541 template <typename Loc>
Chris@16 1542 struct RandomAccess2DLocatorConcept {
Chris@16 1543 void constraints() {
Chris@16 1544 gil_function_requires<RandomAccessNDLocatorConcept<Loc> >();
Chris@16 1545 BOOST_STATIC_ASSERT(Loc::num_dimensions==2);
Chris@16 1546
Chris@16 1547 typedef typename dynamic_x_step_type<Loc>::type dynamic_x_step_t;
Chris@16 1548 typedef typename dynamic_y_step_type<Loc>::type dynamic_y_step_t;
Chris@16 1549 typedef typename transposed_type<Loc>::type transposed_t;
Chris@16 1550
Chris@16 1551 typedef typename Loc::cached_location_t cached_location_t;
Chris@16 1552 gil_function_requires<Point2DConcept<typename Loc::point_t> >();
Chris@16 1553
Chris@16 1554 typedef typename Loc::x_iterator x_iterator;
Chris@16 1555 typedef typename Loc::y_iterator y_iterator;
Chris@16 1556 typedef typename Loc::x_coord_t x_coord_t;
Chris@16 1557 typedef typename Loc::y_coord_t y_coord_t;
Chris@16 1558
Chris@16 1559 x_coord_t xd=0; ignore_unused_variable_warning(xd);
Chris@16 1560 y_coord_t yd=0; ignore_unused_variable_warning(yd);
Chris@16 1561
Chris@16 1562 typename Loc::difference_type d;
Chris@16 1563 typename Loc::reference r=loc(xd,yd); ignore_unused_variable_warning(r);
Chris@16 1564
Chris@16 1565 dynamic_x_step_t loc2(dynamic_x_step_t(), yd);
Chris@16 1566 dynamic_x_step_t loc3(dynamic_x_step_t(), xd, yd);
Chris@16 1567
Chris@16 1568 typedef typename dynamic_y_step_type<typename dynamic_x_step_type<transposed_t>::type>::type dynamic_xy_step_transposed_t;
Chris@16 1569 dynamic_xy_step_transposed_t loc4(loc, xd,yd,true);
Chris@16 1570
Chris@16 1571 bool is_contiguous=loc.is_1d_traversable(xd); ignore_unused_variable_warning(is_contiguous);
Chris@16 1572 loc.y_distance_to(loc, xd);
Chris@16 1573
Chris@16 1574 loc=loc.xy_at(d);
Chris@16 1575 loc=loc.xy_at(xd,yd);
Chris@16 1576
Chris@16 1577 x_iterator xit=loc.x_at(d);
Chris@16 1578 xit=loc.x_at(xd,yd);
Chris@16 1579 xit=loc.x();
Chris@16 1580
Chris@16 1581 y_iterator yit=loc.y_at(d);
Chris@16 1582 yit=loc.y_at(xd,yd);
Chris@16 1583 yit=loc.y();
Chris@16 1584
Chris@16 1585 cached_location_t cl=loc.cache_location(xd,yd); ignore_unused_variable_warning(cl);
Chris@16 1586 }
Chris@16 1587 Loc loc;
Chris@16 1588 };
Chris@16 1589
Chris@16 1590 /// \ingroup PixelLocator2DConcept
Chris@16 1591 /// \brief GIL's 2-dimensional locator over immutable GIL pixels
Chris@16 1592 /**
Chris@16 1593 \code
Chris@16 1594 concept PixelLocatorConcept<RandomAccess2DLocatorConcept Loc> {
Chris@16 1595 where PixelValueConcept<value_type>;
Chris@16 1596 where PixelIteratorConcept<x_iterator>;
Chris@16 1597 where PixelIteratorConcept<y_iterator>;
Chris@16 1598 where x_coord_t == y_coord_t;
Chris@16 1599
Chris@16 1600 typename coord_t = x_coord_t;
Chris@16 1601 };
Chris@16 1602 \endcode
Chris@16 1603 */
Chris@16 1604 template <typename Loc>
Chris@16 1605 struct PixelLocatorConcept {
Chris@16 1606 void constraints() {
Chris@16 1607 gil_function_requires< RandomAccess2DLocatorConcept<Loc> >();
Chris@16 1608 gil_function_requires< PixelIteratorConcept<typename Loc::x_iterator> >();
Chris@16 1609 gil_function_requires< PixelIteratorConcept<typename Loc::y_iterator> >();
Chris@16 1610 typedef typename Loc::coord_t coord_t;
Chris@16 1611 BOOST_STATIC_ASSERT((is_same<typename Loc::x_coord_t, typename Loc::y_coord_t>::value));
Chris@16 1612 }
Chris@16 1613 Loc loc;
Chris@16 1614 };
Chris@16 1615
Chris@16 1616 namespace detail {
Chris@16 1617 template <typename Loc> // preconditions: Loc Models RandomAccessNDLocatorConcept
Chris@16 1618 struct RandomAccessNDLocatorIsMutableConcept {
Chris@16 1619 void constraints() {
Chris@16 1620 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename Loc::template axis<0>::iterator> >();
Chris@16 1621 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename Loc::template axis<Loc::num_dimensions-1>::iterator> >();
Chris@16 1622
Chris@16 1623 typename Loc::difference_type d; initialize_it(d);
Chris@16 1624 typename Loc::value_type v;initialize_it(v);
Chris@16 1625 typename Loc::cached_location_t cl=loc.cache_location(d);
Chris@16 1626 *loc=v;
Chris@16 1627 loc[d]=v;
Chris@16 1628 loc[cl]=v;
Chris@16 1629 }
Chris@16 1630 Loc loc;
Chris@16 1631 };
Chris@16 1632
Chris@16 1633 template <typename Loc> // preconditions: Loc Models RandomAccess2DLocatorConcept
Chris@16 1634 struct RandomAccess2DLocatorIsMutableConcept {
Chris@16 1635 void constraints() {
Chris@16 1636 gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<Loc> >();
Chris@16 1637 typename Loc::x_coord_t xd=0; ignore_unused_variable_warning(xd);
Chris@16 1638 typename Loc::y_coord_t yd=0; ignore_unused_variable_warning(yd);
Chris@16 1639 typename Loc::value_type v; initialize_it(v);
Chris@16 1640 loc(xd,yd)=v;
Chris@16 1641 }
Chris@16 1642 Loc loc;
Chris@16 1643 };
Chris@16 1644 }
Chris@16 1645
Chris@16 1646 /// \ingroup LocatorNDConcept
Chris@16 1647 /// \brief N-dimensional locator over mutable pixels
Chris@16 1648 /**
Chris@16 1649 \code
Chris@16 1650 concept MutableRandomAccessNDLocatorConcept<RandomAccessNDLocatorConcept Loc> {
Chris@16 1651 where Mutable<reference>;
Chris@16 1652 };
Chris@16 1653 \endcode
Chris@16 1654 */
Chris@16 1655 template <typename Loc>
Chris@16 1656 struct MutableRandomAccessNDLocatorConcept {
Chris@16 1657 void constraints() {
Chris@16 1658 gil_function_requires<RandomAccessNDLocatorConcept<Loc> >();
Chris@16 1659 gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<Loc> >();
Chris@16 1660 }
Chris@16 1661 };
Chris@16 1662
Chris@16 1663 /// \ingroup Locator2DConcept
Chris@16 1664 /// \brief 2-dimensional locator over mutable pixels
Chris@16 1665 /**
Chris@16 1666 \code
Chris@16 1667 concept MutableRandomAccess2DLocatorConcept<RandomAccess2DLocatorConcept Loc> : MutableRandomAccessNDLocatorConcept<Loc> {};
Chris@16 1668 \endcode
Chris@16 1669 */
Chris@16 1670 template <typename Loc>
Chris@16 1671 struct MutableRandomAccess2DLocatorConcept {
Chris@16 1672 void constraints() {
Chris@16 1673 gil_function_requires< RandomAccess2DLocatorConcept<Loc> >();
Chris@16 1674 gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<Loc> >();
Chris@16 1675 }
Chris@16 1676 };
Chris@16 1677
Chris@16 1678 /// \ingroup PixelLocator2DConcept
Chris@16 1679 /// \brief GIL's 2-dimensional locator over mutable GIL pixels
Chris@16 1680 /**
Chris@16 1681 \code
Chris@16 1682 concept MutablePixelLocatorConcept<PixelLocatorConcept Loc> : MutableRandomAccess2DLocatorConcept<Loc> {};
Chris@16 1683 \endcode
Chris@16 1684 */
Chris@16 1685 template <typename Loc>
Chris@16 1686 struct MutablePixelLocatorConcept {
Chris@16 1687 void constraints() {
Chris@16 1688 gil_function_requires<PixelLocatorConcept<Loc> >();
Chris@16 1689 gil_function_requires<detail::RandomAccess2DLocatorIsMutableConcept<Loc> >();
Chris@16 1690 }
Chris@16 1691 };
Chris@16 1692
Chris@16 1693 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 1694 ///
Chris@16 1695 /// IMAGE VIEW CONCEPTS
Chris@16 1696 ///
Chris@16 1697 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 1698
Chris@16 1699 /// \defgroup ImageViewNDConcept ImageViewNDLocatorConcept
Chris@16 1700 /// \ingroup ImageViewConcept
Chris@16 1701 /// \brief N-dimensional range
Chris@16 1702
Chris@16 1703 /// \defgroup ImageView2DConcept ImageView2DConcept
Chris@16 1704 /// \ingroup ImageViewConcept
Chris@16 1705 /// \brief 2-dimensional range
Chris@16 1706
Chris@16 1707 /// \defgroup PixelImageViewConcept ImageViewConcept
Chris@16 1708 /// \ingroup ImageViewConcept
Chris@16 1709 /// \brief 2-dimensional range over pixel data
Chris@16 1710
Chris@16 1711 /// \ingroup ImageViewNDConcept
Chris@16 1712 /// \brief N-dimensional view over immutable values
Chris@16 1713 /**
Chris@16 1714 \code
Chris@16 1715 concept RandomAccessNDImageViewConcept<Regular View> {
Chris@16 1716 typename value_type;
Chris@16 1717 typename reference; // result of dereferencing
Chris@16 1718 typename difference_type; // result of operator-(iterator,iterator) (1-dimensional!)
Chris@16 1719 typename const_t; where RandomAccessNDImageViewConcept<View>; // same as View, but over immutable values
Chris@16 1720 typename point_t; where PointNDConcept<point_t>; // N-dimensional point
Chris@16 1721 typename locator; where RandomAccessNDLocatorConcept<locator>; // N-dimensional locator.
Chris@16 1722 typename iterator; where RandomAccessTraversalConcept<iterator>; // 1-dimensional iterator over all values
Chris@16 1723 typename reverse_iterator; where RandomAccessTraversalConcept<reverse_iterator>;
Chris@16 1724 typename size_type; // the return value of size()
Chris@16 1725
Chris@16 1726 // Equivalent to RandomAccessNDLocatorConcept::axis
Chris@16 1727 template <size_t D> struct axis {
Chris@16 1728 typename coord_t = point_t::axis<D>::coord_t;
Chris@16 1729 typename iterator; where RandomAccessTraversalConcept<iterator>; // iterator along D-th axis.
Chris@16 1730 where SameType<coord_t, iterator::difference_type>;
Chris@16 1731 where SameType<iterator::value_type,value_type>;
Chris@16 1732 };
Chris@16 1733
Chris@16 1734 // Defines the type of a view similar to this type, except it invokes Deref upon dereferencing
Chris@16 1735 template <PixelDereferenceAdaptorConcept Deref> struct add_deref {
Chris@16 1736 typename type; where RandomAccessNDImageViewConcept<type>;
Chris@16 1737 static type make(const View& v, const Deref& deref);
Chris@16 1738 };
Chris@16 1739
Chris@16 1740 static const size_t num_dimensions = point_t::num_dimensions;
Chris@16 1741
Chris@16 1742 // Create from a locator at the top-left corner and dimensions
Chris@16 1743 View::View(const locator&, const point_type&);
Chris@16 1744
Chris@16 1745 size_type View::size() const; // total number of elements
Chris@16 1746 reference operator[](View, const difference_type&) const; // 1-dimensional reference
Chris@16 1747 iterator View::begin() const;
Chris@16 1748 iterator View::end() const;
Chris@16 1749 reverse_iterator View::rbegin() const;
Chris@16 1750 reverse_iterator View::rend() const;
Chris@16 1751 iterator View::at(const point_t&);
Chris@16 1752 point_t View::dimensions() const; // number of elements along each dimension
Chris@16 1753 bool View::is_1d_traversable() const; // can an iterator over the first dimension visit each value? I.e. are there gaps between values?
Chris@16 1754
Chris@16 1755 // iterator along a given dimension starting at a given point
Chris@16 1756 template <size_t D> View::axis<D>::iterator View::axis_iterator(const point_t&) const;
Chris@16 1757
Chris@16 1758 reference operator()(View,const point_t&) const;
Chris@16 1759 };
Chris@16 1760 \endcode
Chris@16 1761 */
Chris@16 1762 template <typename View>
Chris@16 1763 struct RandomAccessNDImageViewConcept {
Chris@16 1764 void constraints() {
Chris@16 1765 gil_function_requires< Regular<View> >();
Chris@16 1766
Chris@16 1767 typedef typename View::value_type value_type;
Chris@16 1768 typedef typename View::reference reference; // result of dereferencing
Chris@16 1769 typedef typename View::difference_type difference_type; // result of operator-(1d_iterator,1d_iterator)
Chris@16 1770 typedef typename View::const_t const_t; // same as this type, but over const values
Chris@16 1771 typedef typename View::point_t point_t; // N-dimensional point
Chris@16 1772 typedef typename View::locator locator; // N-dimensional locator
Chris@16 1773 typedef typename View::iterator iterator;
Chris@16 1774 typedef typename View::reverse_iterator reverse_iterator;
Chris@16 1775 typedef typename View::size_type size_type;
Chris@16 1776 static const std::size_t N=View::num_dimensions;
Chris@16 1777
Chris@16 1778 gil_function_requires<RandomAccessNDLocatorConcept<locator> >();
Chris@16 1779 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<iterator> >();
Chris@16 1780 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<reverse_iterator> >();
Chris@16 1781
Chris@16 1782 typedef typename View::template axis<0>::iterator first_it_type;
Chris@16 1783 typedef typename View::template axis<N-1>::iterator last_it_type;
Chris@16 1784 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<first_it_type> >();
Chris@16 1785 gil_function_requires<boost_concepts::RandomAccessTraversalConcept<last_it_type> >();
Chris@16 1786
Chris@16 1787 // BOOST_STATIC_ASSERT((typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value));
Chris@16 1788 // BOOST_STATIC_ASSERT((typename std::iterator_traits< last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value));
Chris@16 1789
Chris@16 1790 // point_t must be an N-dimensional point, each dimension of which must have the same type as difference_type of the corresponding iterator
Chris@16 1791 gil_function_requires<PointNDConcept<point_t> >();
Chris@16 1792 BOOST_STATIC_ASSERT(point_t::num_dimensions==N);
Chris@16 1793 BOOST_STATIC_ASSERT((is_same<typename std::iterator_traits<first_it_type>::difference_type, typename point_t::template axis<0>::coord_t>::value));
Chris@16 1794 BOOST_STATIC_ASSERT((is_same<typename std::iterator_traits<last_it_type>::difference_type, typename point_t::template axis<N-1>::coord_t>::value));
Chris@16 1795
Chris@16 1796 point_t p;
Chris@16 1797 locator lc;
Chris@16 1798 iterator it;
Chris@16 1799 reverse_iterator rit;
Chris@16 1800 difference_type d; detail::initialize_it(d); ignore_unused_variable_warning(d);
Chris@16 1801
Chris@16 1802 View(p,lc); // view must be constructible from a locator and a point
Chris@16 1803
Chris@16 1804 p=view.dimensions();
Chris@16 1805 lc=view.pixels();
Chris@16 1806 size_type sz=view.size(); ignore_unused_variable_warning(sz);
Chris@16 1807 bool is_contiguous=view.is_1d_traversable(); ignore_unused_variable_warning(is_contiguous);
Chris@16 1808
Chris@16 1809 it=view.begin();
Chris@16 1810 it=view.end();
Chris@16 1811 rit=view.rbegin();
Chris@16 1812 rit=view.rend();
Chris@16 1813
Chris@16 1814 reference r1=view[d]; ignore_unused_variable_warning(r1); // 1D access
Chris@16 1815 reference r2=view(p); ignore_unused_variable_warning(r2); // 2D access
Chris@16 1816
Chris@16 1817 // get 1-D iterator of any dimension at a given pixel location
Chris@16 1818 first_it_type fi=view.template axis_iterator<0>(p); ignore_unused_variable_warning(fi);
Chris@16 1819 last_it_type li=view.template axis_iterator<N-1>(p); ignore_unused_variable_warning(li);
Chris@16 1820
Chris@16 1821 typedef PixelDereferenceAdaptorArchetype<typename View::value_type> deref_t;
Chris@16 1822 typedef typename View::template add_deref<deref_t>::type dtype;
Chris@16 1823 }
Chris@16 1824 View view;
Chris@16 1825 };
Chris@16 1826
Chris@16 1827 /// \ingroup ImageView2DConcept
Chris@16 1828 /// \brief 2-dimensional view over immutable values
Chris@16 1829 /**
Chris@16 1830 \code
Chris@16 1831 concept RandomAccess2DImageViewConcept<RandomAccessNDImageViewConcept View> {
Chris@16 1832 where num_dimensions==2;
Chris@16 1833
Chris@16 1834 typename x_iterator = axis<0>::iterator;
Chris@16 1835 typename y_iterator = axis<1>::iterator;
Chris@16 1836 typename x_coord_t = axis<0>::coord_t;
Chris@16 1837 typename y_coord_t = axis<1>::coord_t;
Chris@16 1838 typename xy_locator = locator;
Chris@16 1839
Chris@16 1840 x_coord_t View::width() const;
Chris@16 1841 y_coord_t View::height() const;
Chris@16 1842
Chris@16 1843 // X-navigation
Chris@16 1844 x_iterator View::x_at(const point_t&) const;
Chris@16 1845 x_iterator View::row_begin(y_coord_t) const;
Chris@16 1846 x_iterator View::row_end (y_coord_t) const;
Chris@16 1847
Chris@16 1848 // Y-navigation
Chris@16 1849 y_iterator View::y_at(const point_t&) const;
Chris@16 1850 y_iterator View::col_begin(x_coord_t) const;
Chris@16 1851 y_iterator View::col_end (x_coord_t) const;
Chris@16 1852
Chris@16 1853 // navigating in 2D
Chris@16 1854 xy_locator View::xy_at(const point_t&) const;
Chris@16 1855
Chris@16 1856 // (x,y) versions of all methods taking point_t
Chris@16 1857 View::View(x_coord_t,y_coord_t,const locator&);
Chris@16 1858 iterator View::at(x_coord_t,y_coord_t) const;
Chris@16 1859 reference operator()(View,x_coord_t,y_coord_t) const;
Chris@16 1860 xy_locator View::xy_at(x_coord_t,y_coord_t) const;
Chris@16 1861 x_iterator View::x_at(x_coord_t,y_coord_t) const;
Chris@16 1862 y_iterator View::y_at(x_coord_t,y_coord_t) const;
Chris@16 1863 };
Chris@16 1864 \endcode
Chris@16 1865 */
Chris@16 1866 template <typename View>
Chris@16 1867 struct RandomAccess2DImageViewConcept {
Chris@16 1868 void constraints() {
Chris@16 1869 gil_function_requires<RandomAccessNDImageViewConcept<View> >();
Chris@16 1870 BOOST_STATIC_ASSERT(View::num_dimensions==2);
Chris@16 1871
Chris@16 1872 // TODO: This executes the requirements for RandomAccessNDLocatorConcept again. Fix it to improve compile time
Chris@16 1873 gil_function_requires<RandomAccess2DLocatorConcept<typename View::locator> >();
Chris@16 1874
Chris@16 1875 typedef typename dynamic_x_step_type<View>::type dynamic_x_step_t;
Chris@16 1876 typedef typename dynamic_y_step_type<View>::type dynamic_y_step_t;
Chris@16 1877 typedef typename transposed_type<View>::type transposed_t;
Chris@16 1878
Chris@16 1879 typedef typename View::x_iterator x_iterator;
Chris@16 1880 typedef typename View::y_iterator y_iterator;
Chris@16 1881 typedef typename View::x_coord_t x_coord_t;
Chris@16 1882 typedef typename View::y_coord_t y_coord_t;
Chris@16 1883 typedef typename View::xy_locator xy_locator;
Chris@16 1884
Chris@16 1885 x_coord_t xd=0; ignore_unused_variable_warning(xd);
Chris@16 1886 y_coord_t yd=0; ignore_unused_variable_warning(yd);
Chris@16 1887 x_iterator xit;
Chris@16 1888 y_iterator yit;
Chris@16 1889 typename View::point_t d;
Chris@16 1890
Chris@16 1891 View(xd,yd,xy_locator()); // constructible with width, height, 2d_locator
Chris@16 1892
Chris@16 1893 xy_locator lc=view.xy_at(xd,yd);
Chris@16 1894 lc=view.xy_at(d);
Chris@16 1895
Chris@16 1896 typename View::reference r=view(xd,yd); ignore_unused_variable_warning(r);
Chris@16 1897 xd=view.width();
Chris@16 1898 yd=view.height();
Chris@16 1899
Chris@16 1900 xit=view.x_at(d);
Chris@16 1901 xit=view.x_at(xd,yd);
Chris@16 1902 xit=view.row_begin(xd);
Chris@16 1903 xit=view.row_end(xd);
Chris@16 1904
Chris@16 1905 yit=view.y_at(d);
Chris@16 1906 yit=view.y_at(xd,yd);
Chris@16 1907 yit=view.col_begin(xd);
Chris@16 1908 yit=view.col_end(xd);
Chris@16 1909 }
Chris@16 1910 View view;
Chris@16 1911 };
Chris@16 1912
Chris@16 1913
Chris@16 1914 /// \ingroup PixelImageViewConcept
Chris@16 1915 /// \brief GIL's 2-dimensional view over immutable GIL pixels
Chris@16 1916 /**
Chris@16 1917 \code
Chris@16 1918 concept ImageViewConcept<RandomAccess2DImageViewConcept View> {
Chris@16 1919 where PixelValueConcept<value_type>;
Chris@16 1920 where PixelIteratorConcept<x_iterator>;
Chris@16 1921 where PixelIteratorConcept<y_iterator>;
Chris@16 1922 where x_coord_t == y_coord_t;
Chris@16 1923
Chris@16 1924 typename coord_t = x_coord_t;
Chris@16 1925
Chris@16 1926 std::size_t View::num_channels() const;
Chris@16 1927 };
Chris@16 1928 \endcode
Chris@16 1929 */
Chris@16 1930 template <typename View>
Chris@16 1931 struct ImageViewConcept {
Chris@16 1932 void constraints() {
Chris@16 1933 gil_function_requires<RandomAccess2DImageViewConcept<View> >();
Chris@16 1934
Chris@16 1935 // TODO: This executes the requirements for RandomAccess2DLocatorConcept again. Fix it to improve compile time
Chris@16 1936 gil_function_requires<PixelLocatorConcept<typename View::xy_locator> >();
Chris@16 1937
Chris@16 1938 BOOST_STATIC_ASSERT((is_same<typename View::x_coord_t, typename View::y_coord_t>::value));
Chris@16 1939
Chris@16 1940 typedef typename View::coord_t coord_t; // 1D difference type (same for all dimensions)
Chris@16 1941 std::size_t num_chan = view.num_channels(); ignore_unused_variable_warning(num_chan);
Chris@16 1942 }
Chris@16 1943 View view;
Chris@16 1944 };
Chris@16 1945
Chris@16 1946
Chris@16 1947 namespace detail {
Chris@16 1948 template <typename View> // Preconditions: View Models RandomAccessNDImageViewConcept
Chris@16 1949 struct RandomAccessNDImageViewIsMutableConcept {
Chris@16 1950 void constraints() {
Chris@16 1951 gil_function_requires<detail::RandomAccessNDLocatorIsMutableConcept<typename View::locator> >();
Chris@16 1952
Chris@16 1953 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::iterator> >();
Chris@16 1954 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::reverse_iterator> >();
Chris@16 1955 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::template axis<0>::iterator> >();
Chris@16 1956 gil_function_requires<detail::RandomAccessIteratorIsMutableConcept<typename View::template axis<View::num_dimensions-1>::iterator> >();
Chris@16 1957
Chris@16 1958 typename View::difference_type diff; initialize_it(diff); ignore_unused_variable_warning(diff);
Chris@16 1959 typename View::point_t pt;
Chris@16 1960 typename View::value_type v; initialize_it(v);
Chris@16 1961
Chris@16 1962 view[diff]=v;
Chris@16 1963 view(pt)=v;
Chris@16 1964 }
Chris@16 1965 View view;
Chris@16 1966 };
Chris@16 1967
Chris@16 1968 template <typename View> // preconditions: View Models RandomAccessNDImageViewConcept
Chris@16 1969 struct RandomAccess2DImageViewIsMutableConcept {
Chris@16 1970 void constraints() {
Chris@16 1971 gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<View> >();
Chris@16 1972 typename View::x_coord_t xd=0; ignore_unused_variable_warning(xd);
Chris@16 1973 typename View::y_coord_t yd=0; ignore_unused_variable_warning(yd);
Chris@16 1974 typename View::value_type v; initialize_it(v);
Chris@16 1975 view(xd,yd)=v;
Chris@16 1976 }
Chris@16 1977 View view;
Chris@16 1978 };
Chris@16 1979
Chris@16 1980 template <typename View> // preconditions: View Models ImageViewConcept
Chris@16 1981 struct PixelImageViewIsMutableConcept {
Chris@16 1982 void constraints() {
Chris@16 1983 gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View> >();
Chris@16 1984 }
Chris@16 1985 };
Chris@16 1986 }
Chris@16 1987
Chris@16 1988 /// \ingroup ImageViewNDConcept
Chris@16 1989 /// \brief N-dimensional view over mutable values
Chris@16 1990 /**
Chris@16 1991 \code
Chris@16 1992 concept MutableRandomAccessNDImageViewConcept<RandomAccessNDImageViewConcept View> {
Chris@16 1993 where Mutable<reference>;
Chris@16 1994 };
Chris@16 1995 \endcode
Chris@16 1996 */
Chris@16 1997 template <typename View>
Chris@16 1998 struct MutableRandomAccessNDImageViewConcept {
Chris@16 1999 void constraints() {
Chris@16 2000 gil_function_requires<RandomAccessNDImageViewConcept<View> >();
Chris@16 2001 gil_function_requires<detail::RandomAccessNDImageViewIsMutableConcept<View> >();
Chris@16 2002 }
Chris@16 2003 };
Chris@16 2004
Chris@16 2005 /// \ingroup ImageView2DConcept
Chris@16 2006 /// \brief 2-dimensional view over mutable values
Chris@16 2007 /**
Chris@16 2008 \code
Chris@16 2009 concept MutableRandomAccess2DImageViewConcept<RandomAccess2DImageViewConcept View> : MutableRandomAccessNDImageViewConcept<View> {};
Chris@16 2010 \endcode
Chris@16 2011 */
Chris@16 2012 template <typename View>
Chris@16 2013 struct MutableRandomAccess2DImageViewConcept {
Chris@16 2014 void constraints() {
Chris@16 2015 gil_function_requires<RandomAccess2DImageViewConcept<View> >();
Chris@16 2016 gil_function_requires<detail::RandomAccess2DImageViewIsMutableConcept<View> >();
Chris@16 2017 }
Chris@16 2018 };
Chris@16 2019
Chris@16 2020 /// \ingroup PixelImageViewConcept
Chris@16 2021 /// \brief GIL's 2-dimensional view over mutable GIL pixels
Chris@16 2022 /**
Chris@16 2023 \code
Chris@16 2024 concept MutableImageViewConcept<ImageViewConcept View> : MutableRandomAccess2DImageViewConcept<View> {};
Chris@16 2025 \endcode
Chris@16 2026 */
Chris@16 2027 template <typename View>
Chris@16 2028 struct MutableImageViewConcept {
Chris@16 2029 void constraints() {
Chris@16 2030 gil_function_requires<ImageViewConcept<View> >();
Chris@16 2031 gil_function_requires<detail::PixelImageViewIsMutableConcept<View> >();
Chris@16 2032 }
Chris@16 2033 };
Chris@16 2034
Chris@16 2035 /// \brief Returns whether two views are compatible
Chris@16 2036 ///
Chris@16 2037 /// Views are compatible if their pixels are compatible. Compatible views can be assigned and copy constructed from one another.
Chris@16 2038 template <typename V1, typename V2> // Model ImageViewConcept
Chris@16 2039 struct views_are_compatible : public pixels_are_compatible<typename V1::value_type, typename V2::value_type> {};
Chris@16 2040
Chris@16 2041 /// \brief Views are compatible if they have the same color spaces and compatible channel values. Constness and layout are not important for compatibility
Chris@16 2042 /// \ingroup ImageViewConcept
Chris@16 2043 /**
Chris@16 2044 \code
Chris@16 2045 concept ViewsCompatibleConcept<ImageViewConcept V1, ImageViewConcept V2> {
Chris@16 2046 where PixelsCompatibleConcept<V1::value_type, P2::value_type>;
Chris@16 2047 };
Chris@16 2048 \endcode
Chris@16 2049 */
Chris@16 2050 template <typename V1, typename V2>
Chris@16 2051 struct ViewsCompatibleConcept {
Chris@16 2052 void constraints() {
Chris@16 2053 BOOST_STATIC_ASSERT((views_are_compatible<V1,V2>::value));
Chris@16 2054 }
Chris@16 2055 };
Chris@16 2056
Chris@16 2057
Chris@16 2058 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 2059 ///
Chris@16 2060 /// IMAGE CONCEPTS
Chris@16 2061 ///
Chris@16 2062 ////////////////////////////////////////////////////////////////////////////////////////
Chris@16 2063
Chris@16 2064
Chris@16 2065 /// \ingroup ImageConcept
Chris@16 2066 /// \brief N-dimensional container of values
Chris@16 2067 /**
Chris@16 2068 \code
Chris@16 2069 concept RandomAccessNDImageConcept<typename Img> : Regular<Img> {
Chris@16 2070 typename view_t; where MutableRandomAccessNDImageViewConcept<view_t>;
Chris@16 2071 typename const_view_t = view_t::const_t;
Chris@16 2072 typename point_t = view_t::point_t;
Chris@16 2073 typename value_type = view_t::value_type;
Chris@16 2074 typename allocator_type;
Chris@16 2075
Chris@16 2076 Img::Img(point_t dims, std::size_t alignment=1);
Chris@16 2077 Img::Img(point_t dims, value_type fill_value, std::size_t alignment);
Chris@16 2078
Chris@16 2079 void Img::recreate(point_t new_dims, std::size_t alignment=1);
Chris@16 2080 void Img::recreate(point_t new_dims, value_type fill_value, std::size_t alignment);
Chris@16 2081
Chris@16 2082 const point_t& Img::dimensions() const;
Chris@16 2083 const const_view_t& const_view(const Img&);
Chris@16 2084 const view_t& view(Img&);
Chris@16 2085 };
Chris@16 2086 \endcode
Chris@16 2087 */
Chris@16 2088 template <typename Img>
Chris@16 2089 struct RandomAccessNDImageConcept {
Chris@16 2090 void constraints() {
Chris@16 2091 gil_function_requires<Regular<Img> >();
Chris@16 2092
Chris@16 2093 typedef typename Img::view_t view_t;
Chris@16 2094 gil_function_requires<MutableRandomAccessNDImageViewConcept<view_t> >();
Chris@16 2095
Chris@16 2096 typedef typename Img::const_view_t const_view_t;
Chris@16 2097 typedef typename Img::value_type pixel_t;
Chris@16 2098
Chris@16 2099 typedef typename Img::point_t point_t;
Chris@16 2100 gil_function_requires<PointNDConcept<point_t> >();
Chris@16 2101
Chris@16 2102 const_view_t cv = const_view(img); ignore_unused_variable_warning(cv);
Chris@16 2103 view_t v = view(img); ignore_unused_variable_warning(v);
Chris@16 2104
Chris@16 2105 pixel_t fill_value;
Chris@16 2106 point_t pt=img.dimensions();
Chris@16 2107 Img im1(pt);
Chris@16 2108 Img im2(pt,1);
Chris@16 2109 Img im3(pt,fill_value,1);
Chris@16 2110 img.recreate(pt);
Chris@16 2111 img.recreate(pt,1);
Chris@16 2112 img.recreate(pt,fill_value,1);
Chris@16 2113 }
Chris@16 2114 Img img;
Chris@16 2115 };
Chris@16 2116
Chris@16 2117
Chris@16 2118 /// \ingroup ImageConcept
Chris@16 2119 /// \brief 2-dimensional container of values
Chris@16 2120 /**
Chris@16 2121 \code
Chris@16 2122 concept RandomAccess2DImageConcept<RandomAccessNDImageConcept Img> {
Chris@16 2123 typename x_coord_t = const_view_t::x_coord_t;
Chris@16 2124 typename y_coord_t = const_view_t::y_coord_t;
Chris@16 2125
Chris@16 2126 Img::Img(x_coord_t width, y_coord_t height, std::size_t alignment=1);
Chris@16 2127 Img::Img(x_coord_t width, y_coord_t height, value_type fill_value, std::size_t alignment);
Chris@16 2128
Chris@16 2129 x_coord_t Img::width() const;
Chris@16 2130 y_coord_t Img::height() const;
Chris@16 2131
Chris@16 2132 void Img::recreate(x_coord_t width, y_coord_t height, std::size_t alignment=1);
Chris@16 2133 void Img::recreate(x_coord_t width, y_coord_t height, value_type fill_value, std::size_t alignment);
Chris@16 2134 };
Chris@16 2135 \endcode
Chris@16 2136 */
Chris@16 2137 template <typename Img>
Chris@16 2138 struct RandomAccess2DImageConcept {
Chris@16 2139 void constraints() {
Chris@16 2140 gil_function_requires<RandomAccessNDImageConcept<Img> >();
Chris@16 2141 typedef typename Img::x_coord_t x_coord_t;
Chris@16 2142 typedef typename Img::y_coord_t y_coord_t;
Chris@16 2143 typedef typename Img::value_type value_t;
Chris@16 2144
Chris@16 2145 gil_function_requires<MutableRandomAccess2DImageViewConcept<typename Img::view_t> >();
Chris@16 2146
Chris@16 2147 x_coord_t w=img.width();
Chris@16 2148 y_coord_t h=img.height();
Chris@16 2149 value_t fill_value;
Chris@16 2150 Img im1(w,h);
Chris@16 2151 Img im2(w,h,1);
Chris@16 2152 Img im3(w,h,fill_value,1);
Chris@16 2153 img.recreate(w,h);
Chris@16 2154 img.recreate(w,h,1);
Chris@16 2155 img.recreate(w,h,fill_value,1);
Chris@16 2156 }
Chris@16 2157 Img img;
Chris@16 2158 };
Chris@16 2159
Chris@16 2160 /// \ingroup ImageConcept
Chris@16 2161 /// \brief 2-dimensional image whose value type models PixelValueConcept
Chris@16 2162 /**
Chris@16 2163 \code
Chris@16 2164 concept ImageConcept<RandomAccess2DImageConcept Img> {
Chris@16 2165 where MutableImageViewConcept<view_t>;
Chris@16 2166 typename coord_t = view_t::coord_t;
Chris@16 2167 };
Chris@16 2168 \endcode
Chris@16 2169 */
Chris@16 2170 template <typename Img>
Chris@16 2171 struct ImageConcept {
Chris@16 2172 void constraints() {
Chris@16 2173 gil_function_requires<RandomAccess2DImageConcept<Img> >();
Chris@16 2174 gil_function_requires<MutableImageViewConcept<typename Img::view_t> >();
Chris@16 2175 typedef typename Img::coord_t coord_t;
Chris@16 2176 BOOST_STATIC_ASSERT(num_channels<Img>::value == mpl::size<typename color_space_type<Img>::type>::value);
Chris@16 2177
Chris@16 2178 BOOST_STATIC_ASSERT((is_same<coord_t, typename Img::x_coord_t>::value));
Chris@16 2179 BOOST_STATIC_ASSERT((is_same<coord_t, typename Img::y_coord_t>::value));
Chris@16 2180 }
Chris@16 2181 Img img;
Chris@16 2182 };
Chris@16 2183
Chris@16 2184
Chris@16 2185 } } // namespace boost::gil
Chris@16 2186
Chris@16 2187 #endif