STLSoft - ... Robust, Lightweight, Cross-platform, Template Software ... ATLSTL - Template Software for the Active Template Library COMSTL - The Standard Template Library meets the Component Object Model .netSTL - Standard Template Library meets the Microsoft.NET Common Language Runtime InetSTL - The Standard Template Library meets WinInet MFCSTL - Template Software for the Microsoft Foundation Classes UNIXSTL - Template Software for the UNIX Operating System WinSTL - where the Standard Template Library meets the Win32 API

Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

stlsoft_constraints.h

Go to the documentation of this file.
00001 /* 
00002  * File:        stlsoft_constraints.h (originally MTAlgo.h, ::SynesisStl)
00003  *
00004  * Purpose:     Compile-time template constraints templates.
00005  *
00006  * Created:     19th November 1998
00007  * Updated:     11th September 2004
00008  *
00009  * Home:        http://stlsoft.org/
00010  *
00011  * Copyright (c) 1998-2004, Matthew Wilson and Synesis Software
00012  * All rights reserved.
00013  *
00014  * Redistribution and use in source and binary forms, with or without
00015  * modification, are permitted provided that the following conditions are met:
00016  *
00017  * - Redistributions of source code must retain the above copyright notice, this
00018  *   list of conditions and the following disclaimer.
00019  * - Redistributions in binary form must reproduce the above copyright notice,
00020  *   this list of conditions and the following disclaimer in the documentation
00021  *   and/or other materials provided with the distribution.
00022  * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
00023  *   any contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00027  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00030  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00031  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00032  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00033  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00034  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00035  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00036  * POSSIBILITY OF SUCH DAMAGE.
00037  *
00038  * 
00039 
00040 
00044 
00045 #ifndef STLSOFT_INCL_H_STLSOFT_CONSTRAINTS
00046 #define STLSOFT_INCL_H_STLSOFT_CONSTRAINTS
00047 
00048 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00049 # define STLSOFT_VER_H_STLSOFT_CONSTRAINTS_MAJOR    3
00050 # define STLSOFT_VER_H_STLSOFT_CONSTRAINTS_MINOR    0
00051 # define STLSOFT_VER_H_STLSOFT_CONSTRAINTS_REVISION 1
00052 # define STLSOFT_VER_H_STLSOFT_CONSTRAINTS_EDIT     65
00053 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00054 
00055 /* 
00056  * Includes
00057  */
00058 
00059 #ifndef STLSOFT_INCL_H_STLSOFT
00060 # include "stlsoft.h"       // Include the STLSoft root header
00061 #endif /* !STLSOFT_INCL_H_STLSOFT */
00062 #ifndef STLSOFT_INCL_H_STLSOFT_META
00063 # include "stlsoft_meta.h"  // is_***
00064 #endif /* !STLSOFT_INCL_H_STLSOFT_META */
00065 
00066 /* 
00067  * Namespace
00068  */
00069 
00070 #ifndef _STLSOFT_NO_NAMESPACE
00071 namespace stlsoft
00072 {
00073 #endif /* _STLSOFT_NO_NAMESPACE */
00074 
00075 /* 
00076  * Macros
00077  */
00078 
00079 #if defined(__STLSOFT_COMPILER_IS_BORLAND) || \
00080     defined(__STLSOFT_COMPILER_IS_INTEL) || \
00081     defined(__STLSOFT_COMPILER_IS_MWERKS)
00082 # define stlsoft_constraint_must_be_pod(T)              do { stlsoft_ns_qual(must_be_pod)<T>::func_ptr_type const pfn = stlsoft_ns_qual(must_be_pod)<T>::constraint(); STLSOFT_SUPPRESS_UNUSED(pfn); } while(0)
00083 # define stlsoft_constraint_must_be_pod_or_void(T)      do { stlsoft_ns_qual(must_be_pod_or_void)<T>::func_ptr_type const pfn = stlsoft_ns_qual(must_be_pod_or_void)<T>::constraint(); STLSOFT_SUPPRESS_UNUSED(pfn); } while(0)
00084 #elif defined(__STLSOFT_COMPILER_IS_DMC)
00085 # define stlsoft_constraint_must_be_pod(T)          do { int i = sizeof(stlsoft_ns_qual(must_be_pod)<T>::constraint()); } while(0)
00086 # define stlsoft_constraint_must_be_pod_or_void(T)  do { int i = sizeof(stlsoft_ns_qual(must_be_pod_or_void)<T>::constraint()); } while(0)
00087 #else
00088 # define stlsoft_constraint_must_be_pod(T)          stlsoft_static_assert(sizeof(stlsoft_ns_qual(must_be_pod)<T>::constraint()) != 0)
00089 # define stlsoft_constraint_must_be_pod_or_void(T)  stlsoft_static_assert(sizeof(stlsoft_ns_qual(must_be_pod_or_void)<T>::constraint()) != 0)
00090 #endif /* __STLSOFT_COMPILER_IS_DMC */
00091 
00092 # define stlsoft_constraint_must_be_same_size(T1, T2)   stlsoft_ns_qual(must_be_same_size)<T1, T2>()
00093 # define stlsoft_constraint_must_be_subscriptable(T)    stlsoft_ns_qual(must_be_subscriptable)<T>()
00094 # define stlsoft_constraint_must_have_base(D, B)        stlsoft_ns_qual(must_have_base)<D, B>()
00095 
00096 /* 
00097  * Constraints
00098  */
00099 
00100 // must_have_base
00101 //
00108 template<   ss_typename_param_k D
00109         ,   ss_typename_param_k B
00110         >
00111 struct must_have_base
00112 {
00113 public:
00114     ~must_have_base()
00115     {
00116         void(*p)(D*, B*) = constraints;
00117 
00118         STLSOFT_SUPPRESS_UNUSED(p);
00119     }
00120 
00121 private:
00122     static void constraints(D* pd, B* pb)
00123     {
00124         pb = pd;
00125 
00126         STLSOFT_SUPPRESS_UNUSED(pb);
00127     }
00128 };
00129 
00130 // must_be_same_size
00131 //
00134 template<   ss_typename_param_k T1
00135         ,   ss_typename_param_k T2
00136         >
00137 struct must_be_same_size
00138 {
00139     ~must_be_same_size()
00140     {
00141         void    (*pfn)(void) = constraints;
00142 
00143         STLSOFT_SUPPRESS_UNUSED(pfn);
00144     }
00145 private:
00146     static void constraints()
00147     {
00148         // The compiler will bring you here if T1 and T2 are not the same
00149         // size.
00150         struct must_be_same_size_
00151         {
00152             int T1_must_be_same_size_as_T2 : (static_cast<int>(size_of<T1>::value) == static_cast<int>(size_of<T2>::value));
00153         };
00154 
00155         const int   T1_must_be_same_size_as_T2    = (static_cast<int>(size_of<T1>::value) == static_cast<int>(size_of<T2>::value));
00156         int         i[T1_must_be_same_size_as_T2];
00157 
00158         STLSOFT_SUPPRESS_UNUSED(i);
00159     }
00160 };
00161 
00162 
00165 template <ss_typename_param_k T>
00166 struct must_be_subscriptable
00167 {
00168 public:
00169     ~must_be_subscriptable()
00170     {
00171         int (*pfn)(T const &) = constraints;
00172 
00173         STLSOFT_SUPPRESS_UNUSED(pfn);
00174     }
00175 private:
00176     static int constraints(T const &T_is_not_subscriptable)
00177     {
00178         // The compiler will bring you here if T is not subscriptable
00179         return sizeof(T_is_not_subscriptable[0]);
00180     }
00181 };
00182 
00185 template <ss_typename_param_k T>
00186 struct must_subscript_as_decayable_pointer
00187 {
00188 public:
00189     ~must_subscript_as_decayable_pointer()
00190     {
00191         ss_size_t   (*pfn)(T const &) = constraints;
00192 
00193         STLSOFT_SUPPRESS_UNUSED(pfn);
00194     }
00195 private:
00196     static ss_size_t constraints(T const &T_is_not_decay_subscriptable)
00197     {
00198         // The compiler will bring you here if T has a user-defined
00199         // subscript operator.
00200         return sizeof(0[T_is_not_decay_subscriptable]);
00201     }
00202 };
00203 
00204 
00205 
00206 // must_be_pod
00207 //
00211 // This class can be used to constrain a type to be of either built-in, e.g.
00212 // int, or of a trivial type, i.e. aggregate types or types with publicly
00213 // accessible default contructors and assignment operators
00214 template <ss_typename_param_k T>
00215 union must_be_pod
00216 {
00217 private:
00218     typedef must_be_pod     class_type;
00219 
00220 public:
00221     T   t;
00222     int i;
00223 
00224     typedef int (*func_ptr_type)();
00225 
00226     static func_ptr_type constraint()
00227     {
00228         return constraints;
00229     }
00230 
00231     // Required by CodeWarrior
00232     ~must_be_pod()
00233     {
00234         int   (*pfn)(void) = constraints;
00235 
00236         STLSOFT_SUPPRESS_UNUSED(pfn);
00237     }
00238 
00239 private:
00240     static int constraints()
00241     {
00242 #if defined(__STLSOFT_COMPILER_IS_MWERKS)
00243 # if ((__MWERKS__ & 0xFF00) < 0x3000)
00244         class_type  u;
00245 # else /* ? __MWERKS__ */
00246         class_type  u;
00247 
00248         u = *static_cast<class_type*>(0);
00249 # endif /* __MWERKS__ */
00250 #else /* ? compiler */
00251         class_type  u = class_type();
00252 #endif /* compiler */
00253 
00254         STLSOFT_SUPPRESS_UNUSED(u);
00255 
00256         return sizeof(u);
00257     }
00258 };
00259 
00260 
00261 // must_be_pod_or_void
00262 //
00266 // This class can be used to constrain a type to be of either built-in, e.g.
00267 // int, or of a trivial type, i.e. aggregate types or types with publicly
00268 // accessible default contructors and assignment operators
00269 template <ss_typename_param_k T>
00270 union must_be_pod_or_void
00271 {
00272     T   t;
00273     int i;
00274 
00275     typedef int (*func_ptr_type)();
00276 
00277     static func_ptr_type constraint()
00278     {
00279         return constraints;
00280     }
00281 
00282 #if defined(__STLSOFT_COMPILER_IS_GCC)
00283 protected:
00284 #else /* ? __STLSOFT_COMPILER_IS_GCC */
00285 private:
00286 #endif /* __STLSOFT_COMPILER_IS_GCC */
00287     static int constraints()
00288     {
00289         must_be_pod_or_void<T>  u;
00290 
00291         STLSOFT_SUPPRESS_UNUSED(u);
00292 
00293         return sizeof(u);
00294     }
00295 };
00296 
00297 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00298 
00299 STLSOFT_TEMPLATE_SPECIALISATION
00300 union must_be_pod_or_void<void>
00301 {
00302     typedef int (*func_ptr_type)();
00303 
00304     static func_ptr_type constraint()
00305     {
00306         return NULL;
00307     }
00308 };
00309 
00310 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00311 
00312 /* 
00313 
00314 #if 0
00315 
00318 
00319 #ifdef NIC_TEMPLATE_VERSION
00320 //struct nic_null_
00321 //{};
00322 
00323 typedef void    nic_null_;
00324 
00325 template <ss_typename_param_k T = nic_null_>
00326 struct not_implicitly_comparable
00327     : public T
00328 {
00329 public:
00330     typedef not_implicitly_comparable<T>    class_type;
00331 
00332 #if defined(__STLSOFT_COMPILER_IS_GCC)
00333 protected:
00334 #else /* ? __STLSOFT_COMPILER_IS_GCC */
00335 private:
00336 #endif /* __STLSOFT_COMPILER_IS_GCC */
00337 #if 0
00338     template <ss_typename_param_k T2>
00339     ss_bool_t operator ==(T2 const &) const;
00340     template <ss_typename_param_k T2>
00341     ss_bool_t operator !=(T2 const &) const;
00342 #endif /* 0 */
00343 };
00344 
00346 template <>
00347 struct not_implicitly_comparable<nic_null_>
00348 {
00349 public:
00350     typedef not_implicitly_comparable<nic_null_>    class_type;
00351 
00352 #if defined(__STLSOFT_COMPILER_IS_GCC)
00353 protected:
00354 #else /* ? __STLSOFT_COMPILER_IS_GCC */
00355 private:
00356 #endif /* __STLSOFT_COMPILER_IS_GCC */
00357 #if 0
00358     template <ss_typename_param_k T2>
00359     ss_bool_t operator ==(T2 const &) const;
00360     template <ss_typename_param_k T2>
00361     ss_bool_t operator !=(T2 const &) const;
00362 #endif /* 0 */
00363 };
00364 
00365 template<   ss_typename_param_k T
00366         ,   ss_typename_param_k T2
00367         >
00368 inline ss_bool_t operator ==(not_implicitly_comparable<T> const &lhs, T2 const &rhs)
00369 {
00370 //  return lhs.operator ==(rhs);
00371 
00372   lhs.this_type_does_not_support_comparisons();
00373 
00374   return false; // Placate the eager beavers
00375 }
00376 
00377 template<   ss_typename_param_k T
00378         ,   ss_typename_param_k T2
00379         >
00380 inline ss_bool_t operator ==(T2 const &lhs, not_implicitly_comparable<T> const &rhs)
00381 {
00382 //  return rhs.operator ==(lhs);
00383 
00384   rhs.this_type_does_not_support_comparisons();
00385 
00386   return false; // Placate the eager beavers
00387 }
00388 
00389 #if 0
00390 template<   ss_typename_param_k T1
00391         ,   ss_typename_param_k T2
00392         >
00393 inline ss_bool_t operator ==(not_implicitly_comparable<T1> const &lhs, not_implicitly_comparable<T2> const &rhs)
00394 {
00395 //  return rhs.operator ==(lhs);
00396 
00397   rhs.this_type_does_not_support_comparisons();
00398 
00399   return false; // Placate the eager beavers
00400 }
00401 #endif /* 0 */
00402 
00403 template<   ss_typename_param_k T
00404         ,   ss_typename_param_k T2
00405         >
00406 inline ss_bool_t operator !=(T2 const &lhs, not_implicitly_comparable<T> const &rhs)
00407 {
00408 //  return rhs.operator !=(lhs);
00409 
00410   rhs.this_type_does_not_support_comparisons();
00411 
00412   return false; // Placate the eager beavers
00413 }
00414 
00415 template<   ss_typename_param_k T
00416         ,   ss_typename_param_k T2
00417         >
00418 inline ss_bool_t operator !=(not_implicitly_comparable<T> const &lhs, T2 const &rhs)
00419 {
00420 //  return lhs.operator !=(rhs);
00421 
00422   lhs.this_type_does_not_support_comparisons();
00423 
00424   return false; // Placate the eager beavers
00425 }
00426 
00427 template<   ss_typename_param_k T1
00428         ,   ss_typename_param_k T2
00429         >
00430 inline ss_bool_t operator !=(not_implicitly_comparable<T1> const &lhs, not_implicitly_comparable<T2> const &rhs)
00431 {
00432 //  return lhs.operator !=(rhs);
00433 
00434   lhs.this_type_does_not_support_comparisons();
00435 
00436   return false; // Placate the eager beavers
00437 }
00438 
00439 #else /* ? 0 */
00440 
00441 struct not_implicitly_comparable
00442 {
00443 public:
00444     typedef not_implicitly_comparable   class_type;
00445 
00446 #if defined(__STLSOFT_COMPILER_IS_GCC)
00447 protected:
00448 #else /* ? __STLSOFT_COMPILER_IS_GCC */
00449 private:
00450 #endif /* __STLSOFT_COMPILER_IS_GCC */
00451 
00452 #ifndef NIC_EXTERNAL_OPERATORS
00453     ss_bool_t operator ==(class_type const &) const;
00454     ss_bool_t operator !=(class_type const &) const;
00455 
00456     template <ss_typename_param_k T2>
00457     ss_bool_t operator ==(T2 const &) const;
00458     template <ss_typename_param_k T2>
00459     ss_bool_t operator !=(T2 const &) const;
00460 #endif /* !NIC_EXTERNAL_OPERATORS */
00461 };
00462 
00463 
00464 #ifdef NIC_EXTERNAL_OPERATORS
00465 
00466 template<   ss_typename_param_k T2
00467         >
00468 inline ss_bool_t operator ==(not_implicitly_comparable const &lhs, T2 const &rhs)
00469 {
00470 //  return lhs.operator ==(rhs);
00471 
00472   lhs.this_type_does_not_support_comparisons();
00473 
00474   return false; // Placate the eager beavers
00475 }
00476 
00477 template<   ss_typename_param_k T2
00478         >
00479 inline ss_bool_t operator ==(T2 const &lhs, not_implicitly_comparable const &rhs)
00480 {
00481 //  return rhs.operator ==(lhs);
00482 
00483   rhs.this_type_does_not_support_comparisons();
00484 
00485   return false; // Placate the eager beavers
00486 }
00487 #endif /* NIC_EXTERNAL_OPERATORS */
00488 
00489 #endif /* 0 */
00490 #endif /* 0 */
00491 
00492 /* 
00493 
00494 #ifndef _STLSOFT_NO_NAMESPACE
00495 } // namespace stlsoft
00496 #endif /* _STLSOFT_NO_NAMESPACE */
00497 
00498 /* 
00499 
00500 #endif /* !STLSOFT_INCL_H_STLSOFT_CONSTRAINTS */
00501 
00502 /* 

STLSoft Libraries documentation © Synesis Software Pty Ltd, 2001-2004