00001 /* 00002 * Copyright (C) 2003-2009 Olivier Boudeville 00003 * 00004 * This file is part of the Ceylan library. 00005 * 00006 * The Ceylan library is free software: you can redistribute it and/or modify 00007 * it under the terms of either the GNU Lesser General Public License or 00008 * the GNU General Public License, as they are published by the Free Software 00009 * Foundation, either version 3 of these Licenses, or (at your option) 00010 * any later version. 00011 * 00012 * The Ceylan library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License and the GNU General Public License 00016 * for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License and the GNU General Public License along with the Ceylan library. 00020 * If not, see <http://www.gnu.org/licenses/>. 00021 * 00022 * Author: Olivier Boudeville (olivier.boudeville@esperide.com) 00023 * 00024 */ 00025 00026 00027 #ifndef CEYLAN_TYPES_H_ 00028 #define CEYLAN_TYPES_H_ 00029 00030 00031 #include <list> // for ListSize 00032 00033 00034 // Could be used to define bound: #include <climits> 00035 00036 00052 /* 00053 * inttypes.h is to be preferred to stdint.h, since the former is more 00054 * portable and includes the latter when appropriate. 00055 * 00056 * Even inttypes.h is not included here since it is not present on all 00057 * platforms. 00058 * Otherwise we would need to use here a CEYLAN_USES_INTTYPES_H, which 00059 * would force us to include beforehand CeylanConfig.h (our "config.h"). 00060 * It would not be satisfactory in installed headers, because of risks of 00061 * name clashes. 00062 * 00063 * For the moment, we dodge the issue and use fairly the same tricks as SDL 00064 * (http://www.libsdl.org, see SDL_types.h). 00065 * 00066 * cstdint, defined in Boost (http://www.boost.org), is sadly not existing 00067 * yet in the C++ standard. 00068 * 00069 * On the Nintendo DS, we could use also datatypes defined in libnds. 00070 * 00071 */ 00072 //#include <inttypes.h> // for int8_t and others 00073 00074 00075 00076 namespace Ceylan 00077 { 00078 00079 00080 /* 00081 * Links can be made between the Ceylan basic data types (ex: Sint16) and 00082 * the ones defined by the C language (ex: signed short) and by OpenGL 00083 * (ex: GLshort). 00084 * 00085 * C synonyms to data types are specified, then OpenGL ones (they all 00086 * start with'GL'). 00087 * 00088 * For each Ceylan basic numerical datatype, its lower and higher accepted 00089 * values are specified. For example, if x is a Uint8, then: 00090 * Uint8Min <= x <= Uint8Max (hence Min and Max bounds are included). 00091 * 00092 * @note Depending on the platform and the compiler, size of C types may 00093 * differ. All sizes are therefore checked at compile time (see 00094 * CEYLAN_COMPILE_TIME_ASSERT) and at run-time (see 00095 * testCeylanBasicDatatypes.cc). 00096 * 00097 * @note For example, int (signed or not) is 4 bytes (32 bits) on 32-bit 00098 * processors, and 2 bytes (16 bits) on 16-bit processors. With 4-bit 00099 * processors, it will be probably a mess again. 00100 * 00101 */ 00102 00103 00104 // First, integer types. 00105 00106 00107 00116 typedef signed char Sint8 ; 00117 00118 extern CEYLAN_DLL Ceylan::Sint8 Sint8Min /* = -128 */ ; 00119 extern CEYLAN_DLL Ceylan::Sint8 Sint8Max /* = 127 */ ; 00120 00121 00122 00131 typedef unsigned char Uint8 ; 00132 00133 extern CEYLAN_DLL Ceylan::Uint8 Uint8Min /* = 0 */ ; 00134 extern CEYLAN_DLL Ceylan::Uint8 Uint8Max /* = 255 */ ; 00135 00136 00137 00164 typedef char Byte ; 00165 00166 extern CEYLAN_DLL Ceylan::Byte ByteMin /* should be -128 */ ; 00167 extern CEYLAN_DLL Ceylan::Byte ByteMax /* should be 127 */ ; 00168 00169 00170 00179 typedef signed short Sint16 ; 00180 00181 extern CEYLAN_DLL Ceylan::Sint16 Sint16Min /* = -32768 */ ; 00182 extern CEYLAN_DLL Ceylan::Sint16 Sint16Max /* = 32767 */ ; 00183 00184 00185 00194 typedef unsigned short Uint16 ; 00195 00196 extern CEYLAN_DLL Ceylan::Uint16 Uint16Min /* = 0 */ ; 00197 extern CEYLAN_DLL Ceylan::Uint16 Uint16Max /* = 65535 */ ; 00198 00199 00200 00201 00210 typedef signed int Sint32 ; 00211 00212 00213 /* 00214 * Actually is -2147483648 but is incremented since 00215 * 'this decimal constant is unsigned only in ISO C90'. 00216 * 00217 */ 00218 extern CEYLAN_DLL Ceylan::Sint32 Sint32Min /* = -2147483648 */ ; 00219 extern CEYLAN_DLL Ceylan::Sint32 Sint32Max /* = 2147483647 */ ; 00220 00221 00222 00231 typedef unsigned int Uint32 ; 00232 00233 extern CEYLAN_DLL Ceylan::Uint32 Uint32Min /* = 0 */ ; 00234 extern CEYLAN_DLL Ceylan::Uint32 Uint32Max /* = 4294967295 */ ; 00235 00236 00237 00238 00249 typedef signed long SignedLongInteger ; 00250 00251 extern CEYLAN_DLL Ceylan::SignedLongInteger SignedLongIntegerMin ; 00252 extern CEYLAN_DLL Ceylan::SignedLongInteger SignedLongIntegerMax ; 00253 00254 00255 00267 typedef unsigned long UnsignedLongInteger ; 00268 00269 extern CEYLAN_DLL Ceylan::UnsignedLongInteger UnsignedLongIntegerMin ; 00270 extern CEYLAN_DLL Ceylan::UnsignedLongInteger UnsignedLongIntegerMax ; 00271 00272 00273 00301 /* 00302 * Identifies whether there exists a suitable 64-bit type: 00303 * (64-bit datatype is not supported on all platforms) 00304 * 00305 */ 00306 #if !defined(__STRICT_ANSI__) 00307 #if defined(__GNUC__) || defined(__MWERKS__) || defined(__SUNPRO_C) || defined(__DECC) 00308 #define CEYLAN_64_BIT_TYPE long long 00309 #elif defined(_MSC_VER) 00310 // Visual C++: 00311 #define CEYLAN_64_BIT_TYPE __int64 00312 #endif // if defined(__GNUC__)... 00313 #endif // ! __STRICT_ANSI__ 00314 00315 00316 // The 64-bit type is not available on EPOC/Symbian OS: 00317 #ifdef __SYMBIAN32__ 00318 #undef CEYLAN_64_BIT_TYPE 00319 #endif // __SYMBIAN32__ 00320 00321 00322 00323 // Now defines accordingly this 64-bit type: 00324 #ifdef CEYLAN_64_BIT_TYPE 00325 00326 00335 typedef unsigned CEYLAN_64_BIT_TYPE Uint64 ; 00336 00337 00346 typedef signed CEYLAN_64_BIT_TYPE Sint64 ; 00347 00348 00349 #else // CEYLAN_64_BIT_TYPE 00350 00351 #define CEYLAN_FAKES_64_BIT_TYPE 00352 00354 typedef struct 00355 { 00356 00357 Ceylan::Uint32 hi ; 00358 Ceylan::Uint32 lo ; 00359 00360 } Uint64, Sint64 ; 00361 00362 00363 #endif // CEYLAN_64_BIT_TYPE 00364 00365 00366 00367 /* 00368 * From here normally Ceylan::Uint64 and Ceylan::Sint64 can be used in 00369 * all cases. 00370 * 00371 * 00372 */ 00373 00374 00395 typedef float Float32 ; 00396 00397 extern CEYLAN_DLL Ceylan::Float32 Float32Min /* = -3.4E-38 */ ; 00398 extern CEYLAN_DLL Ceylan::Float32 Float32Max /* = 3.4E38 */ ; 00399 00400 00411 typedef double Float64 ; 00412 00413 extern CEYLAN_DLL Ceylan::Float64 Float64Min /* = -1.7E-308 */ ; 00414 extern CEYLAN_DLL Ceylan::Float64 Float64Max /* = 1.7E308 */ ; 00415 00416 00417 00418 /* 00419 * Very large floating point values are not encapsulated with regard to 00420 * their bit widths since they depend too much on the underlying platform. 00421 * 00422 * For example, GNU/Linux IA32 thinks `long double' is 96-bits (while the 00423 * real number of used bits is only 80, both in processor and in memory), 00424 * whereas HP-UX thinks it is 128-bits, other 80, etc. 00425 * 00426 * So the largest fixed-size floating point value used by Ceylan is 00427 * Ceylan::Float64 (64-bits). 00428 * 00429 * One can use nevertheless (Un)SignedLongFloat, provided she does not 00430 * rely on any specific bit width. 00431 * 00432 */ 00433 00434 00445 typedef long double LongFloat ; 00446 00447 extern CEYLAN_DLL Ceylan::LongFloat LongFloatMin ; 00448 extern CEYLAN_DLL Ceylan::LongFloat LongFloatMax ; 00449 00450 00451 00462 //typedef long double Float80 ; 00463 00464 //extern CEYLAN_DLL Ceylan::Float80 Float80Min /* = -3.4E-4932 */ ; 00465 00466 /* 00467 * Actually is 3.4E4932 but is set to a lower value (the highest 00468 * possible one) since 'floating constant exceeds range of double'. 00469 * 00470 */ 00471 //extern CEYLAN_DLL Ceylan::Float80 Float80Max 00472 // /*= 3.4E4932 in theory, 1.7E308 actually */ ; 00473 00474 00475 00480 //typedef long double Float96 ; 00481 00482 00483 //extern CEYLAN_DLL Ceylan::Float96 Float96Min /* = -3.4E-4932 */ ; 00484 00485 /* 00486 * Actually is 3.4E4932 but is set to a lower value (the highest 00487 * possible one) since 'floating constant exceeds range of double'. 00488 * 00489 */ 00490 //extern CEYLAN_DLL Ceylan::Float96 Float96Max 00491 // /*= 3.4E4932 in theory, 1.7E308 actually */ ; 00492 00493 00494 00495 00501 typedef Ceylan::Uint16 Count ; 00502 00503 00504 00514 typedef std::list<Ceylan::Uint16>::size_type ListSize ; 00515 00516 00517 00519 typedef Ceylan::Uint32 Flags ; 00520 00521 00522 /* 00523 * Makes sure the data types really have the right sizes, thanks to a 00524 * trick coming from SDL: 00525 * if the size of tested type does not match desired value, expression 00526 * 'sizeof(t) == n' is false (0) and the macro attempts to define an 00527 * array of '0*2 -1' = -1 element, which results in a compilation error, 00528 * such as 'error: size of array 00529 * `CEYLAN_stop_wrong_size_for_uint64' is negative'. 00530 * 00531 * If the sizes are the expected ones, all arrays have exactly one element 00532 * and the compiler does not complain. 00533 * 00534 */ 00535 #define CEYLAN_COMPILE_TIME_ASSERT(name, x) \ 00536 typedef int CEYLAN_stop_wrong_size_for_ ## name[(x) * 2 - 1] 00537 00538 CEYLAN_COMPILE_TIME_ASSERT( uint8, sizeof(Uint8) == 1 ) ; 00539 CEYLAN_COMPILE_TIME_ASSERT( sint8, sizeof(Sint8) == 1 ) ; 00540 00541 CEYLAN_COMPILE_TIME_ASSERT( uint16, sizeof(Uint16) == 2 ) ; 00542 CEYLAN_COMPILE_TIME_ASSERT( sint16, sizeof(Sint16) == 2 ) ; 00543 00544 CEYLAN_COMPILE_TIME_ASSERT( uint32, sizeof(Uint32) == 4 ) ; 00545 CEYLAN_COMPILE_TIME_ASSERT( sint32, sizeof(Sint32) == 4 ) ; 00546 CEYLAN_COMPILE_TIME_ASSERT( float32, sizeof(Float32) == 4 ) ; 00547 00548 CEYLAN_COMPILE_TIME_ASSERT( uint64, sizeof(Uint64) == 8 ) ; 00549 CEYLAN_COMPILE_TIME_ASSERT( sint64, sizeof(Sint64) == 8 ) ; 00550 CEYLAN_COMPILE_TIME_ASSERT( float64, sizeof(Float64) == 8 ) ; 00551 00552 //CEYLAN_COMPILE_TIME_ASSERT( Float96, sizeof(Float96) == 12 ) ; 00553 00554 00555 } 00556 00557 00558 00559 #endif // CEYLAN_TYPES_H_ 00560