removed Var iterators, fixed SOO alignment

- removed unnecessary using directives in Data library
- removed iterator pointers from Var (reduce size, always return copy)
- added Alignment header (adapted from LLVM infrastructure)
- added alignment guards to SOO implementations
This commit is contained in:
Aleksandar Fabijanic 2013-05-29 23:36:28 -05:00
parent 51fdec593e
commit e5eaffb790
19 changed files with 502 additions and 140 deletions

View File

@ -68,6 +68,8 @@ Release 1.5.2 (2013-06-xx)
- added JSON conversion to Dynamic Struct and Array - added JSON conversion to Dynamic Struct and Array
- added VarIterator - added VarIterator
- modified behavior of empty Var (empty == empty) - modified behavior of empty Var (empty == empty)
- added Alignment.h header for C++03 alignment needs
Release 1.5.1 (2013-01-11) Release 1.5.1 (2013-01-11)
========================== ==========================

View File

@ -222,7 +222,6 @@ inline void swap(LOB<T>& b1, LOB<T>& b2)
namespace std namespace std
{ {
using std::swap;
template<> template<>
inline void swap<Poco::Data::BLOB>(Poco::Data::BLOB& b1, inline void swap<Poco::Data::BLOB>(Poco::Data::BLOB& b1,
Poco::Data::BLOB& b2) Poco::Data::BLOB& b2)

View File

@ -159,7 +159,6 @@ inline bool RowIterator::operator != (const RowIterator& other) const
namespace std namespace std
{ {
using std::swap;
template<> template<>
inline void swap<Poco::Data::RowIterator>(Poco::Data::RowIterator& s1, inline void swap<Poco::Data::RowIterator>(Poco::Data::RowIterator& s1,
Poco::Data::RowIterator& s2) Poco::Data::RowIterator& s2)

View File

@ -503,7 +503,6 @@ inline void swap(Session& s1, Session& s2)
namespace std namespace std
{ {
using std::swap;
template<> template<>
inline void swap<Poco::Data::Session>(Poco::Data::Session& s1, inline void swap<Poco::Data::Session>(Poco::Data::Session& s1,
Poco::Data::Session& s2) Poco::Data::Session& s2)

View File

@ -820,7 +820,6 @@ inline void swap(Statement& s1, Statement& s2)
namespace std namespace std
{ {
using std::swap;
template<> template<>
inline void swap<Poco::Data::Statement>(Poco::Data::Statement& s1, inline void swap<Poco::Data::Statement>(Poco::Data::Statement& s1,
Poco::Data::Statement& s2) Poco::Data::Statement& s2)

View File

@ -983,6 +983,7 @@
<ClCompile Include="src\HashStatistic.cpp" /> <ClCompile Include="src\HashStatistic.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="include\Poco\Alignment.h" />
<ClInclude Include="include\Poco\Any.h" /> <ClInclude Include="include\Poco\Any.h" />
<ClInclude Include="include\Poco\Array.h" /> <ClInclude Include="include\Poco\Array.h" />
<ClInclude Include="include\Poco\Ascii.h" /> <ClInclude Include="include\Poco\Ascii.h" />

View File

@ -1883,6 +1883,9 @@
<ClInclude Include="include\Poco\Optional.h"> <ClInclude Include="include\Poco\Optional.h">
<Filter>Core\Header Files</Filter> <Filter>Core\Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="include\Poco\Alignment.h">
<Filter>Core\Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="src\pocomsg.rc"> <ResourceCompile Include="src\pocomsg.rc">

View File

@ -0,0 +1,230 @@
//
// Alignment.h
//
// $Id: //poco/svn/Foundation/include/Poco/Alignment.h#2 $
//
// Library: Foundation
// Package: Dynamic
// Module: Alignment
//
// Definition of the Alignment class.
//
// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// Permission is hereby granted, free of charge, to any person or organization
// obtaining a copy of the software and accompanying documentation covered by
// this license (the "Software") to use, reproduce, display, distribute,
// execute, and transmit the Software, and to prepare derivative works of the
// Software, and to permit third-parties to whom the Software is furnished to
// do so, all subject to the following:
//
// The copyright notices in the Software and this entire statement, including
// the above license grant, this restriction and the following disclaimer,
// must be included in all copies of the Software, in whole or in part, and
// all derivative works of the Software, unless such copies or derivative
// works are solely in the form of machine-executable object code generated by
// a source language processor.
//
// 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Adapted for POCO from LLVM Compiler Infrastructure code:
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source License
//
//===----------------------------------------------------------------------===//
//
// This file defines the AlignOf function that computes alignments for
// arbitrary types.
//
//===----------------------------------------------------------------------===//
#ifndef Foundation_AlignOf_INCLUDED
#define Foundation_AlignOf_INCLUDED
namespace Poco {
template <typename T>
struct AlignmentCalcImpl
{
char x;
T t;
private:
AlignmentCalcImpl() {} // Never instantiate.
};
template <typename T>
struct AlignOf
/// A templated class that contains an enum value representing
/// the alignment of the template argument. For example,
/// AlignOf<int>::Alignment represents the alignment of type "int". The
/// alignment calculated is the minimum alignment, and not necessarily
/// the "desired" alignment returned by GCC's __alignof__ (for example). Note
/// that because the alignment is an enum value, it can be used as a
/// compile-time constant (e.g., for template instantiation).
{
enum
{
Alignment = static_cast<unsigned int>(sizeof(AlignmentCalcImpl<T>) - sizeof(T))
};
enum { Alignment_GreaterEqual_2Bytes = Alignment >= 2 ? 1 : 0 };
enum { Alignment_GreaterEqual_4Bytes = Alignment >= 4 ? 1 : 0 };
enum { Alignment_GreaterEqual_8Bytes = Alignment >= 8 ? 1 : 0 };
enum { Alignment_GreaterEqual_16Bytes = Alignment >= 16 ? 1 : 0 };
enum { Alignment_LessEqual_2Bytes = Alignment <= 2 ? 1 : 0 };
enum { Alignment_LessEqual_4Bytes = Alignment <= 4 ? 1 : 0 };
enum { Alignment_LessEqual_8Bytes = Alignment <= 8 ? 1 : 0 };
enum { Alignment_LessEqual_16Bytes = Alignment <= 16 ? 1 : 0 };
};
template <typename T>
inline unsigned alignOf()
/// A templated function that returns the minimum alignment of
/// of a type. This provides no extra functionality beyond the AlignOf
/// class besides some cosmetic cleanliness. Example usage:
/// alignOf<int>() returns the alignment of an int.
{
return AlignOf<T>::Alignment;
}
template <size_t Alignment> struct AlignedCharArrayImpl;
/// Helper for building an aligned character array type.
///
/// This template is used to explicitly build up a collection of aligned
/// character types. We have to build these up using a macro and explicit
/// specialization to cope with old versions of MSVC and GCC where only an
/// integer literal can be used to specify an alignment constraint. Once built
/// up here, we can then begin to indirect between these using normal C++
/// template parameters.
// MSVC requires special handling here.
#ifndef _MSC_VER
#if __has_feature(cxx_alignas)
#define POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
template <> struct AlignedCharArrayImpl<x> \
{ \
char alignas(x) aligned; \
}
#elif defined(__GNUC__) || defined(__IBM_ATTRIBUTES)
#define POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
template <> struct AlignedCharArrayImpl<x> \
{ \
char aligned __attribute__((aligned(x))); \
}
#else
# error No supported align as directive.
#endif
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(512);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1024);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2048);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4096);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192);
#undef POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
#else // _MSC_VER
// We provide special variations of this template for the most common
// alignments because __declspec(align(...)) doesn't actually work when it is
// a member of a by-value function argument in MSVC, even if the alignment
// request is something reasonably like 8-byte or 16-byte.
template <> struct AlignedCharArrayImpl<1> { char aligned; };
template <> struct AlignedCharArrayImpl<2> { short aligned; };
template <> struct AlignedCharArrayImpl<4> { int aligned; };
template <> struct AlignedCharArrayImpl<8> { double aligned; };
#define POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \
template <> struct AlignedCharArrayImpl<x> { \
__declspec(align(x)) char aligned; \
}
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(512);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1024);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2048);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4096);
POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192);
// Any larger and MSVC complains.
#undef POCO_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT
#endif // _MSC_VER
template <typename T1, typename T2 = char, typename T3 = char, typename T4 = char>
union AlignedCharArrayUnion
/// This union template exposes a suitably aligned and sized character
/// array member which can hold elements of any of up to four types.
///
/// These types may be arrays, structs, or any other types. The goal is to
/// produce a union type containing a character array which, when used, forms
/// storage suitable to placement new any of these types over. Support for more
/// than four types can be added at the cost of more boiler plate.
{
private:
class AlignerImpl
{
T1 t1;
T2 t2;
T3 t3;
T4 t4;
AlignerImpl(); // Never defined or instantiated.
};
union SizerImpl
{
char arr1[sizeof(T1)];
char arr2[sizeof(T2)];
char arr3[sizeof(T3)];
char arr4[sizeof(T4)];
};
public:
char buffer[sizeof(SizerImpl)];
/// The character array buffer for use by clients.
///
/// No other member of this union should be referenced. They exist purely to
/// constrain the layout of this character array.
private:
Poco::AlignedCharArrayImpl<AlignOf<AlignerImpl>::Alignment> _nonceMember;
};
} // namespace Poco
#endif // Foundation_AlignOf_INCLUDED

View File

@ -40,10 +40,13 @@
#include "Poco/Exception.h" #include "Poco/Exception.h"
#include "Poco/MetaProgramming.h" #include "Poco/MetaProgramming.h"
#include "Poco/Alignment.h"
#include <algorithm> #include <algorithm>
#include <typeinfo> #include <typeinfo>
#include <cstring> #include <cstring>
#ifdef POCO_ENABLE_CPP11
#include <type_traits>
#endif
namespace Poco { namespace Poco {
@ -64,7 +67,7 @@ template <class> class VarHolderImpl;
template <typename PlaceholderT, unsigned int SizeV = POCO_SMALL_OBJECT_SIZE> template <typename PlaceholderT, unsigned int SizeV = POCO_SMALL_OBJECT_SIZE>
union Placeholder union Placeholder
/// ValueHolder union (used by Poco::Any and Poco::Dynamic::Var for small /// ValueHolder union (used by Poco::Any and Poco::Dynamic::Var for small
/// object optimization). /// object optimization, when enabled).
/// ///
/// If Holder<Type> fits into POCO_SMALL_OBJECT_SIZE bytes of storage, /// If Holder<Type> fits into POCO_SMALL_OBJECT_SIZE bytes of storage,
/// it will be placement-new-allocated into the local buffer /// it will be placement-new-allocated into the local buffer
@ -86,23 +89,23 @@ public:
void erase() void erase()
{ {
std::memset(holder, 0, sizeof(Placeholder)); std::memset(holder.h, 0, sizeof(Placeholder));
} }
bool isLocal() const bool isLocal() const
{ {
return holder[SizeV] != 0; return holder.h[SizeV] != 0;
} }
void setLocal(bool local) const void setLocal(bool local) const
{ {
holder[SizeV] = local ? 1 : 0; holder.h[SizeV] = local ? 1 : 0;
} }
PlaceholderT* content() const PlaceholderT* content() const
{ {
if(isLocal()) if(isLocal())
return reinterpret_cast<PlaceholderT*>(holder); return reinterpret_cast<PlaceholderT*>(holder.h);
else else
return pHolder; return pHolder;
} }
@ -112,9 +115,16 @@ public:
private: private:
#endif #endif
PlaceholderT* pHolder; PlaceholderT* pHolder;
#ifndef POCO_NO_SOO #ifndef POCO_NO_SOO
mutable unsigned char holder[SizeV + 1]; #ifndef POCO_ENABLE_CPP11
#error "Any SOO can only be enabled with C++11 support"
#endif
mutable union
{
std::aligned_storage<SizeV + 1> a;
unsigned char h[SizeV + 1];
} holder;
#endif #endif
friend class Any; friend class Any;
@ -130,7 +140,7 @@ private:
template <typename PlaceholderT> template <typename PlaceholderT>
union Placeholder union Placeholder
/// ValueHolder union (used by Poco::Any and Poco::Dynamic::Var for small /// ValueHolder union (used by Poco::Any and Poco::Dynamic::Var for small
/// object optimization). /// object optimization, when enabled).
/// ///
/// If Holder<Type> fits into POCO_SMALL_OBJECT_SIZE bytes of storage, /// If Holder<Type> fits into POCO_SMALL_OBJECT_SIZE bytes of storage,
/// it will be placement-new-allocated into the local buffer /// it will be placement-new-allocated into the local buffer
@ -275,7 +285,7 @@ public:
/// Returns true if the Any is empty. /// Returns true if the Any is empty.
{ {
char buf[POCO_SMALL_OBJECT_SIZE] = { 0 }; char buf[POCO_SMALL_OBJECT_SIZE] = { 0 };
return 0 == std::memcmp(_valueHolder.holder, buf, POCO_SMALL_OBJECT_SIZE); return 0 == std::memcmp(_valueHolder.holder.h, buf, POCO_SMALL_OBJECT_SIZE);
} }
const std::type_info & type() const const std::type_info & type() const
@ -318,7 +328,7 @@ private:
{ {
if ((sizeof(Holder<ValueType>) <= POCO_SMALL_OBJECT_SIZE)) if ((sizeof(Holder<ValueType>) <= POCO_SMALL_OBJECT_SIZE))
{ {
new ((ValueHolder*) pPlaceholder->holder) Holder(_held); new ((ValueHolder*) pPlaceholder->holder.h) Holder(_held);
pPlaceholder->setLocal(true); pPlaceholder->setLocal(true);
} }
else else
@ -344,7 +354,7 @@ private:
{ {
if (sizeof(Holder<ValueType>) <= Placeholder<ValueType>::Size::value) if (sizeof(Holder<ValueType>) <= Placeholder<ValueType>::Size::value)
{ {
new (reinterpret_cast<ValueHolder*>(_valueHolder.holder)) Holder<ValueType>(value); new (reinterpret_cast<ValueHolder*>(_valueHolder.holder.h)) Holder<ValueType>(value);
_valueHolder.setLocal(true); _valueHolder.setLocal(true);
} }
else else

View File

@ -45,7 +45,7 @@
// Define to enable C++11 support // Define to enable C++11 support
// #define POCO_ENABLE_CPP11 // #define POCO_ENABLE_CPP11
// Define to disable implicit linking // Define to disable implicit linking
@ -100,11 +100,17 @@
// candidates) will be auto-allocated on the stack in // candidates) will be auto-allocated on the stack in
// cases when value holder fits into POCO_SMALL_OBJECT_SIZE // cases when value holder fits into POCO_SMALL_OBJECT_SIZE
// (see below). // (see below).
//
// !!! NOTE: Any/Dynamic::Var SOO may NOT work reliably
// !!! without C++11 (std::aligned_storage in particular)
//
#define POCO_NO_SOO #define POCO_NO_SOO
// Small object size in bytes. When assigned to Any or Var, // Small object size in bytes. When assigned to Any or Var,
// objects longer than this value will be alocated on the heap. // objects larger than this value will be alocated on the heap,
// while those smaller will be placement new-ed into an
// internal buffer.
#if !defined(POCO_SMALL_OBJECT_SIZE) && !defined(POCO_NO_SOO) #if !defined(POCO_SMALL_OBJECT_SIZE) && !defined(POCO_NO_SOO)
#define POCO_SMALL_OBJECT_SIZE 32 #define POCO_SMALL_OBJECT_SIZE 32
#endif #endif

View File

@ -110,14 +110,10 @@ public:
Var(const T& val) Var(const T& val)
/// Creates the Var from the given value. /// Creates the Var from the given value.
#ifdef POCO_NO_SOO #ifdef POCO_NO_SOO
: _pHolder(new VarHolderImpl<T>(val)), : _pHolder(new VarHolderImpl<T>(val))
_pBegin(new Iterator(this, false)),
_pEnd(new Iterator(this, true))
{ {
} }
#else #else
: _pBegin(new Iterator(this, false)),
_pEnd(new Iterator(this, true))
{ {
construct(val); construct(val);
} }
@ -135,10 +131,10 @@ public:
void swap(Var& other); void swap(Var& other);
/// Swaps the content of the this Var with the other Var. /// Swaps the content of the this Var with the other Var.
ConstIterator& begin() const; ConstIterator begin() const;
/// Returns the const Var iterator. /// Returns the const Var iterator.
ConstIterator& end() const; ConstIterator end() const;
/// Returns the const Var iterator. /// Returns the const Var iterator.
Iterator begin(); Iterator begin();
@ -629,7 +625,7 @@ private:
{ {
if (sizeof(VarHolderImpl<ValueType>) <= Placeholder<ValueType>::Size::value) if (sizeof(VarHolderImpl<ValueType>) <= Placeholder<ValueType>::Size::value)
{ {
new (reinterpret_cast<VarHolder*>(_placeholder.holder)) VarHolderImpl<ValueType>(value); new (reinterpret_cast<VarHolder*>(_placeholder.holder.h)) VarHolderImpl<ValueType>(value);
_placeholder.setLocal(true); _placeholder.setLocal(true);
} }
else else
@ -644,7 +640,7 @@ private:
std::string val(value); std::string val(value);
if (sizeof(VarHolderImpl<std::string>) <= Placeholder<std::string>::Size::value) if (sizeof(VarHolderImpl<std::string>) <= Placeholder<std::string>::Size::value)
{ {
new (reinterpret_cast<VarHolder*>(_placeholder.holder)) VarHolderImpl<std::string>(val); new (reinterpret_cast<VarHolder*>(_placeholder.holder.h)) VarHolderImpl<std::string>(val);
_placeholder.setLocal(true); _placeholder.setLocal(true);
} }
else else
@ -676,9 +672,6 @@ private:
Placeholder<VarHolder> _placeholder; Placeholder<VarHolder> _placeholder;
#endif // POCO_NO_SOO #endif // POCO_NO_SOO
Iterator* _pBegin;
Iterator* _pEnd;
}; };
@ -732,30 +725,28 @@ inline const std::type_info& Var::type() const
} }
inline Var::ConstIterator& Var::begin() const inline Var::ConstIterator Var::begin() const
{ {
if (isEmpty()) _pBegin->setPosition(Iterator::POSITION_END); if (isEmpty()) return ConstIterator(const_cast<Var*>(this), true);
else if (*_pBegin == *_pEnd) _pBegin->setPosition(0);
return *_pBegin; return ConstIterator(const_cast<Var*>(this), false);
} }
inline Var::ConstIterator& Var::end() const inline Var::ConstIterator Var::end() const
{ {
return *_pEnd; return ConstIterator(const_cast<Var*>(this), true);
} }
inline Var::Iterator Var::begin() inline Var::Iterator Var::begin()
{ {
if (isEmpty()) _pBegin->setPosition(Iterator::POSITION_END); if (isEmpty()) return Iterator(const_cast<Var*>(this), true);
else if (*_pBegin == *_pEnd) _pBegin->setPosition(0);
return *_pBegin; return Iterator(const_cast<Var*>(this), false);
} }
inline Var::Iterator Var::end() inline Var::Iterator Var::end()
{ {
return *_pEnd; return Iterator(this, true);
} }

View File

@ -286,9 +286,9 @@ protected:
poco_check_ptr (pVarHolder); poco_check_ptr (pVarHolder);
if ((sizeof(VarHolderImpl<T>) <= Placeholder<T>::Size::value)) if ((sizeof(VarHolderImpl<T>) <= Placeholder<T>::Size::value))
{ {
new ((VarHolder*) pVarHolder->holder) VarHolderImpl<T>(val); new ((VarHolder*) pVarHolder->holder.h) VarHolderImpl<T>(val);
pVarHolder->setLocal(true); pVarHolder->setLocal(true);
return (VarHolder*) pVarHolder->holder; return (VarHolder*) pVarHolder->holder.h;
} }
else else
{ {

View File

@ -47,26 +47,20 @@ namespace Poco {
namespace Dynamic { namespace Dynamic {
Var::Var() : Var::Var()
#ifdef POCO_NO_SOO #ifdef POCO_NO_SOO
_pHolder(0), : _pHolder(0)
#endif #endif
_pBegin(new Iterator(this, true)),
_pEnd(new Iterator(this, true))
{ {
} }
Var::Var(const char* pVal) Var::Var(const char* pVal)
#ifdef POCO_NO_SOO #ifdef POCO_NO_SOO
: _pHolder(new VarHolderImpl<std::string>(pVal)), : _pHolder(new VarHolderImpl<std::string>(pVal))
_pBegin(new Iterator(this, false)),
_pEnd(new Iterator(this, true))
{ {
} }
#else #else
: _pBegin(new Iterator(this, false)),
_pEnd(new Iterator(this, true))
{ {
construct(std::string(pVal)); construct(std::string(pVal));
} }
@ -75,14 +69,10 @@ Var::Var(const char* pVal)
Var::Var(const Var& other) Var::Var(const Var& other)
#ifdef POCO_NO_SOO #ifdef POCO_NO_SOO
: _pHolder(other._pHolder ? other._pHolder->clone() : 0), : _pHolder(other._pHolder ? other._pHolder->clone() : 0)
_pBegin(new Iterator(*other._pBegin)),
_pEnd(new Iterator(*other._pEnd))
{ {
} }
#else #else
: _pBegin(new Iterator(*other._pBegin)),
_pEnd(new Iterator(*other._pEnd))
{ {
if ((this != &other) && !other.isEmpty()) if ((this != &other) && !other.isEmpty())
construct(other); construct(other);

View File

@ -44,6 +44,11 @@
#include "Poco/Net/SocketDefs.h" #include "Poco/Net/SocketDefs.h"
#include "Poco/Net/IPAddressImpl.h" #include "Poco/Net/IPAddressImpl.h"
#include <vector> #include <vector>
#ifdef POCO_ENABLE_CPP11
#include <type_traits>
#else
#include "Poco/Alignment.h"
#endif
namespace Poco { namespace Poco {
@ -387,9 +392,23 @@ private:
typedef Impl* Ptr; typedef Impl* Ptr;
Ptr pImpl() const; Ptr pImpl() const;
void destruct(); void destruct();
char _memory[sizeof(Poco::Net::Impl::IPv6AddressImpl)]; char* storage();
#ifdef POCO_ENABLE_CPP11
static const unsigned sz = sizeof(Poco::Net::Impl::IPv6AddressImpl);
union
{
std::aligned_storage<sz> a;
char buffer[sz];
}
#else // !POCO_ENABLE_CPP11
AlignedCharArrayUnion <Poco::Net::Impl::IPv6AddressImpl,
Poco::Net::Impl::IPv4AddressImpl>
#endif // POCO_ENABLE_CPP11
_memory;
}; };
@ -401,7 +420,13 @@ inline void IPAddress::destruct()
inline IPAddress::Ptr IPAddress::pImpl() const inline IPAddress::Ptr IPAddress::pImpl() const
{ {
return reinterpret_cast<Ptr>(const_cast<char *>(_memory)); return reinterpret_cast<Ptr>(const_cast<char *>(_memory.buffer));
}
inline char* IPAddress::storage()
{
return _memory.buffer;
} }

View File

@ -153,9 +153,23 @@ private:
typedef Impl* Ptr; typedef Impl* Ptr;
Ptr pImpl() const; Ptr pImpl() const;
void destruct(); void destruct();
char _memory[sizeof(Poco::Net::Impl::IPv6SocketAddressImpl)]; char* storage();
#ifdef POCO_ENABLE_CPP11
static const unsigned sz = sizeof(Poco::Net::Impl::IPv6SocketAddressImpl);
union
{
std::aligned_storage<sz> a;
char buffer[sz];
}
#else // !POCO_ENABLE_CPP11
AlignedCharArrayUnion <Poco::Net::Impl::IPv6SocketAddressImpl,
Poco::Net::Impl::IPv4SocketAddressImpl>
#endif // POCO_ENABLE_CPP11
_memory;
}; };
@ -172,7 +186,13 @@ inline void SocketAddress::destruct()
inline SocketAddress::Ptr SocketAddress::pImpl() const inline SocketAddress::Ptr SocketAddress::pImpl() const
{ {
return reinterpret_cast<Ptr>(const_cast<char *>(_memory)); return reinterpret_cast<Ptr>(const_cast<char *>(_memory.buffer));
}
inline char* SocketAddress::storage()
{
return _memory.buffer;
} }

View File

@ -64,26 +64,26 @@ namespace Net {
IPAddress::IPAddress() IPAddress::IPAddress()
{ {
new (_memory) IPv4AddressImpl(); new (storage()) IPv4AddressImpl();
} }
IPAddress::IPAddress(const IPAddress& addr) IPAddress::IPAddress(const IPAddress& addr)
{ {
if (addr.family() == IPv4) if (addr.family() == IPv4)
new (_memory) IPv4AddressImpl(addr.addr()); new (storage()) IPv4AddressImpl(addr.addr());
else else
new (_memory) IPv6AddressImpl(addr.addr()); new (storage()) IPv6AddressImpl(addr.addr());
} }
IPAddress::IPAddress(Family family) IPAddress::IPAddress(Family family)
{ {
if (family == IPv4) if (family == IPv4)
new (_memory) IPv4AddressImpl(); new (storage()) IPv4AddressImpl();
#if defined(POCO_HAVE_IPv6) #if defined(POCO_HAVE_IPv6)
else if (family == IPv6) else if (family == IPv6)
new (_memory) IPv6AddressImpl(); new (storage()) IPv6AddressImpl();
#endif #endif
else else
throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()"); throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()");
@ -95,14 +95,14 @@ IPAddress::IPAddress(const std::string& addr)
IPv4AddressImpl empty4 = IPv4AddressImpl(); IPv4AddressImpl empty4 = IPv4AddressImpl();
if (addr.empty() || trim(addr) == "0.0.0.0") if (addr.empty() || trim(addr) == "0.0.0.0")
{ {
new (_memory) IPv4AddressImpl(empty4.addr()); new (storage()) IPv4AddressImpl(empty4.addr());
return; return;
} }
IPv4AddressImpl addr4(IPv4AddressImpl::parse(addr)); IPv4AddressImpl addr4(IPv4AddressImpl::parse(addr));
if (addr4 != empty4) if (addr4 != empty4)
{ {
new (_memory) IPv4AddressImpl(addr4.addr()); new (storage()) IPv4AddressImpl(addr4.addr());
return; return;
} }
@ -110,14 +110,14 @@ IPAddress::IPAddress(const std::string& addr)
IPv6AddressImpl empty6 = IPv6AddressImpl(); IPv6AddressImpl empty6 = IPv6AddressImpl();
if (addr.empty() || trim(addr) == "::") if (addr.empty() || trim(addr) == "::")
{ {
new (_memory) IPv6AddressImpl(empty6.addr()); new (storage()) IPv6AddressImpl(empty6.addr());
return; return;
} }
IPv6AddressImpl addr6(IPv6AddressImpl::parse(addr)); IPv6AddressImpl addr6(IPv6AddressImpl::parse(addr));
if (addr6 != IPv6AddressImpl()) if (addr6 != IPv6AddressImpl())
{ {
new (_memory) IPv6AddressImpl(addr6.addr()); new (storage()) IPv6AddressImpl(addr6.addr());
return; return;
} }
#endif #endif
@ -131,14 +131,14 @@ IPAddress::IPAddress(const std::string& addr, Family family)
if (family == IPv4) if (family == IPv4)
{ {
IPv4AddressImpl addr4(IPv4AddressImpl::parse(addr)); IPv4AddressImpl addr4(IPv4AddressImpl::parse(addr));
new (_memory) IPv4AddressImpl(addr4.addr()); new (storage()) IPv4AddressImpl(addr4.addr());
return; return;
} }
#if defined(POCO_HAVE_IPv6) #if defined(POCO_HAVE_IPv6)
else if (family == IPv6) else if (family == IPv6)
{ {
IPv6AddressImpl addr6(IPv6AddressImpl::parse(addr)); IPv6AddressImpl addr6(IPv6AddressImpl::parse(addr));
new (_memory) IPv6AddressImpl(addr6.addr()); new (storage()) IPv6AddressImpl(addr6.addr());
return; return;
} }
#endif #endif
@ -149,10 +149,10 @@ IPAddress::IPAddress(const std::string& addr, Family family)
IPAddress::IPAddress(const void* addr, poco_socklen_t length) IPAddress::IPAddress(const void* addr, poco_socklen_t length)
{ {
if (length == sizeof(struct in_addr)) if (length == sizeof(struct in_addr))
new (_memory) IPv4AddressImpl(addr); new (storage()) IPv4AddressImpl(addr);
#if defined(POCO_HAVE_IPv6) #if defined(POCO_HAVE_IPv6)
else if (length == sizeof(struct in6_addr)) else if (length == sizeof(struct in6_addr))
new (_memory) IPv6AddressImpl(addr); new (storage()) IPv6AddressImpl(addr);
#endif #endif
else throw Poco::InvalidArgumentException("Invalid address length passed to IPAddress()"); else throw Poco::InvalidArgumentException("Invalid address length passed to IPAddress()");
} }
@ -161,10 +161,10 @@ IPAddress::IPAddress(const void* addr, poco_socklen_t length)
IPAddress::IPAddress(const void* addr, poco_socklen_t length, Poco::UInt32 scope) IPAddress::IPAddress(const void* addr, poco_socklen_t length, Poco::UInt32 scope)
{ {
if (length == sizeof(struct in_addr)) if (length == sizeof(struct in_addr))
new (_memory) IPv4AddressImpl(addr); new (storage()) IPv4AddressImpl(addr);
#if defined(POCO_HAVE_IPv6) #if defined(POCO_HAVE_IPv6)
else if (length == sizeof(struct in6_addr)) else if (length == sizeof(struct in6_addr))
new (_memory) IPv6AddressImpl(addr, scope); new (storage()) IPv6AddressImpl(addr, scope);
#endif #endif
else throw Poco::InvalidArgumentException("Invalid address length passed to IPAddress()"); else throw Poco::InvalidArgumentException("Invalid address length passed to IPAddress()");
} }
@ -175,13 +175,13 @@ IPAddress::IPAddress(unsigned prefix, Family family)
if (family == IPv4) if (family == IPv4)
{ {
if (prefix <= 32) if (prefix <= 32)
new (_memory) IPv4AddressImpl(prefix); new (storage()) IPv4AddressImpl(prefix);
} }
#if defined(POCO_HAVE_IPv6) #if defined(POCO_HAVE_IPv6)
else if (family == IPv6) else if (family == IPv6)
{ {
if (prefix <= 128) if (prefix <= 128)
new (_memory) IPv6AddressImpl(prefix); new (storage()) IPv6AddressImpl(prefix);
} }
#endif #endif
else throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()"); else throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()");
@ -194,10 +194,10 @@ IPAddress::IPAddress(const SOCKET_ADDRESS& socket_address)
{ {
ADDRESS_FAMILY family = socket_address.lpSockaddr->sa_family; ADDRESS_FAMILY family = socket_address.lpSockaddr->sa_family;
if (family == AF_INET) if (family == AF_INET)
new (_memory) IPv4AddressImpl(&reinterpret_cast<const struct sockaddr_in*>(socket_address.lpSockaddr)->sin_addr); new (storage()) IPv4AddressImpl(&reinterpret_cast<const struct sockaddr_in*>(socket_address.lpSockaddr)->sin_addr);
#if defined(POCO_HAVE_IPv6) #if defined(POCO_HAVE_IPv6)
else if (family == AF_INET6) else if (family == AF_INET6)
new (_memory) IPv6AddressImpl(&reinterpret_cast<const struct sockaddr_in6*>(socket_address.lpSockaddr)->sin6_addr, new (storage()) IPv6AddressImpl(&reinterpret_cast<const struct sockaddr_in6*>(socket_address.lpSockaddr)->sin6_addr,
reinterpret_cast<const struct sockaddr_in6*>(socket_address.lpSockaddr)->sin6_scope_id); reinterpret_cast<const struct sockaddr_in6*>(socket_address.lpSockaddr)->sin6_scope_id);
#endif #endif
else throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()"); else throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()");
@ -209,10 +209,10 @@ IPAddress::IPAddress(const struct sockaddr& sockaddr)
{ {
unsigned short family = sockaddr.sa_family; unsigned short family = sockaddr.sa_family;
if (family == AF_INET) if (family == AF_INET)
new (_memory) IPv4AddressImpl(&reinterpret_cast<const struct sockaddr_in*>(&sockaddr)->sin_addr); new (storage()) IPv4AddressImpl(&reinterpret_cast<const struct sockaddr_in*>(&sockaddr)->sin_addr);
#if defined(POCO_HAVE_IPv6) #if defined(POCO_HAVE_IPv6)
else if (family == AF_INET6) else if (family == AF_INET6)
new (_memory) IPv6AddressImpl(&reinterpret_cast<const struct sockaddr_in6*>(&sockaddr)->sin6_addr, new (storage()) IPv6AddressImpl(&reinterpret_cast<const struct sockaddr_in6*>(&sockaddr)->sin6_addr,
reinterpret_cast<const struct sockaddr_in6*>(&sockaddr)->sin6_scope_id); reinterpret_cast<const struct sockaddr_in6*>(&sockaddr)->sin6_scope_id);
#endif #endif
else throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()"); else throw Poco::InvalidArgumentException("Invalid or unsupported address family passed to IPAddress()");
@ -231,9 +231,9 @@ IPAddress& IPAddress::operator = (const IPAddress& addr)
{ {
destruct(); destruct();
if (addr.family() == IPAddress::IPv4) if (addr.family() == IPAddress::IPv4)
new (_memory) IPv4AddressImpl(addr.addr()); new (storage()) IPv4AddressImpl(addr.addr());
else else
new (_memory) IPv6AddressImpl(addr.addr()); new (storage()) IPv6AddressImpl(addr.addr());
} }
return *this; return *this;
} }
@ -546,14 +546,14 @@ bool IPAddress::tryParse(const std::string& addr, IPAddress& result)
if (impl4 != IPv4AddressImpl()) if (impl4 != IPv4AddressImpl())
{ {
new (result._memory) IPv4AddressImpl(impl4.addr()); new (result.storage()) IPv4AddressImpl(impl4.addr());
return true; return true;
} }
#if defined(POCO_HAVE_IPv6) #if defined(POCO_HAVE_IPv6)
IPv6AddressImpl impl6(IPv6AddressImpl::parse(addr)); IPv6AddressImpl impl6(IPv6AddressImpl::parse(addr));
if (impl6 != IPv6AddressImpl()) if (impl6 != IPv6AddressImpl())
{ {
new (result._memory) IPv6AddressImpl(impl6.addr()); new (result.storage()) IPv6AddressImpl(impl6.addr());
return true; return true;
} }
#endif #endif

View File

@ -75,7 +75,7 @@ struct AFLT
SocketAddress::SocketAddress() SocketAddress::SocketAddress()
{ {
new (_memory) IPv4SocketAddressImpl; new (storage()) IPv4SocketAddressImpl;
} }
@ -135,19 +135,19 @@ SocketAddress::SocketAddress(const std::string& hostAndPort)
SocketAddress::SocketAddress(const SocketAddress& socketAddress) SocketAddress::SocketAddress(const SocketAddress& socketAddress)
{ {
if (socketAddress.family() == IPAddress::IPv4) if (socketAddress.family() == IPAddress::IPv4)
new (_memory) IPv4SocketAddressImpl(reinterpret_cast<const sockaddr_in*>(socketAddress.addr())); new (storage()) IPv4SocketAddressImpl(reinterpret_cast<const sockaddr_in*>(socketAddress.addr()));
else else
new (_memory) IPv6SocketAddressImpl(reinterpret_cast<const sockaddr_in6*>(socketAddress.addr())); new (storage()) IPv6SocketAddressImpl(reinterpret_cast<const sockaddr_in6*>(socketAddress.addr()));
} }
SocketAddress::SocketAddress(const struct sockaddr* sockAddr, poco_socklen_t length) SocketAddress::SocketAddress(const struct sockaddr* sockAddr, poco_socklen_t length)
{ {
if (length == sizeof(struct sockaddr_in)) if (length == sizeof(struct sockaddr_in))
new (_memory) IPv4SocketAddressImpl(reinterpret_cast<const struct sockaddr_in*>(sockAddr)); new (storage()) IPv4SocketAddressImpl(reinterpret_cast<const struct sockaddr_in*>(sockAddr));
#if defined(POCO_HAVE_IPv6) #if defined(POCO_HAVE_IPv6)
else if (length == sizeof(struct sockaddr_in6)) else if (length == sizeof(struct sockaddr_in6))
new (_memory) IPv6SocketAddressImpl(reinterpret_cast<const struct sockaddr_in6*>(sockAddr)); new (storage()) IPv6SocketAddressImpl(reinterpret_cast<const struct sockaddr_in6*>(sockAddr));
#endif #endif
else throw Poco::InvalidArgumentException("Invalid address length passed to SocketAddress()"); else throw Poco::InvalidArgumentException("Invalid address length passed to SocketAddress()");
} }
@ -175,9 +175,9 @@ SocketAddress& SocketAddress::operator = (const SocketAddress& socketAddress)
{ {
destruct(); destruct();
if (socketAddress.family() == IPAddress::IPv4) if (socketAddress.family() == IPAddress::IPv4)
new (_memory) IPv4SocketAddressImpl(reinterpret_cast<const sockaddr_in*>(socketAddress.addr())); new (storage()) IPv4SocketAddressImpl(reinterpret_cast<const sockaddr_in*>(socketAddress.addr()));
else else
new (_memory) IPv6SocketAddressImpl(reinterpret_cast<const sockaddr_in6*>(socketAddress.addr())); new (storage()) IPv6SocketAddressImpl(reinterpret_cast<const sockaddr_in6*>(socketAddress.addr()));
} }
return *this; return *this;
} }
@ -232,10 +232,10 @@ std::string SocketAddress::toString() const
void SocketAddress::init(const IPAddress& hostAddress, Poco::UInt16 portNumber) void SocketAddress::init(const IPAddress& hostAddress, Poco::UInt16 portNumber)
{ {
if (hostAddress.family() == IPAddress::IPv4) if (hostAddress.family() == IPAddress::IPv4)
new (_memory) IPv4SocketAddressImpl(hostAddress.addr(), htons(portNumber)); new (storage()) IPv4SocketAddressImpl(hostAddress.addr(), htons(portNumber));
#if defined(POCO_HAVE_IPv6) #if defined(POCO_HAVE_IPv6)
else if (hostAddress.family() == IPAddress::IPv6) else if (hostAddress.family() == IPAddress::IPv6)
new (_memory) IPv6SocketAddressImpl(hostAddress.addr(), htons(portNumber), hostAddress.scope()); new (storage()) IPv6SocketAddressImpl(hostAddress.addr(), htons(portNumber), hostAddress.scope());
#endif #endif
else throw Poco::NotImplementedException("unsupported IP address family"); else throw Poco::NotImplementedException("unsupported IP address family");
} }

View File

@ -184,65 +184,110 @@ following copyrighted material, the use of which is hereby acknowledged.
!!!SQlite 3.7.14 !!!SQlite 3.7.14
The original author of SQLite has dedicated the code to the The original author of SQLite has dedicated the code to the
public domain (http://www.sqlite.org/copyright.html). public domain (http://www.sqlite.org/copyright.html).
Anyone is free to copy, modify, publish, use, compile, sell, or distribute the Anyone is free to copy, modify, publish, use, compile, sell, or distribute the
original SQLite code, either in source code form or as a compiled binary, original SQLite code, either in source code form or as a compiled binary,
for any purpose, commercial or non-commercial, and by any means. for any purpose, commercial or non-commercial, and by any means.
---- ----
!!!double-conversion !!!double-conversion
Copyright 2010 the V8 project authors. All rights reserved. Copyright 2010 the V8 project authors. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are modification, are permitted provided that the following conditions are
met: met:
* Redistributions of source code must retain the above copyright * Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above * Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided disclaimer in the documentation and/or other materials provided
with the distribution. with the distribution.
* Neither the name of Google Inc. nor the names of its * Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived contributors may be used to endorse or promote products derived
from this software without specific prior written permission. from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---- ----
!!!JSON_parser !!!JSON_parser
Copyright (c) 2005 JSON.org Copyright (c) 2005 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: 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 above copyright notice and this permission notice shall be included in all The Software shall be used for Good, not Evil.
copies or substantial portions of the Software.
The Software shall be used for Good, not Evil. 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.
----
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, !!!Code from the LLVM Compiler Infrastructure
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER University of Illinois/NCSA
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, Open Source License
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. Copyright (c) 2007-2012 University of Illinois at Urbana-Champaign.
All rights reserved.
Developed by:
LLVM Team
University of Illinois at Urbana-Champaign
http://llvm.org
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal with
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:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimers.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimers in the
documentation and/or other materials provided with the distribution.
* Neither the names of the LLVM Team, University of Illinois at
Urbana-Champaign, nor the names of its contributors may be used to
endorse or promote products derived from this Software without specific
prior written permission.
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
CONTRIBUTORS 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 WITH THE
SOFTWARE.

View File

@ -251,5 +251,48 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
</pre></p> </pre></p>
<h3>Code from the LLVM Compiler Infrastructure</h3>
<p><pre>University of Illinois/NCSA
Open Source License
Copyright (c) 2007-2012 University of Illinois at Urbana-Champaign.
All rights reserved.
Developed by:
LLVM Team
University of Illinois at Urbana-Champaign
http://llvm.org
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal with
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:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimers.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimers in the
documentation and/or other materials provided with the distribution.
* Neither the names of the LLVM Team, University of Illinois at
Urbana-Champaign, nor the names of its contributors may be used to
endorse or promote products derived from this Software without specific
prior written permission.
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
CONTRIBUTORS 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 WITH THE
SOFTWARE.
</pre></p>
</body> </body>
</html> </html>