Sirikata
libcore/include/sirikata/core/util/Platform.hpp
Go to the documentation of this file.
00001 /*  Sirikata -- Platform Dependent Definitions
00002  *  Platform.hpp
00003  *
00004  *  Copyright (c) 2009, Ewen Cheslack-Postava and Daniel Reiter Horn
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions are
00009  *  met:
00010  *  * Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer.
00012  *  * Redistributions in binary form must reproduce the above copyright
00013  *    notice, this list of conditions and the following disclaimer in
00014  *    the documentation and/or other materials provided with the
00015  *    distribution.
00016  *  * Neither the name of Sirikata nor the names of its contributors may
00017  *    be used to endorse or promote products derived from this software
00018  *    without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00021  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00022  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00023  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
00024  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00025  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00026  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00027  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00028  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00029  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00030  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00031  */
00032 
00033 #ifndef _SIRIKATA_PLATFORM_HPP_
00034 #define _SIRIKATA_PLATFORM_HPP_
00035 
00036 
00037 #define SIRIKATA_PLATFORM_WINDOWS 0
00038 #define SIRIKATA_PLATFORM_LINUX   1
00039 #define SIRIKATA_PLATFORM_MAC     2
00040 
00041 
00042 #if defined(__WIN32__) || defined(_WIN32)
00043 #  define SIRIKATA_PLATFORM SIRIKATA_PLATFORM_WINDOWS
00044 #elif defined(__APPLE_CC__) || defined(__APPLE__)
00045 #  define SIRIKATA_PLATFORM SIRIKATA_PLATFORM_MAC
00046 #  ifndef __MACOSX__
00047 #    define __MACOSX__
00048 #  endif
00049 #else
00050 #  define SIRIKATA_PLATFORM SIRIKATA_PLATFORM_LINUX
00051 #endif
00052 
00053 #ifdef SIRIKATA_DEBUG_BUILD
00054 #define SIRIKATA_DEBUG 1
00055 #else
00056 #define SIRIKATA_DEBUG 0
00057 #endif
00058 
00059 #ifndef SIRIKATA_EXPORT
00060 # if SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_WINDOWS
00061 #   if defined(STATIC_LINKED)
00062 #     define SIRIKATA_EXPORT
00063 #   else
00064 #     if defined(SIRIKATA_BUILD)
00065 #       define SIRIKATA_EXPORT __declspec(dllexport)
00066 #       define SIRIKATA_EXPORT_TEMPLATE
00067 #     else
00068 #       define SIRIKATA_EXPORT __declspec(dllimport)
00069 #       define SIRIKATA_EXPORT_TEMPLATE extern
00070 #     endif
00071 #   endif
00072 #   define SIRIKATA_PLUGIN_EXPORT __declspec(dllexport)
00073 # else
00074 #   if defined(__GNUC__) && __GNUC__ >= 4
00075 #     define SIRIKATA_EXPORT __attribute__ ((visibility("default")))
00076 #     define SIRIKATA_PLUGIN_EXPORT __attribute__ ((visibility("default")))
00077 #   else
00078 #     define SIRIKATA_EXPORT
00079 #     define SIRIKATA_PLUGIN_EXPORT
00080 #   endif
00081 #   define SIRIKATA_EXPORT_TEMPLATE
00082 # endif
00083 #endif
00084 
00085 
00086 #ifndef SIRIKATA_FUNCTION_EXPORT
00087 # if SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_WINDOWS
00088 #   if defined(STATIC_LINKED)
00089 #     define SIRIKATA_FUNCTION_EXPORT
00090 #   else
00091 #     if defined(SIRIKATA_BUILD)
00092 #       define SIRIKATA_FUNCTION_EXPORT __declspec(dllexport)
00093 #     else
00094 #       define SIRIKATA_FUNCTION_EXPORT __declspec(dllimport)
00095 #     endif
00096 #   endif
00097 # else
00098 #   if defined(__GNUC__) && __GNUC__ >= 4
00099 #     define SIRIKATA_FUNCTION_EXPORT __attribute__ ((visibility("default")))
00100 #   else
00101 #     define SIRIKATA_FUNCTION_EXPORT
00102 #   endif
00103 # endif
00104 #endif
00105 
00106 
00107 
00108 #ifndef SIRIKATA_EXPORT_C
00109 # define SIRIKATA_EXPORT_C extern "C" SIRIKATA_EXPORT
00110 #endif
00111 
00112 #ifndef SIRIKATA_PLUGIN_EXPORT_C
00113 # define SIRIKATA_PLUGIN_EXPORT_C extern "C" SIRIKATA_PLUGIN_EXPORT
00114 #endif
00115 
00116 
00117 // Where supported, marking a function with WARN_UNUSED will cause the compiler
00118 // to complain if a caller ignores the return value.
00119 #ifndef WARN_UNUSED
00120 # if defined(__GNUC__) && __GNUC__ >= 4  // This is conservative, maybe be available with earlier versions
00121 #  define WARN_UNUSED __attribute__((warn_unused_result))
00122 # else
00123 #  define WARN_UNUSED
00124 # endif
00125 #endif
00126 
00127 
00128 #ifdef __GLIBC__
00129 # include <endian.h>
00130 # define SIRIKATA_LITTLE_ENDIAN __LITTLE_ENDIAN
00131 # define SIRIKATA_BIG_ENDIAN    __BIG_ENDIAN
00132 # define SIRIKATA_BYTE_ORDER    __BYTE_ORDER
00133 #elif defined(__APPLE__) || defined(MACOSX) || defined(BSD) || defined(__FreeBSD__)
00134 # include<machine/endian.h>
00135 # ifdef BYTE_ORDER
00136 #  define SIRIKATA_LITTLE_ENDIAN LITTLE_ENDIAN
00137 #  define SIRIKATA_BIG_ENDIAN    BIG_ENDIAN
00138 #  define SIRIKATA_BYTE_ORDER    BYTE_ORDER
00139 # else
00140 #  error "MACINTOSH DOES NOT DEFINE ENDIANNESS"
00141 # endif
00142 #else
00143 # define SIRIKATA_LITTLE_ENDIAN 1234
00144 # define SIRIKATA_BIG_ENDIAN    4321
00145 # ifdef _BIG_ENDIAN
00146 #  define SIRIKATA_BYTE_ORDER SIRIKATA_BIG_ENDIAN
00147 #  ifdef _LITTLE_ENDIAN
00148 #   error "BOTH little and big endian defined"
00149 #  endif
00150 # else
00151 #  ifdef _LITTLE_ENDIAN
00152 #   define SIRIKATA_BYTE_ORDER SIRIKATA_LITTLE_ENDIAN
00153 #  elif defined(__sparc) || defined(__sparc__) \
00154    ||   defined(_POWER) || defined(__powerpc__) \
00155    ||   defined(__ppc__) || defined(__hpux) \
00156    ||   defined(_MIPSEB) || defined(_POWER) \
00157    ||   defined(__s390__)
00158 #   define SIRIKATA_BYTE_ORDER SIRIKATA_BIG_ENDIAN
00159 #  elif defined(__i386__) || defined(__alpha__) \
00160    ||   defined(__ia64) || defined(__ia64__) \
00161    ||   defined(_M_IX86) || defined(_M_IA64) \
00162    ||   defined(_M_ALPHA) || defined(__amd64) \
00163    ||   defined(__amd64__) || defined(_M_AMD64) \
00164    ||   defined(__x86_64) || defined(__x86_64__) \
00165    ||   defined(_M_X64)
00166 #   define SIRIKATA_BYTE_ORDER SIRIKATA_LITTLE_ENDIAN
00167 #  else
00168 #   error "Not a known CPU type"
00169 #  endif
00170 # endif
00171 #endif
00172 
00173 #if SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_WINDOWS
00174 #ifndef NOMINMAX
00175 #define NOMINMAX
00176 #endif
00177 #define WIN32_LEAN_AND_MEAN
00178 #include <windows.h>
00179 //need to get rid of GetMessage for protocol buffer compatibility
00180 #undef GetMessage
00181 #endif
00182 #ifndef _WIN32
00183 #include <stdint.h>
00184 #endif
00185 #include <assert.h>
00186 
00187 #ifdef __cplusplus
00188 
00189 #include <cstddef>
00190 #include <cstring>
00191 #include <cmath>
00192 #include <fstream>
00193 #include <iostream>
00194 #include <string>
00195 #include <sstream>
00196 #include <vector>
00197 #include <list>
00198 #include <queue>
00199 #include <deque>
00200 #include <stack>
00201 #include <set>
00202 #include <map>
00203 #include <algorithm>
00204 
00205 #ifdef __GNUC__
00206 // Required for OGRE.
00207 #if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4
00208 #define BOOST_HAS_GCC_TR1
00209 
00210 // #include_next is broken: it does not search default include paths!
00211 #define BOOST_TR1_DISABLE_INCLUDE_NEXT
00212 // config_all.hpp reads this variable, then sets BOOST_HAS_INCLUDE_NEXT anyway
00213 #include <boost/tr1/detail/config_all.hpp>
00214 #ifdef BOOST_HAS_INCLUDE_NEXT
00215 // This behavior has existed since boost 1.34, unlikely to change.
00216 #undef BOOST_HAS_INCLUDE_NEXT
00217 #endif
00218 
00219 #endif
00220 #endif
00221 
00222 #include <boost/tr1/memory.hpp>
00223 #include <boost/tr1/array.hpp>
00224 #include <boost/tr1/functional.hpp>
00225 #include <boost/tr1/unordered_set.hpp>
00226 #include <boost/tr1/unordered_map.hpp>
00227 
00228 namespace Sirikata {
00229 
00230 // numeric typedefs to get standardized types
00231 typedef unsigned char uchar;
00232 #if SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_WINDOWS
00233 #ifndef NOMINMAX
00234 #define NOMINMAX
00235 #endif
00236 typedef __int8 int8;
00237 typedef unsigned __int8 uint8;
00238 typedef __int16 int16;
00239 typedef unsigned __int16 uint16;
00240 typedef __int32 int32;
00241 typedef unsigned __int32 uint32;
00242 typedef __int64 int64;
00243 typedef unsigned __int64 uint64;
00244 
00245 #else
00246 # include <stdint.h>
00247 typedef int8_t int8;
00248 typedef uint8_t uint8;
00249 typedef int16_t int16;
00250 typedef uint16_t uint16;
00251 typedef int32_t int32;
00252 typedef uint32_t uint32;
00253 typedef int64_t int64;
00254 typedef uint64_t uint64;
00255 #endif
00256 
00257 typedef float float32;
00258 typedef double float64;
00259 
00260 typedef uchar byte;
00261 typedef std::string String;
00262 typedef std::vector<uint8> MemoryBuffer;
00263 
00264 namespace Network {
00265 class IOService;
00266 class Stream;
00267 class Address;
00268 typedef std::vector<uint8> Chunk;
00269 }
00270 #ifdef NDEBUG
00271 class ThreadIdCheck{};
00272 #else
00273 class ThreadIdCheck { public:
00274     unsigned int mThreadId;
00275 };
00276 #endif
00277 class OptionSet;
00278 
00279 namespace Task {
00280 class LocalTime;
00281 class DeltaTime;
00282 }
00283 class Time;
00284 typedef Task::DeltaTime Duration;
00285 
00286 } // namespace Sirikata
00287 #include "Version.hpp"
00288 #include "MemoryReference.hpp"
00289 #include "TotallyOrdered.hpp"
00290 #include "Singleton.hpp"
00291 #include "FactoryWithOptions.hpp"
00292 #include "Vector2.hpp"
00293 #include "Vector3.hpp"
00294 #include "Vector4.hpp"
00295 #include "Matrix3x3.hpp"
00296 #include "Matrix4x4.hpp"
00297 #include "Quaternion.hpp"
00298 #include "SolidAngle.hpp"
00299 #include "SelfWeakPtr.hpp"
00300 #include "Noncopyable.hpp"
00301 #include "Array.hpp"
00302 #include <sirikata/core/options/OptionValue.hpp>
00303 #include "Logging.hpp"
00304 #include "Location.hpp"
00305 #include "VInt.hpp"
00306 namespace Sirikata {
00307 template<class T>T*aligned_malloc(size_t num_bytes, const unsigned char alignment) {
00308     unsigned char *data=(unsigned char*)malloc(num_bytes+alignment);
00309     if (data!=NULL) {
00310         size_t remainder=((size_t)data)%alignment;
00311         size_t offset=alignment-remainder;
00312         data+=offset;
00313         data[-1]=offset;
00314         return (T*)(data);
00315     }
00316     return (T*)NULL;
00317 }
00318 template<class T>T*aligned_new(const unsigned char alignment) {
00319     return aligned_malloc<T>(sizeof(T),alignment);
00320 }
00321 template<class T> void aligned_free(T* data) {
00322     if (data!=NULL) {
00323         unsigned char *bloc=(unsigned char*)data;
00324         unsigned char offset=bloc[-1];
00325         free(bloc-offset);
00326     }
00327 }
00328 
00329 typedef Vector2<float32> Vector2f;
00330 typedef Vector2<float64> Vector2d;
00331 typedef Vector2<uint32> Vector2ui32;
00332 typedef Vector2<int32> Vector2i32;
00333 
00334 typedef Vector3<float32> Vector3f;
00335 typedef Vector3<float64> Vector3d;
00336 typedef Vector3<uint32> Vector3ui32;
00337 typedef Vector3<int32> Vector3i32;
00338 
00339 typedef Vector4<float32> Vector4f;
00340 typedef Vector4<float64> Vector4d;
00341 typedef Vector4<uint32> Vector4ui32;
00342 typedef Vector4<int32> Vector4i32;
00343 
00344 typedef VInt<uint32> vuint32;
00345 typedef VInt<uint64> vuint64;
00346 
00347 using std::tr1::placeholders::_1;
00348 using std::tr1::placeholders::_2;
00349 using std::tr1::placeholders::_3;
00350 using std::tr1::placeholders::_4;
00351 using std::tr1::placeholders::_5;
00352 using std::tr1::placeholders::_6;
00353 using std::tr1::placeholders::_7;
00354 using std::tr1::placeholders::_8;
00355 using std::tr1::placeholders::_9;
00356 }
00357 #include "BoundingSphere.hpp"
00358 #include "BoundingBox.hpp"
00359 namespace Sirikata {
00360 typedef BoundingBox<float32> BoundingBox3f3f;
00361 typedef BoundingBox<float64> BoundingBox3d3f;
00362 typedef BoundingBox<float32> BoundingBox3f;
00363 typedef BoundingBox<float64> BoundingBox3d;
00364 typedef BoundingSphere<float32> BoundingSphere3f;
00365 typedef BoundingSphere<float64> BoundingSphere3d;
00366 }
00367 
00368 // A select few system-wide types
00369 namespace Sirikata {
00370 
00371 typedef uint32 ServerID;
00372 #define NullServerID 0
00373 struct ServerIDNull {
00374     ServerID operator()() {
00375         return NullServerID;
00376     };
00377 };
00378 struct ServerIDRandom {
00379     ServerID operator()() {
00380         // Because ServerIDs aren't really random (we start allocating linearly
00381         // from 1), this just tries to generate one that won't conflict by
00382         // choosing a large number ( > 1,000,000).
00383         return (1 << 20) + (rand() % (1 << 20));
00384     };
00385 };
00386 
00387 // Space Server Regions
00388 typedef std::vector<BoundingBox3f> BoundingBoxList;
00389 struct SegmentationInfo {
00390     ServerID server;
00391     BoundingBoxList region;
00392 };
00393 
00394 struct ObjectHostID {
00395     ObjectHostID()
00396      : id(0)
00397     {
00398     }
00399 
00400     explicit ObjectHostID(uint64 _id)
00401      : id(_id)
00402     {
00403     }
00404 
00405     uint64 id;
00406 };
00407 
00408 SIRIKATA_FUNCTION_EXPORT uint32 uint32_lexical_cast(const String& rhs);
00409 SIRIKATA_FUNCTION_EXPORT std::ostream& operator<<(std::ostream& os, const ObjectHostID& rhs);
00410 SIRIKATA_FUNCTION_EXPORT std::istream& operator>>(std::istream& is, ObjectHostID& rhs);
00411 
00412 } // namespace Sirikata
00413 
00414 #if 0
00415 template class std::tr1::unordered_map<Sirikata::int32, Sirikata::int32>;
00416 template class std::tr1::unordered_map<Sirikata::uint32, Sirikata::uint32>;
00417 template class std::tr1::unordered_map<Sirikata::uint64, Sirikata::uint64>;
00418 template class std::tr1::unordered_map<Sirikata::int64, Sirikata::int64>;
00419 template class std::tr1::unordered_map<Sirikata::String, Sirikata::String>;
00420 
00421 template class std::tr1::unordered_map<Sirikata::int32, void*>;
00422 template class std::tr1::unordered_map<Sirikata::uint32, void*>;
00423 template class std::tr1::unordered_map<Sirikata::uint64, void*>;
00424 template class std::tr1::unordered_map<Sirikata::int64, void*>;
00425 template class std::tr1::unordered_map<Sirikata::String, void*>;
00426 template class std::map<Sirikata::int32, Sirikata::int32>;
00427 template class std::map<Sirikata::uint32, Sirikata::uint32>;
00428 template class std::map<Sirikata::uint64, Sirikata::uint64>;
00429 template class std::map<Sirikata::int64, Sirikata::int64>;
00430 template class std::map<Sirikata::String, Sirikata::String>;
00431 template class std::map<Sirikata::int32, void*>;
00432 template class std::map<Sirikata::uint32, void*>;
00433 template class std::map<Sirikata::uint64, void*>;
00434 template class std::map<Sirikata::int64, void*>;
00435 template class std::map<Sirikata::String, void*>;
00436 template class std::vector<Sirikata::String>;
00437 template class std::vector<void*>;
00438 template class std::vector<Sirikata::int8>;
00439 template class std::vector<Sirikata::uint8>;
00440 #endif
00441 #endif //__cplusplus
00442 #endif //_SIRIKATA_PLATFORM_HPP_