| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 | 
							- /////////////////////////////////////////////////////////////////////////////
 
- // Name:        wx/private/flagscheck.h
 
- // Purpose:     helpers for checking that (bit)flags don't overlap
 
- // Author:      Vaclav Slavik
 
- // Created:     2008-02-21
 
- // Copyright:   (c) 2008 Vaclav Slavik
 
- // Licence:     wxWindows licence
 
- /////////////////////////////////////////////////////////////////////////////
 
- #ifndef _WX_PRIVATE_FLAGSCHECK_H_
 
- #define _WX_PRIVATE_FLAGSCHECK_H_
 
- #include "wx/debug.h"
 
- // IBM xlC 8 can't parse the template syntax
 
- #if !defined(__IBMCPP__)
 
- #include "wx/meta/if.h"
 
- namespace wxPrivate
 
- {
 
- // These templates are used to implement wxADD_FLAG macro below.
 
- //
 
- // The idea is that we want to trigger *compilation* error if the flags
 
- // overlap, not just runtime assert failure. We can't implement the check
 
- // using just a simple logical operation, we need checks equivalent to this
 
- // code:
 
- //
 
- //   mask = wxFLAG_1;
 
- //   assert( (mask & wxFLAG_2) == 0 ); // no overlap
 
- //   mask |= wxFLAG_3;
 
- //   assert( (mask & wxFLAG_3) == 0 ); // no overlap
 
- //   mask |= wxFLAG_3;
 
- //   ...
 
- //
 
- // This can be done at compilation time by using templates metaprogramming
 
- // technique that makes the compiler carry on the computation.
 
- //
 
- // NB: If any of this doesn't compile with your compiler and would be too
 
- //     hard to make work, it's probably best to disable this code and replace
 
- //     the macros below with empty stubs, this isn't anything critical.
 
- template<int val> struct FlagsHaveConflictingValues
 
- {
 
-     // no value here - triggers compilation error
 
- };
 
- template<int val> struct FlagValue
 
- {
 
-     enum { value = val };
 
- };
 
- // This template adds its template parameter integer 'add' to another integer
 
- // 'all' and produces their OR-combination (all | add). The result is "stored"
 
- // as constant SafelyAddToMask<>::value. Combination of many flags is achieved
 
- // by chaining parameter lists: the 'add' parameter is value member of
 
- // another (different) SafelyAddToMask<> instantiation.
 
- template<int all, int add> struct SafelyAddToMask
 
- {
 
-     // This typedefs ensures that no flags in the list conflict. If there's
 
-     // any overlap between the already constructed part of the mask ('all')
 
-     // and the value being added to it ('add'), the test that is wxIf<>'s
 
-     // first parameter will be non-zero and so Added value will be
 
-     // FlagsHaveConflictingValues<add>. The next statement will try to use
 
-     // AddedValue::value, but there's no such thing in
 
-     // FlagsHaveConflictingValues<> and so compilation will fail.
 
-     typedef typename wxIf<(all & add) == 0,
 
-                           FlagValue<add>,
 
-                           FlagsHaveConflictingValues<add> >::value
 
-             AddedValue;
 
-     enum { value = all | AddedValue::value };
 
- };
 
- } // wxPrivate namespace
 
- // This macro is used to ensure that no two flags that can be combined in
 
- // the same integer value have overlapping bits. This is sometimes not entirely
 
- // trivial to ensure, for example in wxWindow styles or flags for wxSizerItem
 
- // that span several enums, some of them used for multiple purposes.
 
- //
 
- // By constructing allowed flags mask using wxADD_FLAG macro and then using
 
- // this mask to check flags passed as arguments, you can ensure that
 
- //
 
- // a) if any of the allowed flags overlap, you will get compilation error
 
- // b) if invalid flag is used, there will be an assert at runtime
 
- //
 
- // Example usage:
 
- //
 
- //   static const int SIZER_FLAGS_MASK =
 
- //       wxADD_FLAG(wxCENTRE,
 
- //       wxADD_FLAG(wxHORIZONTAL,
 
- //       wxADD_FLAG(wxVERTICAL,
 
- //       ...
 
- //       0))...);
 
- //
 
- // And wherever flags are used:
 
- //
 
- //   wxASSERT_VALID_FLAG( m_flag, SIZER_FLAGS_MASK );
 
- #define wxADD_FLAG(f, others) \
 
-     ::wxPrivate::SafelyAddToMask<f, others>::value
 
- #else
 
-     #define wxADD_FLAG(f, others) (f | others)
 
- #endif
 
- // Checks if flags value 'f' is within the mask of allowed values
 
- #define wxASSERT_VALID_FLAGS(f, mask)                   \
 
-     wxASSERT_MSG( (f & mask) == f,                      \
 
-                   "invalid flag: not within " #mask )
 
- #endif // _WX_PRIVATE_FLAGSCHECK_H_
 
 
  |