Initial commit

This commit is contained in:
2022-10-08 17:16:13 -04:00
commit 385638c5e1
1925 changed files with 872504 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
/******************************************************************************
* Project: libspatialindex - A C++ library for spatial indexing
* Author: Marios Hadjieleftheriou, mhadji@gmail.com
******************************************************************************
* Copyright (c) 2004, Marios Hadjieleftheriou
*
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
******************************************************************************/
#pragma once
#include "PoolPointer.h"
namespace Tools
{
template <class X> class PointerPool
{
public:
explicit PointerPool(uint32_t capacity) : m_capacity(capacity)
{
#ifndef NDEBUG
m_hits = 0;
m_misses = 0;
m_pointerCount = 0;
#endif
}
~PointerPool()
{
assert(m_pool.size() <= m_capacity);
while (! m_pool.empty())
{
X* x = m_pool.top(); m_pool.pop();
#ifndef NDEBUG
--m_pointerCount;
#endif
delete x;
}
#ifndef NDEBUG
std::cerr << "Lost pointers: " << m_pointerCount << std::endl;
#endif
}
PoolPointer<X> acquire()
{
X* p = 0;
if (! m_pool.empty())
{
p = m_pool.top(); m_pool.pop();
#ifndef NDEBUG
m_hits++;
#endif
}
else
{
p = new X();
#ifndef NDEBUG
m_pointerCount++;
m_misses++;
#endif
}
return PoolPointer<X>(p, this);
}
void release(X* p)
{
if (m_pool.size() < m_capacity)
{
m_pool.push(p);
}
else
{
#ifndef NDEBUG
--m_pointerCount;
#endif
delete p;
}
assert(m_pool.size() <= m_capacity);
}
uint32_t getCapacity() const { return m_capacity; }
void setCapacity(uint32_t c)
{
assert (c >= 0);
m_capacity = c;
}
private:
uint32_t m_capacity;
std::stack<X*> m_pool;
#ifndef NDEBUG
public:
uint64_t m_hits;
uint64_t m_misses;
uint64_t m_pointerCount;
#endif
};
}

View File

@@ -0,0 +1,102 @@
/******************************************************************************
* Project: libspatialindex - A C++ library for spatial indexing
* Author: Marios Hadjieleftheriou, mhadji@gmail.com
******************************************************************************
* Copyright (c) 2004, Marios Hadjieleftheriou
*
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
******************************************************************************/
#pragma once
#include "PointerPool.h"
namespace Tools
{
template <class X> class PointerPool;
template <class X> class PoolPointer
{
public:
explicit PoolPointer(X* p = 0) : m_pointer(p), m_pPool(0) { m_prev = m_next = this; }
explicit PoolPointer(X* p, PointerPool<X>* pPool) throw() : m_pointer(p), m_pPool(pPool) { m_prev = m_next = this; }
~PoolPointer() { release(); }
PoolPointer(const PoolPointer& p) throw() { acquire(p); }
PoolPointer& operator=(const PoolPointer& p)
{
if (this != &p)
{
release();
acquire(p);
}
return *this;
}
X& operator*() const throw() { return *m_pointer; }
X* operator->() const throw() { return m_pointer; }
X* get() const throw() { return m_pointer; }
bool unique() const throw() { return m_prev ? m_prev == this : true; }
void relinquish() throw()
{
m_pPool = 0;
m_pointer = 0;
release();
}
private:
X* m_pointer;
mutable const PoolPointer* m_prev;
mutable const PoolPointer* m_next;
PointerPool<X>* m_pPool;
void acquire(const PoolPointer& p) throw()
{
m_pPool = p.m_pPool;
m_pointer = p.m_pointer;
m_next = p.m_next;
m_next->m_prev = this;
m_prev = &p;
#ifndef mutable
p.m_next = this;
#else
(const_cast<linked_ptr<X>*>(&p))->m_next = this;
#endif
}
void release()
{
if (unique())
{
if (m_pPool != 0) m_pPool->release(m_pointer);
else delete m_pointer;
}
else
{
m_prev->m_next = m_next;
m_next->m_prev = m_prev;
m_prev = m_next = 0;
}
m_pointer = 0;
m_pPool = 0;
}
};
}

View File

@@ -0,0 +1,84 @@
/******************************************************************************
* Project: libspatialindex - A C++ library for spatial indexing
* Author: Marios Hadjieleftheriou, mhadji@gmail.com
******************************************************************************
* Copyright (c) 2004, Marios Hadjieleftheriou
*
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
******************************************************************************/
#pragma once
namespace Tools
{
template <class X> class SmartPointer
{
public:
explicit SmartPointer(X* p = 0) throw() : m_pointer(p) { m_prev = m_next = this; }
~SmartPointer() { release(); }
SmartPointer(const SmartPointer& p) throw() { acquire(p); }
SmartPointer& operator=(const SmartPointer& p)
{
if (this != &p)
{
release();
acquire(p);
}
return *this;
}
X& operator*() const throw() { return *m_pointer; }
X* operator->() const throw() { return m_pointer; }
X* get() const throw() { return m_pointer; }
bool unique() const throw() { return m_prev ? m_prev == this : true; }
private:
X* m_pointer;
mutable const SmartPointer* m_prev;
mutable const SmartPointer* m_next;
void acquire(const SmartPointer& p) throw()
{
m_pointer = p.m_pointer;
m_next = p.m_next;
m_next->m_prev = this;
m_prev = &p;
#ifndef mutable
p.m_next = this;
#else
(const_cast<linked_ptr<X>*>(&p))->m_next = this;
#endif
}
void release()
{
if (unique()) delete m_pointer;
else
{
m_prev->m_next = m_next;
m_next->m_prev = m_prev;
m_prev = m_next = 0;
}
m_pointer = 0;
}
};
}

View File

@@ -0,0 +1,507 @@
/******************************************************************************
* Project: libspatialindex - A C++ library for spatial indexing
* Author: Marios Hadjieleftheriou, mhadji@gmail.com
******************************************************************************
* Copyright (c) 2004, Marios Hadjieleftheriou
*
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
******************************************************************************/
#pragma once
#if (defined _WIN32 || defined _WIN64 || defined WIN32 || defined WIN64) && !defined __GNUC__
typedef __int8 int8_t;
typedef __int16 int16_t;
typedef __int32 int32_t;
typedef __int64 int64_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
// Nuke this annoying warning. See http://www.unknownroad.com/rtfm/VisualStudio/warningC4251.html
#pragma warning( disable: 4251 )
#else
#include <stdint.h>
#endif
#if (defined _WIN32 || defined _WIN64 || defined WIN32 || defined WIN64) && !defined __GNUC__
#ifdef SPATIALINDEX_CREATE_DLL
#define SIDX_DLL __declspec(dllexport)
#else
#define SIDX_DLL __declspec(dllimport)
#endif
#else
#define SIDX_DLL
#endif
#include <assert.h>
#include <iostream>
#include <iomanip>
#include <iterator>
#include <string>
#include <sstream>
#include <fstream>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <list>
#include <algorithm>
#include <cwchar>
#if HAVE_PTHREAD_H
#include <pthread.h>
#endif
#include "SmartPointer.h"
#include "PointerPool.h"
#include "PoolPointer.h"
typedef uint8_t byte;
namespace Tools
{
SIDX_DLL enum IntervalType
{
IT_RIGHTOPEN = 0x0,
IT_LEFTOPEN,
IT_OPEN,
IT_CLOSED
};
SIDX_DLL enum VariantType
{
VT_LONG = 0x0,
VT_BYTE,
VT_SHORT,
VT_FLOAT,
VT_DOUBLE,
VT_CHAR,
VT_USHORT,
VT_ULONG,
VT_INT,
VT_UINT,
VT_BOOL,
VT_PCHAR,
VT_PVOID,
VT_EMPTY,
VT_LONGLONG,
VT_ULONGLONG,
VT_PWCHAR
};
SIDX_DLL enum FileMode
{
APPEND = 0x0,
CREATE
};
//
// Exceptions
//
class SIDX_DLL Exception
{
public:
virtual std::string what() = 0;
virtual ~Exception() {}
};
class SIDX_DLL IndexOutOfBoundsException : public Exception
{
public:
IndexOutOfBoundsException(size_t i);
virtual ~IndexOutOfBoundsException() {}
virtual std::string what();
private:
std::string m_error;
}; // IndexOutOfBoundsException
class SIDX_DLL IllegalArgumentException : public Exception
{
public:
IllegalArgumentException(std::string s);
virtual ~IllegalArgumentException() {}
virtual std::string what();
private:
std::string m_error;
}; // IllegalArgumentException
class SIDX_DLL IllegalStateException : public Exception
{
public:
IllegalStateException(std::string s);
virtual ~IllegalStateException() {}
virtual std::string what();
private:
std::string m_error;
}; // IllegalStateException
class SIDX_DLL EndOfStreamException : public Exception
{
public:
EndOfStreamException(std::string s);
virtual ~EndOfStreamException() {}
virtual std::string what();
private:
std::string m_error;
}; // EndOfStreamException
class SIDX_DLL ResourceLockedException : public Exception
{
public:
ResourceLockedException(std::string s);
virtual ~ResourceLockedException() {}
virtual std::string what();
private:
std::string m_error;
}; // ResourceLockedException
class SIDX_DLL NotSupportedException : public Exception
{
public:
NotSupportedException(std::string s);
virtual ~NotSupportedException() {}
virtual std::string what();
private:
std::string m_error;
}; // NotSupportedException
//
// Interfaces
//
class SIDX_DLL IInterval
{
public:
virtual ~IInterval() {}
virtual double getLowerBound() const = 0;
virtual double getUpperBound() const = 0;
virtual void setBounds(double, double) = 0;
virtual bool intersectsInterval(const IInterval&) const = 0;
virtual bool intersectsInterval(IntervalType type, const double start, const double end) const = 0;
virtual bool containsInterval(const IInterval&) const = 0;
virtual IntervalType getIntervalType() const = 0;
}; // IInterval
class SIDX_DLL IObject
{
public:
virtual ~IObject() {}
virtual IObject* clone() = 0;
// return a new object that is an exact copy of this one.
// IMPORTANT: do not return the this pointer!
}; // IObject
class SIDX_DLL ISerializable
{
public:
virtual ~ISerializable() {}
virtual uint32_t getByteArraySize() = 0;
// returns the size of the required byte array.
virtual void loadFromByteArray(const byte* data) = 0;
// load this object using the byte array.
virtual void storeToByteArray(byte** data, uint32_t& length) = 0;
// store this object in the byte array.
};
class SIDX_DLL IComparable
{
public:
virtual ~IComparable() {}
virtual bool operator<(const IComparable& o) const = 0;
virtual bool operator>(const IComparable& o) const = 0;
virtual bool operator==(const IComparable& o) const = 0;
}; //IComparable
class SIDX_DLL IObjectComparator
{
public:
virtual ~IObjectComparator() {}
virtual int compare(IObject* o1, IObject* o2) = 0;
}; // IObjectComparator
class SIDX_DLL IObjectStream
{
public:
virtual ~IObjectStream() {}
virtual IObject* getNext() = 0;
// returns a pointer to the next entry in the
// stream or 0 at the end of the stream.
virtual bool hasNext() = 0;
// returns true if there are more items in the stream.
virtual uint32_t size() = 0;
// returns the total number of entries available in the stream.
virtual void rewind() = 0;
// sets the stream pointer to the first entry, if possible.
}; // IObjectStream
//
// Classes & Functions
//
class SIDX_DLL Variant
{
public:
Variant();
VariantType m_varType;
union
{
int16_t iVal; // VT_SHORT
int32_t lVal; // VT_LONG
int64_t llVal; // VT_LONGLONG
byte bVal; // VT_BYTE
float fltVal; // VT_FLOAT
double dblVal; // VT_DOUBLE
char cVal; // VT_CHAR
uint16_t uiVal; // VT_USHORT
uint32_t ulVal; // VT_ULONG
uint64_t ullVal; // VT_ULONGLONG
bool blVal; // VT_BOOL
char* pcVal; // VT_PCHAR
void* pvVal; // VT_PVOID
wchar_t* pwcVal;
} m_val;
}; // Variant
class SIDX_DLL PropertySet;
SIDX_DLL std::ostream& operator<<(std::ostream& os, const Tools::PropertySet& p);
class SIDX_DLL PropertySet : public ISerializable
{
public:
PropertySet();
PropertySet(const byte* data);
virtual ~PropertySet();
Variant getProperty(std::string property) const;
void setProperty(std::string property, Variant const& v);
void removeProperty(std::string property);
virtual uint32_t getByteArraySize();
virtual void loadFromByteArray(const byte* data);
virtual void storeToByteArray(byte** data, uint32_t& length);
private:
std::map<std::string, Variant> m_propertySet;
// #ifdef HAVE_PTHREAD_H
// pthread_rwlock_t m_rwLock;
// #else
// bool m_rwLock;
// #endif
friend SIDX_DLL std::ostream& Tools::operator<<(std::ostream& os, const Tools::PropertySet& p);
}; // PropertySet
// does not support degenerate intervals.
class SIDX_DLL Interval : public IInterval
{
public:
Interval();
Interval(IntervalType, double, double);
Interval(double, double);
Interval(const Interval&);
virtual ~Interval() {}
virtual IInterval& operator=(const IInterval&);
virtual bool operator==(const Interval&) const;
virtual bool operator!=(const Interval&) const;
virtual double getLowerBound() const;
virtual double getUpperBound() const;
virtual void setBounds(double, double);
virtual bool intersectsInterval(const IInterval&) const;
virtual bool intersectsInterval(IntervalType type, const double start, const double end) const;
virtual bool containsInterval(const IInterval&) const;
virtual IntervalType getIntervalType() const;
IntervalType m_type;
double m_low;
double m_high;
}; // Interval
SIDX_DLL std::ostream& operator<<(std::ostream& os, const Tools::Interval& iv);
class SIDX_DLL Random
{
public:
Random();
Random(uint32_t seed, uint16_t xsubi0);
virtual ~Random();
int32_t nextUniformLong();
// returns a uniformly distributed long.
uint32_t nextUniformUnsignedLong();
// returns a uniformly distributed unsigned long.
int32_t nextUniformLong(int32_t low, int32_t high);
// returns a uniformly distributed long in the range [low, high).
uint32_t nextUniformUnsignedLong(uint32_t low, uint32_t high);
// returns a uniformly distributed unsigned long in the range [low, high).
int64_t nextUniformLongLong();
// returns a uniformly distributed long long.
uint64_t nextUniformUnsignedLongLong();
// returns a uniformly distributed unsigned long long.
int64_t nextUniformLongLong(int64_t low, int64_t high);
// returns a uniformly distributed unsigned long long in the range [low, high).
uint64_t nextUniformUnsignedLongLong(uint64_t low, uint64_t high);
// returns a uniformly distributed unsigned long long in the range [low, high).
int16_t nextUniformShort();
// returns a uniformly distributed short.
uint16_t nextUniformUnsignedShort();
// returns a uniformly distributed unsigned short.
double nextUniformDouble();
// returns a uniformly distributed double in the range [0, 1).
double nextUniformDouble(double low, double high);
// returns a uniformly distributed double in the range [low, high).
bool flipCoin();
private:
void initDrand(uint32_t seed, uint16_t xsubi0);
uint16_t* m_pBuffer;
}; // Random
#if HAVE_PTHREAD_H
class SIDX_DLL LockGuard
{
public:
LockGuard(pthread_mutex_t* pLock);
~LockGuard();
private:
pthread_mutex_t* m_pLock;
}; // LockGuard
#endif
class SIDX_DLL BufferedFile
{
public:
BufferedFile(uint32_t u32BufferSize = 16384);
virtual ~BufferedFile();
virtual void close();
virtual bool eof();
virtual void rewind() = 0;
virtual void seek(std::fstream::off_type offset) = 0;
protected:
std::fstream m_file;
char* m_buffer;
uint32_t m_u32BufferSize;
bool m_bEOF;
};
class SIDX_DLL BufferedFileReader : public BufferedFile
{
public:
BufferedFileReader();
BufferedFileReader(const std::string& sFileName, uint32_t u32BufferSize = 32768);
virtual ~BufferedFileReader();
virtual void open(const std::string& sFileName);
virtual void rewind();
virtual void seek(std::fstream::off_type offset);
virtual uint8_t readUInt8();
virtual uint16_t readUInt16();
virtual uint32_t readUInt32();
virtual uint64_t readUInt64();
virtual float readFloat();
virtual double readDouble();
virtual bool readBoolean();
virtual std::string readString();
virtual void readBytes(uint32_t u32Len, byte** pData);
};
class SIDX_DLL BufferedFileWriter : public BufferedFile
{
public:
BufferedFileWriter();
BufferedFileWriter(const std::string& sFileName, FileMode mode = CREATE, uint32_t u32BufferSize = 32768);
virtual ~BufferedFileWriter();
virtual void open(const std::string& sFileName, FileMode mode = CREATE);
virtual void rewind();
virtual void seek(std::fstream::off_type offset);
virtual void write(uint8_t i);
virtual void write(uint16_t i);
virtual void write(uint32_t i);
virtual void write(uint64_t i);
virtual void write(float i);
virtual void write(double i);
virtual void write(bool b);
virtual void write(const std::string& s);
virtual void write(uint32_t u32Len, byte* pData);
};
class SIDX_DLL TemporaryFile
{
public:
TemporaryFile();
virtual ~TemporaryFile();
void rewindForReading();
void rewindForWriting();
bool eof();
std::string getFileName() const;
uint8_t readUInt8();
uint16_t readUInt16();
uint32_t readUInt32();
uint64_t readUInt64();
float readFloat();
double readDouble();
std::string readString();
void readBytes(uint32_t u32Len, byte** pData);
void write(uint8_t i);
void write(uint16_t i);
void write(uint32_t i);
void write(uint64_t i);
void write(float i);
void write(double i);
void write(const std::string& s);
void write(uint32_t u32Len, byte* pData);
private:
std::string m_sFile;
BufferedFile* m_pFile;
};
}

View File

@@ -0,0 +1,85 @@
/******************************************************************************
* Project: libspatialindex - A C++ library for spatial indexing
* Author: Howard Butler, hobu.inc@gmail.com
******************************************************************************
* Copyright (c) 2011, Howard Butler
*
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
******************************************************************************/
#pragma once
/* Only define this stuff if we're not ANDROID */
#ifndef ANDROID
#ifndef HAVE_SRAND48
#if HAVE_FEATURES_H
#include <features.h>
#ifndef __THROW
/* copy-pasted from sys/cdefs.h */
/* GCC can always grok prototypes. For C++ programs we add throw()
to help it optimize the function calls. But this works only with
gcc 2.8.x and egcs. For gcc 3.2 and up we even mark C functions
as non-throwing using a function attribute since programs can use
the -fexceptions options for C code as well. */
# if !defined __cplusplus && __GNUC_PREREQ (3, 3)
# define __THROW __attribute__ ((__nothrow__))
# define __NTH(fct) __attribute__ ((__nothrow__)) fct
# else
# if defined __cplusplus && __GNUC_PREREQ (2,8)
# define __THROW throw ()
# define __NTH(fct) fct throw ()
# else
# define __THROW
# define __NTH(fct) fct
# endif
# endif
#endif
#else
# define __THROW
# define __NTH(fct) fct
#endif
extern void srand48(long int seed) __THROW;
extern unsigned short *seed48(unsigned short xseed[3]) __THROW;
extern long nrand48(unsigned short xseed[3]) __THROW;
extern long mrand48(void) __THROW;
extern long lrand48(void) __THROW;
extern void lcong48(unsigned short p[7]) __THROW;
extern long jrand48(unsigned short xseed[3]) __THROW;
extern double erand48(unsigned short xseed[3]) __THROW;
extern double drand48(void) __THROW;
#endif
/* Only define this stuff if we're not ANDROID */
#endif