text:
	#pragma once // Some compilers (e.g. VC++) benefit significantly from using this. We've measured 3-4% build speed improvements in apps as a result.
#endif

EA_DISABLE_VC_WARNING(4244) // warning C4244: 'conversion from '___' to '___', possible loss of data
EA_DISABLE_VC_WARNING(4623) // warning C4623: default constructor was implicitly defined as deleted
EA_DISABLE_VC_WARNING(4625) // warning C4625: copy constructor was implicitly defined as deleted
EA_DISABLE_VC_WARNING(4510) // warning C4510: default constructor could not be generated

namespace eastl
{
	/// EASTL_TUPLE_VECTOR_DEFAULT_NAME
	///
	/// Defines a default container name in the absence of a user-provided name.
	///
	#ifndef EASTL_TUPLE_VECTOR_DEFAULT_NAME
	#define EASTL_TUPLE_VECTOR_DEFAULT_NAME EASTL_DEFAULT_NAME_PREFIX " tuple-vector" // Unless the user overrides something, this is "EASTL tuple-vector".
	#endif

	/// EASTL_TUPLE_VECTOR_DEFAULT_ALLOCATOR
	///
	#ifndef EASTL_TUPLE_VECTOR_DEFAULT_ALLOCATOR
	#define EASTL_TUPLE_VECTOR_DEFAULT_ALLOCATOR allocator_type(EASTL_TUPLE_VECTOR_DEFAULT_NAME)
	#endif

namespace TupleVecInternal
{

// forward declarations
template <eastl_size_t I, typename... Ts>
struct tuplevec_element;

template <eastl_size_t I, typename... Ts>
using tuplevec_element_t = typename tuplevec_element<I, Ts...>::type;

template <typename... Ts>
struct TupleTypes {};

template <typename Allocator, typename Indices, typename... Ts>
class TupleVecImpl;

template <typename... Ts>
struct TupleRecurser;

template <eastl_size_t I, typename... Ts>
struct TupleIndexRecurser;

template <eastl_size_t I, typename T>
struct TupleVecLeaf;

template <typename Indices, typename... Ts>
struct TupleVecIter;

// tuplevec_element helper to be able to isolate a type given an index
template <eastl_size_t I>
struct tuplevec_element<I>
{
	static_assert(I != I, "tuplevec_element index out of range");
};

template <typename T, typename... Ts>
struct tuplevec_element<0, T, Ts...>
{
	tuplevec_element() = delete; // tuplevec_element should only be used for compile-time assistance, and never be instantiated
	typedef T type;
};

template <eastl_size_t I, typename T, typename... Ts>
struct tuplevec_element<I, T, Ts...>
{
	typedef tuplevec_element_t<I - 1, Ts...> type;
};

// attempt to isolate index given a type
template <typename T, typename TupleVector>
struct tuplevec_index
{
};

template <typename T>
struct tuplevec_index<T, TupleTypes<>>
{
	typedef void DuplicateTypeCheck;
	tuplevec_index() = delete; // tuplevec_index should only be used for compile-time assistance, and never be instantiated
	static const eastl_size_t index = 0;
};

template <typename T, typename... TsRest>
struct tuplevec_index<T, TupleTypes<T, TsRest...>>
{
	typedef int DuplicateTypeCheck;
	static_assert(is_void<typename tuplevec_index<T, TupleTypes<TsRest...>>::DuplicateTypeCheck>::value, "duplicate type T in tuple_vector::get<T>(); unique types must be provided in declaration, or only use get<eastl_size_t>()");

	static const eastl_size_t index = 0;
};

template <typename T, typename Ts, typename... TsRest>
struct tuplevec_index<T, TupleTypes<Ts, TsRest...>>
{
	typedef typename tuplevec_index<T, TupleTypes<TsRest...>>::DuplicateTypeCheck DuplicateTypeCheck;
	static const eastl_size_t index = tuplevec_index<T, TupleTypes<TsRest...>>::index + 1;
};

template <typename Allocator, typename T, typename Indices, typename... Ts>
struct tuplevec_index<T, TupleVecImpl<Allocator, Indices, Ts...>> : public tuplevec_index<T, TupleTypes<Ts...>>
{
};

// helper to calculate the layout of the allocations for the tuple of types (esp. to take alignment into account)
template <>
struct TupleRecurser<>
{
	typedef eastl_size_t size_type;

	// This class should never be instantiated. This is just a helper for working with static functions when anonymous functions don't work
	// and provide some other utilities
	TupleRecurser() = delete;

	static EA_CONSTEXPR size_type GetTotalAlignment()
	{
		return 0;
	}

	static EA_CONSTEXPR size_type GetTotalAllocationSize(size_type capacity, size_type offset)
	{
		EA_UNUSED(capacity);
		return offset;
	}

	template<typename Allocator, size_type I, typename Indices, typename... VecTypes>
	static pair<void*, size_type> DoAllocate(TupleVecImpl<Allocator, Indices, VecTypes...> &vec, void** ppNewLeaf, size_type capacity, size_type offset)
	{
		EA_UNUSED(ppNewLeaf);

		// If n is zero, then we allocate no memory and just return NULL.
		// This is fine, as our default ctor initializes with NULL pointers.
		size_type alignment = TupleRecurser<VecTypes...>::GetTotalAlignment();
		void* ptr = capacity ? allocate_memory(vec.get_allocator(), offset, alignment, 0) : nullptr;

	#if EASTL_ASSERT_ENABLED
		if (EASTL_UNLIKELY((size_t)ptr & (alignment - 1)) != 0)
		{
			EASTL_FAIL_MSG("tuple_vector::DoAllocate -- memory not alignment at requested alignment");
		}
	#endif

		return make_pair(ptr, offset);
	}

	template<typename TupleVecImplType, size_type I>
	static void SetNewData(TupleVecImplType &vec, void* pData, size_type capacity, size_type offset)
	{
		EA_UNUSED(vec);
		EA_UNUSED(pData);
		EA_UNUSED(capacity);
		EA_UNUSED(offset);
	}
};

template <typename T, typename... Ts>
struct TupleRecurser<T, Ts...> : TupleRecurser<Ts...>
{
	typedef eastl_size_t size_type;

	static EA_CONSTEXPR size_type GetTotalAlignment()
	{
		return max(static_cast<size_type>(alignof(T)), TupleRecurser<Ts...>::GetTotalAlignment());
	}

	static EA_CONSTEXPR size_type GetTotalAllocationSize(size_type capacity, size_type offset)
	{
		return TupleRecurser<Ts...>::GetTotalAllocationSize(capacity, CalculateAllocationSize(offset, capacity));
	}

	template<typename Allocator, size_type I, typename Indices, typename... VecTypes>
	static pair<void*, size_type> DoAllocate(TupleVecImpl<Allocator, Indices, VecTypes...> &vec, void** ppNewLeaf, size_type capacity, size_type offset)
	{
		size_type allocationOffset = CalculatAllocationOffset(offset);
		size_type allocationSize = CalculateAllocationSize(offset, capacity);
		pair<void*, size_type> allocation = TupleRecurser<Ts...>::template DoAllocate<Allocator, I + 1, Indices, VecTypes...>(
			vec, ppNewLeaf, capacity, allocationSize);
		ppNewLeaf[I] = (void*)((uintptr_t)(allocation.first) + allocationOffset);
		return allocation;
	}

	template<typename TupleVecImplType, size_type I>
	static void SetNewData(TupleVecImplType &vec, void* pData, size_type capacity, size_type offset)
	{
		size_type allocationOffset = CalculatAllocationOffset(offset);
		size_type allocationSize = CalculateAllocationSize(offset, capacity);
		vec.TupleVecLeaf<I, T>::mpData = (T*)((uintptr_t)pData + allocationOffset);
		TupleRecurser<Ts...>::template SetNewData<TupleVecImplType, I + 1>(vec, pData, capacity, allocationSize);
	}

private:
	static EA_CONSTEXPR size_type CalculateAllocationSize(size_type offset, size_type capacity)
	{
		return CalculatAllocationOffset(offset) + sizeof(T) * capacity;
	}

	static EA_CONSTEXPR size_type CalculatAllocationOffset(size_type offset) { return (offset + alignof(T) - 1) & (~alignof(T) + 1); }
};

template <eastl_size_t I, typename T>
struct TupleVecLeaf
{
	typedef eastl_size_t size_type;

	void DoUninitializedMoveAndDestruct(const size_type begin, const size_type end, T* pDest)
	{
		T* pBegin = mpData + begin;
		T* pEnd = mpData + end;
		eastl::uninitialized_move_ptr_if_noexcept(pBegin, pEnd, pDest);
		eastl::destruct(pBegin, pEnd);
	}

	void DoInsertAndFill(size_type pos, size_type n, size_type numElements, const T& arg)
	{
		T* pDest = mpData + pos;
		T* pDataEnd = mpData + numElements;
		const T temp = arg;
		const size_type nExtra = (numElements - pos);
		if (n < nExtra) // If the inserted values are entirely within initialized memory (i.e. are before mpEnd)...
		{
			eastl::uninitialized_move_ptr(pDataEnd - n, pDataEnd, pDataEnd);
			eastl::move_backward(pDest, pDataEnd - n, pDataEnd); // We need move_backward because of potential overlap issues.
			eastl::fill(pDest, pDest + n, temp);
		}
		else
		{
			eastl::uninitialized_fill_n_ptr(pDataEnd, n - nExtra, temp);
			eastl::uninitialized_move_ptr(pDest, pDataEnd, pDataEnd + n - nExtra);
			eastl::fill(pDest, pDataEnd, temp);
		}
	}

	void DoInsertRange(T* pSrcBegin, T* pSrcEnd, T* pDestBegin, size_type numDataElements)
	{
		size_type pos = pDestBegin - mpData;
		size_type n = pSrcEnd - pSrcBegin;
		T* pDataEnd = mpData + numDataElements;
		const size_type nExtra = numDataElements - pos;
		if (n < nExtra) // If the inserted values are entirely within initialized memory (i.e. are before mpEnd)...
		{
			eastl::uninitialized_move_ptr(pDataEnd - n, pDataEnd, pDataEnd);
			eastl::move_backward(pDestBegin, pDataEnd - n, pDataEnd); // We need move_backward because of potential overlap issues.
			eastl::copy(pSrcBegin, pSrcEnd, pDestBegin);
		}
		else
		{
			eastl::uninitialized_copy(pSrcEnd - (n - nExtra), pSrcEnd, pDataEnd);
			eastl::uninitialized_move_ptr(pDestBegin, pDataEnd, pDataEnd + n - nExtra);
			eastl::copy(pSrcBegin, pSrcEnd - (n - nExtra), pDestBegin);
		}
	}

	void DoInsertValue(size_type pos, size_type numElements, T&& arg)
	{
		T* pDest = mpData + pos;
		T* pDataEnd = mpData + numElements;

		eastl::uninitialized_move_ptr(pDataEnd - 1, pDataEnd, pDataEnd);
		eastl::move_backward(pDest, pDataEnd - 1, pDataEnd); // We need move_backward because of potential overlap issues.
		eastl::destruct(pDest);
		::new (pDest) T(eastl::forward<T>(arg));
	}

	T* mpData = nullptr;
};

// swallow allows for parameter pack expansion of arguments as means of expanding operations performed
// if a void function is used for operation expansion, it should be wrapped in (..., 0) so that the compiler
// thinks it has a parameter to pass into the function
template <typename... Ts>
void swallow(Ts&&...) { }

inline bool variadicAnd(bool cond) { return cond; }

inline bool variadicAnd(bool cond, bool conds...) { return cond && variadicAnd(conds); }

// Helper struct to check for strict compatibility between two iterators, whilst still allowing for
// conversion between TupleVecImpl<Ts...>::iterator and TupleVecImpl<Ts...>::const_iterator.
template <bool IsSameSize, typename From, typename To>
struct TupleVecIterCompatibleImpl : public false_type { };

template<>
struct TupleVecIterCompatibleImpl<true, TupleTypes<>, TupleTypes<>> : public true_type { };

template <typename From, typename... FromRest, typename To, typename... ToRest>
struct TupleVecIterCompatibleImpl<true, TupleTypes<From, FromRest...>, TupleTypes<To, ToRest...>> : public integral_constant<bool,
		TupleVecIterCompatibleImpl<true, TupleTypes<FromRest...>, TupleTypes<ToRest...>>::value &&
		is_same<typename remove_const<From>::type, typename remove_const<To>::type>::value >
{ };

template <typename From, typename To>
struct TupleVecIterCompatible;

template<typename... Us, typename... Ts>
struct TupleVecIterCompatible<TupleTypes<Us...>, TupleTypes<Ts...>> :
	public TupleVecIterCompatibleImpl<sizeof...(Us) == sizeof...(Ts), TupleTypes<Us...>, TupleTypes<Ts...>>
{ };

// The Iterator operates by storing a persistent index internally,
// and resolving the tuple of pointers to the various parts of the original tupleVec when dereferenced.
// While resolving the tuple is a non-zero operation, it consistently generated better code than the alternative of
// storing - and harmoniously updating on each modification - a full tuple of pointers to the tupleVec's data
template <eastl_size_t... Indices, typename... Ts>
struct TupleVecIter<index_sequence<Indices...>, Ts...>
	: public iterator<EASTL_ITC_NS::random_access_iterator_tag, tuple<Ts...>, eastl_size_t, tuple<Ts*...>, tuple<Ts&...>>
{
private:
	typedef TupleVecIter<index_sequence<Indices...>, Ts...> this_type;
	typedef eastl_size_t size_type;

	typedef iterator<EASTL_ITC_NS::random_access_iterator_tag, tuple<Ts...>, eastl_size_t, tuple<Ts*...>, tuple<Ts&...>> iter_type;

	template<typename U, typename... Us>
	friend struct TupleVecIter;

	template<typename U, typename V, typename... Us>
	friend class TupleVecImpl;

	template<typename U>
	friend class move_iterator;
public:
	typedef typename iter_type::iterator_category iterator_category;
	typedef typename iter_type::value_type value_type;
	typedef typename iter_type::difference_type difference_type;
	typedef typename iter_type::pointer pointer;
	typedef typename iter_type::reference reference;

	TupleVecIter() = default;

	template<typename VecImplType>
	TupleVecIter(VecImplType* tupleVec, size_type index)
		: mIndex(index)
		, mpData{(void*)tupleVec->TupleVecLeaf<Indices, Ts>::mpData...}
	{ }

	template <typename OtherIndicesType, typename... Us,
			  typename = typename enable_if<TupleVecIterCompatible<TupleTypes<Us...>, TupleTypes<Ts...>>::value, bool>::type>
	TupleVecIter(const TupleVecIter<OtherIndicesType, Us...>& other)
		: mIndex(other.mIndex)
		, mpData{other.mpData[Indices]...}
	{
	}

	bool operator==(const TupleVecIter& other) const { return mIndex == other.mIndex && mpData[0] == other.mpData[0]; }
	bool operator!=(const TupleVecIter& other) const { return mIndex != other.mIndex || mpData[0] != other.mpData[0]; }
	reference operator*() const { return MakeReference(); }

	this_type& operator++() { ++mIndex; return *this; }
	this_type operator++(int)
	{
		this_type temp = *this;
		++mIndex;
		return temp;
	}

	this_type& operator--() { --mIndex; return *this; }
	this_type operator--(int)
	{
		this_type temp = *this;
		--mIndex;
		return temp;
	}

	this_type& operator+=(difference_type n) { mIndex += n; return *this; }
	this_type operator+(difference_type n) const
	{
		this_type temp = *this;
		return temp += n;
	}
	friend this_type operator+(difference_type n, const this_type& rhs)
	{
		this_type temp = rhs;
		return temp += n;
	}

	this_type& operator-=(difference_type n) { mIndex -= n; return *this; }
	this_type operator-(difference_type n) const
	{
		this_type temp = *this;
		return temp -= n;
	}
	friend this_type operator-(difference_type n, const this_type& rhs)
	{
		this_type temp = rhs;
		return temp -= n;
	}

	difference_type operator-(const this_type& rhs) const { return mIndex - rhs.mIndex; }
	bool operator<(const this_type& rhs) const { return mIndex < rhs.mIndex; }
	bool operator>(const this_type& rhs) const { return mIndex > rhs.mIndex; }
	bool operator>=(const this_type& rhs) const { return mIndex >= rhs.mIndex; }
	bool operator<=(const this_type& rhs) const { return mIndex <= rhs.mIndex; }

	reference operator[](const size_type n) const
	{
		return *(*this + n);
	}

private:

	value_type MakeValue() const
	{
		return value_type(((Ts*)mpData[Indices])[mIndex]...);
	}

	reference MakeReference() const
	{
		return reference(((Ts*)mpData[Indices])[mIndex]...);
	}

	pointer MakePointer() const
	{
		return pointer(&((Ts*)mpData[Indices])[mIndex]...);
	}

	size_type mIndex = 0;
	const void* mpData[sizeof...(Ts)];
};

// TupleVecImpl
template <typename Allocator, eastl_size_t... Indices, typename... Ts>
class TupleVecImpl<Allocator, index_sequence<Indices...>, Ts...> : public TupleVecLeaf<Indices, Ts>...
{
	typedef Allocator	allocator_type;
	typedef index_sequence<Indices...> index_sequence_type;
	typedef TupleVecImpl<Allocator, index_sequence_type, Ts...> this_type;
	typedef TupleVecImpl<Allocator, index_sequence_type, const Ts...> const_this_type;

public:
	typedef TupleVecInternal::TupleVecIter<index_sequence_type, Ts...> iterator;
	typedef TupleVecInternal::TupleVecIter<index_sequence_type, const Ts...> const_iterator;
	typedef eastl::reverse_iterator<iterator> reverse_iterator;
	typedef eastl::reverse_iterator<const_iterator> const_reverse_iterator;
	typedef eastl_size_t size_type;
	typedef eastl::tuple<Ts...> value_tuple;
	typedef eastl::tuple<Ts&...> reference_tuple;
	typedef eastl::tuple<const Ts&...> const_reference_tuple;
	typedef eastl::tuple<Ts*...> ptr_tuple;
	typedef eastl::tuple<const Ts*...> const_ptr_tuple;
	typedef eastl::tuple<Ts&&...> rvalue_tuple;

	TupleVecImpl()
		: mDataSizeAndAllocator(0, EASTL_TUPLE_VECTOR_DEFAULT_ALLOCATOR)
	{}

	TupleVecImpl(const allocator_type& allocator)
		: mDataSizeAndAllocator(0, allocator)
	{}

	TupleVecImpl(this_type&& x)
		: mDataSizeAndAllocator(0, eastl::move(x.get_allocator()))
	{
		swap(x);
	}

	TupleVecImpl(this_type&& x, const Allocator& allocator)
		: mDataSizeAndAllocator(0, allocator)
	{
		if (get_allocator() == x.get_allocator()) // If allocators are equivalent, then we can safely swap member-by-member
		{
			swap(x);
		}
		else
		{
			this_type temp(eastl::move(*this));
			temp.swap(x);
		}
	}

	TupleVecImpl(const this_type& x)
		: mDataSizeAndAllocator(0, x.get_allocator())
	{
		DoInitFromIterator(x.begin(), x.end());
	}

	template<typename OtherAllocator>
	TupleVecImpl(const TupleVecImpl<OtherAllocator, index_sequence_type, Ts...>& x, const Allocator& allocator)
		: mDataSizeAndAllocator(0, allocator)
	{
		DoInitFromIterator(x.begin(), x.end());
	}

	template<typename MoveIterBase>
	TupleVecImpl(move_iterator<MoveIterBase> begin, move_iterator<MoveIterBase> end, const allocator_type& allocator = EASTL_TUPLE_VECTOR_DEFAULT_ALLOCATOR)
		: mDataSizeAndAllocator(0, allocator)
	{
		DoInitFromIterator(begin, end);
	}

	TupleVecImpl(const_iterator begin, const_iterator end, const allocator_type& allocator = EASTL_TUPLE_VECTOR_DEFAULT_ALLOCATOR)
		: mDataSizeAndAllocator(0, allocator )
	{
		DoInitFromIterator(begin, end);
	}

	TupleVecImpl(size_type n, const allocator_type& allocator = EASTL_TUPLE_VECTOR_DEFAULT_ALLOCATOR)
		: mDataSizeAndAllocator(0, allocator)
	{
		DoInitDefaultFill(n);
	}

	TupleVecImpl(size_type n, const Ts&... args)
		: mDataSizeAndAllocator(0, EASTL_TUPLE_VECTOR_DEFAULT_ALLOCATOR)
	{
		DoInitFillArgs(n, args...);
	}

	TupleVecImpl(size_type n, const Ts&... args, const allocator_type& allocator)
		: mDataSizeAndAllocator(0, allocator)
	{
		DoInitFillArgs(n, args...);
	}

	TupleVecImpl(size_type n, const_reference_tuple tup, const allocator_type& allocator = EASTL_TUPLE_VECTOR_DEFAULT_ALLOCATOR)
		: mDataSizeAndAllocator(0, allocator)
	{
		DoInitFillTuple(n, tup);
	}

	TupleVecImpl(const value_tuple* first, const value_tuple* last, const allocator_type& allocator = EASTL_TUPLE_VECTOR_DEFAULT_ALLOCATOR)
		: mDataSizeAndAllocator(0, allocator)
	{
		DoInitFromTupleArray(first, last);
	}

	TupleVecImpl(std::initializer_list<value_tuple> iList, const allocator_type& allocator = EASTL_TUPLE_VECTOR_DEFAULT_ALLOCATOR)
		: mDataSizeAndAllocator(0, allocator)
	{
		DoInitFromTupleArray(iList.begin(), iList.end());
	}

protected:
	// ctor to provide a pre-allocated field of data that the container will own, specifically for fixed_tuple_vector
	TupleVecImpl(const allocator_type& allocator, void* pData, size_type capacity, size_type dataSize)
		: mpData(pData), mNumCapacity(capacity), mDataSizeAndAllocator(dataSize, allocator)
	{
		TupleRecurser<Ts...>::template SetNewData<this_type, 0>(*this, mpData, mNumCapacity, 0);
	}

public:
	~TupleVecImpl()
	{
		swallow((eastl::destruct(TupleVecLeaf<Indices, Ts>::mpData, TupleVecLeaf<Indices, Ts>::mpData + mNumElements), 0)...);
		if (mpData)
			EASTLFree(get_allocator(), mpData, internalDataSize());
	}

	void assign(size_type n, const Ts&... args)
	{
		if (n > mNumCapacity)
		{
			this_type temp(n, args..., get_allocator()); // We have little choice but to reallocate with new memory.
			swap(temp);
		}
		else if (n > mNumElements) // If n > mNumElements ...
		{
			size_type oldNumElements = mNumElements;
			swallow((eastl::fill(TupleVecLeaf<Indices, Ts>::mpData, TupleVecLeaf<Indices, Ts>::mpData + oldNumElements, args), 0)...);
			swallow((eastl::uninitialized_fill_ptr(TupleVecLeaf<Indices, Ts>::mpData + oldNumElements,
					                       TupleVecLeaf<Indices, Ts>::mpData + n, args), 0)...);
			mNumElements = n;
		}
		else // else 0 <= n <= mNumElements
		{
			swallow((eastl::fill(TupleVecLeaf<Indices, Ts>::mpData, TupleVecLeaf<Indices, Ts>::mpData + n, args), 0)...);
			erase(begin() + n, end());
		}
	}

	void assign(const_iterator first, const_iterator last)
	{
#if EASTL_ASSERT_ENABLED
		if (EASTL_UNLIKELY(!validate_iterator_pair(first, last)))
			EASTL_FAIL_MSG("tuple_vector::assign -- invalid iterator pair");
#endif
		size_type newNumElements = last - first;
		if (newNumElements > mNumCapacity)
		{
			this_type temp(first, last, get_allocator());
			swap(temp);
		}
		else
		{
			const void* ppOtherData[sizeof...(Ts)] = {first.mpData[Indices]...};
			size_type firstIdx = first.mIndex;
			size_type lastIdx = last.mIndex;
			if (newNumElements > mNumElements) // If n > mNumElements ...
			{
				size_type oldNumElements = mNumElements;
				swallow((eastl::copy((Ts*)(ppOtherData[Indices]) + firstIdx,
						       (Ts*)(ppOtherData[Indices]) + firstIdx + oldNumElements,
						       TupleVecLeaf<Indices, Ts>::mpData), 0)...);
				swallow((eastl::uninitialized_copy_ptr((Ts*)(ppOtherData[Indices]) + firstIdx + oldNumElements,
						                       (Ts*)(ppOtherData[Indices]) + lastIdx,
						                       TupleVecLeaf<Indices, Ts>::mpData + oldNumElements), 0)...);
				mNumElements = newNumElements;
			}
			else // else 0 <= n <= mNumElements
			{
				swallow((eastl::copy((Ts*)(ppOtherData[Indices]) + firstIdx, (Ts*)(ppOtherData[Indices]) + lastIdx,
						       TupleVecLeaf<Indices, Ts>::mpData), 0)...);
				erase(begin() + newNumElements, end());
			}
		}
	}

	void assign(const value_tuple* first, const value_tuple* last)
	{
#if EASTL_ASSERT_ENABLED
		if (EASTL_UNLIKELY(first > last || first == nullptr || last == nullptr))
			EASTL_FAIL_MSG("tuple_vector::assign from tuple array -- invalid ptrs");
#endif
		size_type newNumElements = last - first;
		if (newNumElements > mNumCapacity)
		{
			this_type temp(first, last, get_allocator());
			swap(temp);
		}
		else
		{
			if (newNumElements > mNumElements) // If n > mNumElements ...
			{
				size_type oldNumElements = mNumElements;

				DoCopyFromTupleArray(begin(), begin() + oldNumElements, first);
				DoUninitializedCopyFromTupleArray(begin() + oldNumElements, begin() + newNumElements, first + oldNumElements);
				mNumElements = newNumElements;
			}
			else // else 0 <= n <= mNumElements
			{
				DoCopyFromTupleArray(begin(), begin() + newNumElements, first);
				erase(begin() + newNumElements, end());
			}
		}
	}

	reference_tuple push_back()
	{
		size_type oldNumElements = mNumElements;
		size_type newNumElements = oldNumElements + 1;
		size_type oldNumCapacity = mNumCapacity;
		mNumElements = newNumElements;
		DoGrow(oldNumElements, oldNumCapacity, newNumElements);
		swallow(::new(TupleVecLeaf<Indices, Ts>::mpData + oldNumElements) Ts()...);
		return back();
	}

	void push_back(const Ts&... args)
	{
		size_type oldNumElements = mNumElements;
		size_type newNumElements = oldNumElements + 1;
		size_type oldNumCapacity = mNumCapacity;
		mNumElements = newNumElements;
		DoGrow(oldNumElements, oldNumCapacity, newNumElements);
		swallow(::new(TupleVecLeaf<Indices, Ts>::mpData + oldNumElements) Ts(args)...);
	}

	void push_back_uninitialized()
	{
		size_type oldNumElements = mNumElements;
		size_type newNumElements = oldNumElements + 1;
		size_type oldNumCapacity = mNumCapacity;
		mNumElements = newNumElements;
		DoGrow(oldNumElements, oldNumCapacity, newNumElements);
	}

	reference_tuple emplace_back(Ts&&... args)
	{
		size_type oldNumElements = mNumElements;
		size_type newNumElements = oldNumElements + 1;
		size_type oldNumCapacity = mNumCapacity;
		mNumElements = newNumElements;
		DoGrow(oldNumElements, oldNumCapacity, newNumElements);
		swallow(::new(TupleVecLeaf<Indices, Ts>::mpData + oldNumElements) Ts(eastl::forward<Ts>(args))...);
		return back();
	}

	iterator emplace(const_iterator pos, Ts&&... args)
	{
#if EASTL_ASSERT_ENABLED
		if (EASTL_UNLIKELY(validate_iterator(pos) == isf_none))
			EASTL_FAIL_MSG("tuple_vector::emplace -- invalid iterator");
#endif
		size_type firstIdx = pos - cbegin();
		size_type oldNumElements = mNumElements;
		size_type newNumElements = mNumElements + 1;
		size_type oldNumCapacity = mNumCapacity;
		mNumElements = newNumElements;
		if (newNumElements > oldNumCapacity || firstIdx != oldNumElements)
		{
			if (newNumElements > oldNumCapacity)
			{
				const size_type newCapacity = eastl::max(GetNewCapacity(oldNumCapacity), newNumElements);

				void* ppNewLeaf[sizeof...(Ts)];
				pair<void*, size_type> allocation =	TupleRecurser<Ts...>::template DoAllocate<allocator_type, 0, index_sequence_type, Ts...>(
					*this, ppNewLeaf, newCapacity, 0);

				swallow((TupleVecLeaf<Indices, Ts>::DoUninitializedMoveAndDestruct(
					0, firstIdx, (Ts*)ppNewLeaf[Indices]), 0)...);
				swallow((TupleVecLeaf<Indices, Ts>::DoUninitializedMoveAndDestruct(
					firstIdx, oldNumElements, (Ts*)ppNewLeaf[Indices] + firstIdx + 1), 0)...);
				swallow(::new ((Ts*)ppNewLeaf[Indices] + firstIdx) Ts(eastl::forward<Ts>(args))...);
				swallow(TupleVecLeaf<Indices, Ts>::mpData = (Ts*)ppNewLeaf[Indices]...);

				EASTLFree(get_allocator(), mpData, internalDataSize());
				mpData = allocation.first;
				mNumCapacity = newCapacity;
				internalDataSize() = allocation.second;
			}
			else
			{
				swallow((TupleVecLeaf<Indices, Ts>::DoInsertValue(firstIdx, oldNumElements, eastl::forward<Ts>(args)), 0)...);
			}
		}
		else
		{
			swallow(::new (TupleVecLeaf<Indices, Ts>::mpData + oldNumElements) Ts(eastl::forward<Ts>(args))...);
		}
		return begin() + firstIdx;
	}

	iterator insert(const_iterator pos, size_type n, const Ts&... args)
	{
#if EASTL_ASSERT_ENABLED
		if (EASTL_UNLIKELY(validate_iterator(pos) == isf_none))
			EASTL_FAIL_MSG("tuple_vector::insert -- invalid iterator");
#endif
		size_type firstIdx = pos - cbegin();
		size_type lastIdx = firstIdx + n;
		size_type oldNumElements = mNumElements;
		size_type newNumElements = mNumElements + n;
		size_type oldNumCapacity = mNumCapacity;
		mNumElements = newNumElements;
		if (newNumElements > oldNumCapacity || firstIdx != oldNumElements)
		{
			if (newNumElements > oldNumCapacity)
			{
				const size_type newCapacity = eastl::max(GetNewCapacity(oldNumCapacity), newNumElements);

				void* ppNewLeaf[sizeof...(Ts)];
				pair<void*, size_type> allocation = TupleRecurser<Ts...>::template DoAllocate<allocator_type, 0, index_sequence_type, Ts...>(
						*this, ppNewLeaf, newCapacity, 0);

				swallow((TupleVecLeaf<Indices, Ts>::DoUninitializedMoveAndDestruct(
					0, firstIdx, (Ts*)ppNewLeaf[Indices]), 0)...);
				swallow((TupleVecLeaf<Indices, Ts>::DoUninitializedMoveAndDestruct(
					firstIdx, oldNumElements, (Ts*)ppNewLeaf[Indices] + lastIdx), 0)...);
				swallow((eastl::uninitialized_fill_ptr((Ts*)ppNewLeaf[Indices] + firstIdx, (Ts*)ppNewLeaf[Indices] + lastIdx, args), 0)...);
				swallow(TupleVecLeaf<Indices, Ts>::mpData = (Ts*)ppNewLeaf[Indices]...);

				EASTLFree(get_allocator(), mpData, internalDataSize());
				mpData = allocation.first;
				mNumCapacity = newCapacity;
				internalDataSize() = allocation.second;
			}
			else
			{
				swallow((TupleVecLeaf<Indices, Ts>::DoInsertAndFill(firstIdx, n, oldNumElements, args), 0)...);
			}
		}
		else
		{
			swallow((eastl::uninitialized_fill_ptr(TupleVecLeaf<Indices, Ts>::mpData + oldNumElements,
					                       TupleVecLeaf<Indices, Ts>::mpData + newNumElements, args), 0)...);
		}
		return begin() + firstIdx;
	}

	iterator insert(const_iterator pos, const_iterator first, const_iterator last)
	{
#if EASTL_ASSERT_ENABLED
		if (EASTL_UNLIKELY(validate_iterator(pos) == isf_none))
			EASTL_FAIL_MSG("tuple_vector::insert -- invalid iterator");
		if (EASTL_UNLIKELY(!validate_iterator_pair(first, last)))
			EASTL_FAIL_MSG("tuple_vector::insert -- invalid iterator pair");
#endif
		size_type posIdx = pos - cbegin();
		size_type firstIdx = first.mIndex;
		size_type lastIdx = last.mIndex;
		size_type numToInsert = last - first;
		size_type oldNumElements = mNumElements;
		size_type newNumElements = oldNumElements + numToInsert;
		size_type oldNumCapacity = mNumCapacity;
		mNumElements = newNumElements;
		const void* ppOtherData[sizeof...(Ts)] = {first.mpData[Indices]...};
		if (newNumElements > oldNumCapacity || posIdx != oldNumElements)
		{
			if (newNumElements > oldNumCapacity)
			{
				const size_type newCapacity = eastl::max(GetNewCapacity(oldNumCapacity), newNumElements);

				void* ppNewLeaf[sizeof...(Ts)];
				pair<void*, size_type> allocation = TupleRecurser<Ts...>::template DoAllocate<allocator_type, 0, index_sequence_type, Ts...>(
						*this, ppNewLeaf, newCapacity, 0);

				swallow((TupleVecLeaf<Indices, Ts>::DoUninitializedMoveAndDestruct(
					0, posIdx, (Ts*)ppNewLeaf[Indices]), 0)...);
				swallow((TupleVecLeaf<Indices, Ts>::DoUninitializedMoveAndDestruct(
					posIdx, oldNumElements, (Ts*)ppNewLeaf[Indices] + posIdx + numToInsert), 0)...);
				swallow((eastl::uninitialized_copy_ptr((Ts*)(ppOtherData[Indices]) + firstIdx,
						                       (Ts*)(ppOtherData[Indices]) + lastIdx,
						                       (Ts*)ppNewLeaf[Indices] + posIdx), 0)...);
				swallow(TupleVecLeaf<Indices, Ts>::mpData = (Ts*)ppNewLeaf[Indices]...);

				EASTLFree(get_allocator(), mpData, internalDataSize());
				mpData = allocation.first;
				mNumCapacity = newCapacity;
				internalDataSize() = allocation.second;
			}
			else
			{
				swallow((TupleVecLeaf<Indices, Ts>::DoInsertRange(
					(Ts*)(ppOtherData[Indices]) + firstIdx, (Ts*)(ppOtherData[Indices]) + lastIdx,
					TupleVecLeaf<Indices, Ts>::mpData + posIdx, oldNumElements), 0)...);
			}
		}
		else
		{
			swallow((eastl::uninitialized_copy_ptr((Ts*)(ppOtherData[Indices]) + firstIdx,
					                       (Ts*)(ppOtherData[Indices]) + lastIdx,
					                       TupleVecLeaf<Indices, Ts>::mpData + posIdx), 0)...);
		}
		return begin() + posIdx;
	}

	iterator insert(const_iterator pos, const value_tuple* first, const value_tuple* last)
	{
#if EASTL_ASSERT_ENABLED
		if (EASTL_UNLIKELY(validate_iterator(pos) == isf_none))
			EASTL_FAIL_MSG("tuple_vector::insert -- invalid iterator");
		if (EASTL_UNLIKELY(first > last || first == nullptr || last == nullptr))
			EASTL_FAIL_MSG("tuple_vector::insert -- invalid source pointers");
#endif
		size_type posIdx = pos - cbegin();
		size_type numToInsert = last - first;
		size_type oldNumElements = mNumElements;
		size_type newNumElements = oldNumElements + numToInsert;
		size_type oldNumCapacity = mNumCapacity;
		mNumElements = newNumElements;
		if (newNumElements > oldNumCapacity || posIdx != oldNumElements)
		{
			if (newNumElements > oldNumCapacity)
			{
				const size_type newCapacity = eastl::max(GetNewCapacity(oldNumCapacity), newNumElements);

				void* ppNewLeaf[sizeof...(Ts)];
				pair<void*, size_type> allocation = TupleRecurser<Ts...>::template DoAllocate<allocator_type, 0, index_sequence_type, Ts...>(
					*this, ppNewLeaf, newCapacity, 0);

				swallow((TupleVecLeaf<Indices, Ts>::DoUninitializedMoveAndDestruct(
					0, posIdx, (Ts*)ppNewLeaf[Indices]), 0)...);
				swallow((TupleVecLeaf<Indices, Ts>::DoUninitializedMoveAndDestruct(
					posIdx, oldNumElements, (Ts*)ppNewLeaf[Indices] + posIdx + numToInsert), 0)...);

				swallow(TupleVecLeaf<Indices, Ts>::mpData = (Ts*)ppNewLeaf[Indices]...);

				// Do this after mpData is updated so that we can use new iterators
				DoUninitializedCopyFromTupleArray(begin() + posIdx, begin() + posIdx + numToInsert, first);

				EASTLFree(get_allocator(), mpData, internalDataSize());
				mpData = allocation.first;
				mNumCapacity = newCapacity;
				internalDataSize() = allocation.second;
			}
			else
			{
				const size_type nExtra = oldNumElements - posIdx;
				void* ppDataEnd[sizeof...(Ts)] = { (void*)(TupleVecLeaf<Indices, Ts>::mpData + oldNumElements)... };
				void* ppDataBegin[sizeof...(Ts)] = { (void*)(TupleVecLeaf<Indices, Ts>::mpData + posIdx)... };
				if (numToInsert < nExtra) // If the inserted values are entirely within initialized memory (i.e. are before mpEnd)...
				{
					swallow((eastl::uninitialized_move_ptr((Ts*)ppDataEnd[Indices] - numToInsert,
						(Ts*)ppDataEnd[Indices], (Ts*)ppDataEnd[Indices]), 0)...);
					// We need move_backward because of potential overlap issues.
					swallow((eastl::move_backward((Ts*)ppDataBegin[Indices],
						(Ts*)ppDataEnd[Indices] - numToInsert, (Ts*)ppDataEnd[Indices]), 0)...);

					DoCopyFromTupleArray(pos, pos + numToInsert, first);
				}
				else
				{
					size_type numToInitialize = numToInsert - nExtra;
					swallow((eastl::uninitialized_move_ptr((Ts*)ppDataBegin[Indices],
						(Ts*)ppDataEnd[Indices], (Ts*)ppDataEnd[Indices] + numToInitialize), 0)...);

					DoCopyFromTupleArray(pos, begin() + oldNumElements, first);
					DoUninitializedCopyFromTupleArray(begin() + oldNumElements, pos + numToInsert, first + nExtra);
				}
			}
		}
		else
		{
			DoUninitializedCopyFromTupleArray(pos, pos + numToInsert, first);
		}
		return begin() + posIdx;
	}

	iterator erase(const_iterator first, const_iterator last)
	{
#if EASTL_ASSERT_ENABLED
		if (EASTL_UNLIKELY(validate_iterator(first) == isf_none || validate_iterator(last) == isf_none))
			EASTL_FAIL_MSG("tuple_vector::erase -- invalid iterator");
		if (EASTL_UNLIKELY(!validate_iterator_pair(first, last)))
			EASTL_FAIL_MSG("tuple_vector::erase -- invalid iterator pair");
#endif
		if (first != last)
		{
			size_type firstIdx = first - cbegin();
			size_type lastIdx = last - cbegin();
			size_type oldNumElements = mNumElements;
			size_type newNumElements = oldNumElements - (lastIdx - firstIdx);
			mNumElements = newNumElements;
			swallow((eastl::move(TupleVecLeaf<Indices, Ts>::mpData + lastIdx,
					       TupleVecLeaf<Indices, Ts>::mpData + oldNumElements,
					       TupleVecLeaf<Indices, Ts>::mpData + firstIdx), 0)...);
			swallow((eastl::destruct(TupleVecLeaf<Indices, Ts>::mpData + newNumElements,
					           TupleVecLeaf<Indices, Ts>::mpData + oldNumElements), 0)...);
		}
		return begin() + first.mIndex;
	}

	iterator erase_unsorted(const_iterator pos)
	{
#if EASTL_ASSERT_ENABLED
		if (EASTL_UNLIKELY(validate_iterator(pos) == isf_none))
			EASTL_FAIL_MSG("tuple_vector::erase_unsorted -- invalid iterator");
#endif
		size_type oldNumElements = mNumElements;
		size_type newNumElements = oldNumElements - 1;
		mNumElements = newNumElements;
		swallow((eastl::move(TupleVecLeaf<Indices, Ts>::mpData + newNumElements,
				       TupleVecLeaf<Indices, Ts>::mpData + oldNumElements,
				       TupleVecLeaf<Indices, Ts>::mpData + (pos - begin())), 0)...);
		swallow((eastl::destruct(TupleVecLeaf<Indices, Ts>::mpData + newNumElements,
				           TupleVecLeaf<Indices, Ts>::mpData + oldNumElements), 0)...);
		return begin() + pos.mIndex;
	}

	void resize(size_type n)
	{
		size_type oldNumElements = mNumElements;
		size_type oldNumCapacity = mNumCapacity;
		mNumElements = n;
		if (n > oldNumElements)
		{
			if (n > oldNumCapacity)
			{
				DoReallocate(oldNumElements, eastl::max<size_type>(GetNewCapacity(oldNumCapacity), n));
			}
			swallow((eastl::uninitialized_default_fill_n(TupleVecLeaf<Indices, Ts>::mpData + oldNumElements, n - oldNumElements), 0)...);
		}
		else
		{
			swallow((eastl::destruct(TupleVecLeaf<Indices, Ts>::mpData + n,
					           TupleVecLeaf<Indices, Ts>::mpData + oldNumElements), 0)...);
		}
	}

	void resize(size_type n, const Ts&... args)
	{
		size_type oldNumElements = mNumElements;
		size_type oldNumCapacity = mNumCapacity;
		mNumElements = n;
		if (n > oldNumElements)
		{
			if (n > oldNumCapacity)
			{
				DoReallocate(oldNumElements, eastl::max<size_type>(GetNewCapacity(oldNumCapacity), n));
			}
			swallow((eastl::uninitialized_fill_ptr(TupleVecLeaf<Indices, Ts>::mpData + oldNumElements,
					                       TupleVecLeaf<Indices, Ts>::mpData + n, args), 0)...);
		}
		else
		{
			swallow((eastl::destruct(TupleVecLeaf<Indices, Ts>::mpData + n,
					           TupleVecLeaf<Indices, Ts>::mpData + oldNumElements), 0)...);
		}
	}

	void reserve(size_type n)
	{
		DoConditionalReallocate(mNumElements, mNumCapacity, n);
	}

	void shrink_to_fit()
	{
		this_type temp(move_iterator<iterator>(begin()), move_iterator<iterator>(end()), get_allocator());
		swap(temp);
	}

	void clear() EA_NOEXCEPT
	{
		size_type oldNumElements = mNumElements;
		mNumElements = 0;
		swallow((eastl::destruct(TupleVecLeaf<Indices, Ts>::mpData, TupleVecLeaf<Indices, Ts>::mpData + oldNumElements), 0)...);
	}

	void pop_back()
	{
#if EASTL_ASSERT_ENABLED
		if (EASTL_UNLIKELY(mNumElements <= 0))
			EASTL_FAIL_MSG("tuple_vector::pop_back -- container is empty");
#endif
		size_type oldNumElements = mNumElements--;
		swallow((eastl::destruct(TupleVecLeaf<Indices, Ts>::mpData + oldNumElements - 1,
				           TupleVecLeaf<Indices, Ts>::mpData + oldNumElements), 0)...);
	}

	void swap(this_type& x)
	{
		swallow((eastl::swap(TupleVecLeaf<Indices, Ts>::mpData, x.TupleVecLeaf<Indices, Ts>::mpData), 0)...);
		eastl::swap(mpData, x.mpData);
		eastl::swap(mNumElements, x.mNumElements);
		eastl::swap(mNumCapacity, x.mNumCapacity);
		eastl::swap(get_allocator(), x.get_allocator());
		eastl::swap(internalDataSize(), x.internalDataSize());
	}

	void assign(size_type n, const_reference_tuple tup) { assign(n, eastl::get<Indices>(tup)...); }
	void assign(std::initializer_list<value_tuple> iList) { assign(iList.begin(), iList.end()); }

	void push_back(Ts&&... args) { emplace_back(eastl::forward<Ts>(args)...); }
	void push_back(const_reference_tuple tup) { push_back(eastl::get<Indices>(tup)...); }
	void push_back(rvalue_tuple tup) { emplace_back(eastl::forward<Ts>(eastl::get<Indices>(tup))...); }

	void emplace_back(rvalue_tuple tup) { emplace_back(eastl::forward<Ts>(eastl::get<Indices>(tup))...); }
	void emplace(const_iterator pos, rvalue_tuple tup) { emplace(pos, eastl::forward<Ts>(eastl::get<Indices>(tup))...); }

	iterator insert(const_iterator pos, const Ts&... args) { return insert(pos, 1, args...); }
	iterator insert(const_iterator pos, Ts&&... args) { return emplace(pos, eastl::forward<Ts>(args)...); }
	iterator insert(const_iterator pos, rvalue_tuple tup) { return emplace(pos, eastl::forward<Ts>(eastl::get<Indices>(tup))...); }
	iterator insert(const_iterator pos, const_reference_tuple tup) { return insert(pos, eastl::get<Indices>(tup)...); }
	iterator insert(const_iterator pos, size_type n, const_reference_tuple tup) { return insert(pos, n, eastl::get<Indices>(tup)...); }
	iterator insert(const_iterator pos, std::initializer_list<value_tuple> iList) { return insert(pos, iList.begin(), iList.end()); }

	iterator erase(const_iterator pos) { return erase(pos, pos + 1); }
	reverse_iterator erase(const_reverse_iterator pos) { return reverse_iterator(erase((pos + 1).base(), (pos).base())); }
	reverse_iterator erase(const_reverse_iterator first, const_reverse_iterator last) { return reverse_iterator(erase((last).base(), (first).base())); }
	reverse_iterator erase_unsorted(const_reverse_iterator pos) { return reverse_iterator(erase_unsorted((pos + 1).base())); }

	void resize(size_type n, const_reference_tuple tup) { resize(n, eastl::get<Indices>(tup)...); }

	bool empty() const EA_NOEXCEPT { return mNumElements == 0; }
	size_type size() const EA_NOEXCEPT { return mNumElements; }
	size_type capacity() const EA_NOEXCEPT { return mNumCapacity; }

	iterator begin() EA_NOEXCEPT { return iterator(this, 0); }
	const_iterator begin() const EA_NOEXCEPT { return const_iterator((const_this_type*)(this), 0); }
	const_iterator cbegin() const EA_NOEXCEPT { return const_iterator((const_this_type*)(this), 0); }

	iterator end() EA_NOEXCEPT { return iterator(this, size()); }
	const_iterator end() const EA_NOEXCEPT { return const_iterator((const_this_type*)(this), size()); }
	const_iterator cend() const EA_NOEXCEPT { return const_iterator((const_this_type*)(this), size()); }

	reverse_iterator rbegin() EA_NOEXCEPT { return reverse_iterator(end()); }
	const_reverse_iterator rbegin() const  EA_NOEXCEPT { return const_reverse_iterator(end()); }
	const_reverse_iterator crbegin() const EA_NOEXCEPT { return const_reverse_iterator(end()); }

	reverse_iterator rend() EA_NOEXCEPT { return reverse_iterator(begin()); }
	const_reverse_iterator rend() const EA_NOEXCEPT { return const_reverse_iterator(begin()); }
	const_reverse_iterator crend() const EA_NOEXCEPT { return const_reverse_iterator(begin()); }

	ptr_tuple data() EA_NOEXCEPT { return ptr_tuple(TupleVecLeaf<Indices, Ts>::mpData...); }
	const_ptr_tuple data() const EA_NOEXCEPT { return const_ptr_tuple(TupleVecLeaf<Indices, Ts>::mpData...); }

	reference_tuple at(size_type n)
	{
#if EASTL_EXCEPTIONS_ENABLED
		if (EASTL_UNLIKELY(n >= mNumElements))
			throw std::out_of_range("tuple_vector::at -- out of range");
#elif EASTL_ASSERT_ENABLED
		if (EASTL_UNLIKELY(n >= mNumElements))
			EASTL_FAIL_MSG("tuple_vector::at -- out of range");
#endif
		return reference_tuple(*(TupleVecLeaf<Indices, Ts>::mpData + n)...);
	}

	const_reference_tuple at(size_type n) const
	{
#if EASTL_EXCEPTIONS_ENABLED
		if (EASTL_UNLIKELY(n >= mNumElements))
			throw std::out_of_range("tuple_vector::at -- out of range");
#elif EASTL_ASSERT_ENABLED
		if (EASTL_UNLIKELY(n >= mNumElements))
			EASTL_FAIL_MSG("tuple_vector::at -- out of range");
#endif
		return const_reference_tuple(*(TupleVecLeaf<Indices, Ts>::mpData + n)...);
	}

	reference_tuple operator[](size_type n) { return at(n); }
	const_reference_tuple operator[](size_type n) const { return at(n); }

	reference_tuple front()
	{
		#if EASTL_ASSERT_ENABLED && EASTL_EMPTY_REFERENCE_ASSERT_ENABLED
			if (EASTL_UNLIKELY(mNumElements == 0)) // We don't allow the user to reference an empty container.
				EASTL_FAIL_MSG("tuple_vector::front -- empty vector");
		#else
			// We allow the user to reference an empty container.
		#endif

		return at(0);
	}

	const_reference_tuple front() const
	{
		#if EASTL_ASSERT_ENABLED && EASTL_EMPTY_REFERENCE_ASSERT_ENABLED
			if (EASTL_UNLIKELY(mNumElements == 0)) // We don't allow the user to reference an empty container.
				EASTL_FAIL_MSG("tuple_vector::front -- empty vector");
		#else
			// We allow the user to reference an empty container.
		#endif

		return at(0);
	}

	reference_tuple back()
	{
		#if EASTL_ASSERT_ENABLED && EASTL_EMPTY_REFERENCE_ASSERT_ENABLED
			if (EASTL_UNLIKELY(mNumElements == 0)) // We don't allow the user to reference an empty container.
				EASTL_FAIL_MSG("tuple_vector::back -- empty vector");
		#else
			// We allow the user to reference an empty container.
		#endif

		return at(size() - 1);
	}

	const_reference_tuple back() const
	{
		#if EASTL_ASSERT_ENABLED && EASTL_EMPTY_REFERENCE_ASSERT_ENABLED
			if (EASTL_UNLIKELY(mNumElements == 0)) // We don't allow the user to reference an empty container.
				EASTL_FAIL_MSG("tuple_vector::back -- empty vector");
		#else
			// We allow the user to reference an empty container.
		#endif

		return at(size() - 1);
	}

	template <size_type I>
	tuplevec_element_t<I, Ts...>* get()
	{
		typedef tuplevec_element_t<I, Ts...> Element;
		return TupleVecLeaf<I, Element>::mpData;
	}
	template <size_type I>
	const tuplevec_element_t<I, Ts...>* get() const
	{
		typedef tuplevec_element_t<I, Ts...> Element;
		return TupleVecLeaf<I, Element>::mpData;
	}

	template <typename T>
	T* get()
	{
		typedef tuplevec_index<T, TupleTypes<Ts...>> Index;
		return TupleVecLeaf<Index::index, T>::mpData;
	}
	template <typename T>
	const T* get() const
	{
		typedef tuplevec_index<T, TupleTypes<Ts...>> Index;
		return TupleVecLeaf<Index::index, T>::mpData;
	}

	this_type& operator=(const this_type& other)
	{
		if (this != &other)
		{
			clear();
			assign(other.begin(), other.end());
		}
		return *this;
	}

	this_type& operator=(this_type&& other)
	{
		if (this != &other)
		{
			swap(other);
		}
		return *this;
	}

	this_type& operator=(std::initializer_list<value_tuple> iList)
	{
		assign(iList.begin(), iList.end());
		return *this;
	}

	bool validate() const EA_NOEXCEPT
	{
		if (mNumElements > mNumCapacity)
			return false;
		if (!(variadicAnd(mpData <= TupleVecLeaf<Indices, Ts>::mpData...)))
			return false;
		void* pDataEnd = (void*)((uintptr_t)mpData + internalDataSize());
		if (!(variadicAnd(pDataEnd >= TupleVecLeaf<Indices, Ts>::mpData...)))
			return false;
		return true;
	}

	int validate_iterator(const_iterator iter) const EA_NOEXCEPT
	{
		if (!(variadicAnd(iter.mpData[Indices] == TupleVecLeaf<Indices, Ts>::mpData...)))
			return isf_none;
		if (iter.mIndex < mNumElements)
			return (isf_valid | isf_current | isf_can_dereference);
		if (iter.mIndex <= mNumElements)
			return (isf_valid | isf_current);
		return isf_none;
	}

	static bool validate_iterator_pair(const_iterator first, const_iterator last) EA_NOEXCEPT
	{
		return (first.mIndex <= last.mIndex) && variadicAnd(first.mpData[Indices] == last.mpData[Indices]...);
	}

	template <typename Iterator, typename = typename enable_if<is_iterator_wrapper<Iterator>::value, bool>::type>
	int validate_iterator(Iterator iter) const EA_NOEXCEPT { return validate_iterator(unwrap_iterator(iter)); }

	template <typename Iterator, typename = typename enable_if<is_iterator_wrapper<Iterator>::value, bool>::type>
	static bool validate_iterator_pair(Iterator first, Iterator last) EA_NOEXCEPT { return validate_iterator_pair(unwrap_iterator(first), unwrap_iterator(last)); }

	allocator_type& get_allocator() EA_NOEXCEPT { return mDataSizeAndAllocator.second(); }
	const allocator_type& get_allocator() const EA_NOEXCEPT { return mDataSizeAndAllocator.second(); }

	void set_allocator(const allocator_type& alloc) { mDataSizeAndAllocator.second() = alloc; }

protected:

	void* mpData = nullptr;
	size_type mNumElements = 0;
	size_type mNumCapacity = 0;

	compressed_pair<size_type, allocator_type> mDataSizeAndAllocator;

	size_type& internalDataSize() EA_NOEXCEPT { return mDataSizeAndAllocator.first(); }
	size_type const& internalDataSize() const EA_NOEXCEPT { return mDataSizeAndAllocator.first(); }

	friend struct TupleRecurser<>;
	template<typename... Us>
	friend struct TupleRecurser;

	template <typename MoveIterBase>
	void DoInitFromIterator(move_iterator<MoveIterBase> begin, move_iterator<MoveIterBase> end)
	{
#if EASTL_ASSERT_ENABLED
		if (EASTL_UNLIKELY(!validate_iterator_pair(begin, end)))
			EASTL_FAIL_MSG("tuple_vector::erase -- invalid iterator pair");
#endif
		size_type newNumElements = (size_type)(end - begin);
		const void* ppOtherData[sizeof...(Ts)] = { begin.base().mpData[Indices]... };
		size_type beginIdx = begin.base().mIndex;
		size_type endIdx = end.base().mIndex;
		DoConditionalReallocate(0, mNumCapacity, newNumElements);
		mNumElements = newNumElements;
		swallow((eastl::uninitialized_move_ptr(eastl::move_iterator<Ts*>((Ts*)(ppOtherData[Indices]) + beginIdx),
				                       eastl::move_iterator<Ts*>((Ts*)(ppOtherData[Indices]) + endIdx),
				                       TupleVecLeaf<Indices, Ts>::mpData), 0)...);
	}

	void DoInitFromIterator(const_iterator begin, const_iterator end)
	{
#if EASTL_ASSERT_ENABLED
		if (EASTL_UNLIKELY(!validate_iterator_pair(begin, end)))
			EASTL_FAIL_MSG("tuple_vector::erase -- invalid iterator pair");
#endif
		size_type newNumElements = (size_type)(end - begin);
		const void* ppOtherData[sizeof...(Ts)] = { begin.mpData[Indices]... };
		size_type beginIdx = begin.mIndex;
		size_type endIdx = end.mIndex;
		DoConditionalReallocate(0, mNumCapacity, newNumElements);
		mNumElements = newNumElements;
		swallow((eastl::uninitialized_copy_ptr((Ts*)(ppOtherData[Indices]) + beginIdx,
				                       (Ts*)(ppOtherData[Indices]) + endIdx,
				                       TupleVecLeaf<Indices, Ts>::mpData), 0)...);
	}

	void DoInitFillTuple(size_type n, const_reference_tuple tup) { DoInitFillArgs(n, eastl::get<Indices>(tup)...); }

	void DoInitFillArgs(size_type n, const Ts&... args)
	{
		DoConditionalReallocate(0, mNumCapacity, n);
		mNumElements = n;
		swallow((eastl::uninitialized_fill_ptr(TupleVecLeaf<Indices, Ts>::mpData, TupleVecLeaf<Indices, Ts>::mpData + n, args), 0)...);
	}

	void DoInitDefaultFill(size_type n)
	{
		DoConditionalReallocate(0, mNumCapacity, n);
		mNumElements = n;
		swallow((eastl::uninitialized_default_fill_n(TupleVecLeaf<Indices, Ts>::mpData, n), 0)...);
	}

	void DoInitFromTupleArray(const value_tuple* first, const value_tuple* last)
	{
#if EASTL_ASSERT_ENABLED
		if (EASTL_UNLIKELY(first > last || first == nullptr || last == nullptr))
			EASTL_FAIL_MSG("tuple_vector::ctor from tuple array -- invalid ptrs");
#endif
		size_type newNumElements = last - first;
		DoConditionalReallocate(0, mNumCapacity, newNumElements);
		mNumElements = newNumElements;
		DoUninitializedCopyFromTupleArray(begin(), end(), first);
	}

	void DoCopyFromTupleArray(iterator destPos, iterator destEnd, const value_tuple* srcTuple)
	{
		// assign to constructed region
		while (destPos < destEnd)
		{
			*destPos = *srcTuple;
			++destPos;
			++srcTuple;
		}
	}

	void DoUninitializedCopyFromTupleArray(iterator destPos, iterator destEnd, const value_tuple* srcTuple)
	{
		// placement-new/copy-ctor to unconstructed regions
		while (destPos < destEnd)
		{
			swallow(::new(eastl::get<Indices>(destPos.MakePointer())) Ts(eastl::get<Indices>(*srcTuple))...);
			++destPos;
			++srcTuple;
		}
	}

	// Try to grow the size of the container "naturally" given the number of elements being used
	void DoGrow(size_type oldNumElements, size_type oldNumCapacity, size_type requiredCapacity)
	{
		if (requiredCapacity > oldNumCapacity)
			DoReallocate(oldNumElements, GetNewCapacity(requiredCapacity));
	}

	// Reallocate to the newCapacity (IFF it's actually larger, though)
	void DoConditionalReallocate(size_type oldNumElements, size_type oldNumCapacity, size_type requiredCapacity)
	{
		if (requiredCapacity > oldNumCapacity)
			DoReallocate(oldNumElements, requiredCapacity);
	}

	void DoReallocate(size_type oldNumElements, size_type requiredCapacity)
	{
		void* ppNewLeaf[sizeof...(Ts)];
		pair<void*, size_type> allocation = TupleRecurser<Ts...>::template DoAllocate<allocator_type, 0, index_sequence_type, Ts...>(
			*this, ppNewLeaf, requiredCapacity, 0);
		swallow((TupleVecLeaf<Indices, Ts>::DoUninitializedMoveAndDestruct(0, oldNumElements, (Ts*)ppNewLeaf[Indices]), 0)...);
		swallow(TupleVecLeaf<Indices, Ts>::mpData = (Ts*)ppNewLeaf[Indices]...);

		EASTLFree(get_allocator(), mpData, internalDataSize());
		mpData = allocation.first;
		mNumCapacity = requiredCapacity;
		internalDataSize() = allocation.second;
	}

	size_type GetNewCapacity(size_type oldNumCapacity)
	{
		return (oldNumCapacity > 0) ? (2 * oldNumCapacity) : 1;
	}
};

}  // namespace TupleVecInternal

// Move_iterator specialization for TupleVecIter.
// An rvalue reference of a move_iterator would normaly be "tuple<Ts...> &&" whereas
// what we actually want is "tuple<Ts&&...>". This specialization gives us that.
template <eastl_size_t... Indices, typename... Ts>
class move_iterator<TupleVecInternal::TupleVecIter<index_sequence<Indices...>, Ts...>>
{
public:
	typedef TupleVecInternal::TupleVecIter<index_sequence<Indices...>, Ts...> iterator_type;
												 // a wrapping iterator type.
	typedef iterator_traits<iterator_type> traits_type;
	typedef typename traits_type::iterator_category iterator_category;
	typedef typename traits_type::value_type value_type;
	typedef typename traits_type::difference_type difference_type;
	typedef typename traits_type::pointer pointer;
	typedef tuple<Ts&&...> reference;
	typedef move_iterator<iterator_type> this_type;

protected:
	iterator_type mIterator;

public:
	move_iterator() : mIterator() {}
	explicit move_iterator(iterator_type mi) : mIterator(mi) {}

	template <typename U>
	move_iterator(const move_iterator<U>& mi) : mIterator(mi.base()) {}

	iterator_type base() const { return mIterator; }
	reference operator*() const { return eastl::move(MakeReference()); }
	pointer operator->() const { return mIterator; }

	this_type& operator++() { ++mIterator; return *this; }
	this_type operator++(int) {
		this_type tempMoveIterator = *this;
		++mIterator;
		return tempMoveIterator;
	}

	this_type& operator--() { --mIterator; return *this; }
	this_type operator--(int)
	{
		this_type tempMoveIterator = *this;
		--mIterator;
		return tempMoveIterator;
	}

	this_type operator+(difference_type n) const { return move_iterator(mIterator + n); }
	this_type& operator+=(difference_type n)
	{
		mIterator += n;
		return *this;
	}

	this_type operator-(difference_type n) const { return move_iterator(mIterator - n); }
	this_type& operator-=(difference_type n)
	{
		mIterator -= n;
		return *this;
	}

	difference_type operator-(const this_type& rhs) const { return mIterator - rhs.mIterator; }
	bool operator<(const this_type& rhs) const { return mIterator < rhs.mIterator; }
	bool operator>(const this_type& rhs) const { return mIterator > rhs.mIterator; }
	bool operator>=(const this_type& rhs) const { return mIterator >= rhs.mIterator; }
	bool operator<=(const this_type& rhs) const { return mIterator <= rhs.mIterator; }

	reference operator[](difference_type n) const { return *(*this + n); }

private:
	reference MakeReference() const
	{
		return reference(eastl::move(((Ts*)mIterator.mpData[Indices])[mIterator.mIndex])...);
	}

	// Unwrapping interface, not part of the public API.
	iterator_type unwrap() const { return mIterator; }

	// The unwrapper helpers need access to unwrap().
	friend is_iterator_wrapper_helper<this_type, true>;
	friend is_iterator_wrapper<this_type>;
};

template <typename AllocatorA, typename AllocatorB, typename Indices, typename... Ts>
inline bool operator==(const TupleVecInternal::TupleVecImpl<AllocatorA, Indices, Ts...>& a,
					   const TupleVecInternal::TupleVecImpl<AllocatorB, Indices, Ts...>& b)
{
	return ((a.size() == b.size()) && eastl::equal(a.begin(), a.end(), b.begin()));
}

template <typename AllocatorA, typename AllocatorB, typename Indices, typename... Ts>
inline bool operator!=(const TupleVecInternal::TupleVecImpl<AllocatorA, Indices, Ts...>& a,
					   const TupleVecInternal::TupleVecImpl<AllocatorB, Indices, Ts...>& b)
{
	return ((a.size() != b.size()) || !eastl::equal(a.begin(), a.end(), b.begin()));
}

template <typename AllocatorA, typename AllocatorB, typename Indices, typename... Ts>
inline bool operator<(const TupleVecInternal::TupleVecImpl<AllocatorA, Indices, Ts...>& a,
					  const TupleVecInternal::TupleVecImpl<AllocatorB, Indices, Ts...>& b)
{
	return eastl::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
}

template <typename AllocatorA, typename AllocatorB, typename Indices, typename... Ts>
inline bool operator>(const TupleVecInternal::TupleVecImpl<AllocatorA, Indices, Ts...>& a,
					  const TupleVecInternal::TupleVecImpl<AllocatorB, Indices, Ts...>& b)
{
	return b < a;
}

template <typename AllocatorA, typename AllocatorB, typename Indices, typename... Ts>
inline bool operator<=(const TupleVecInternal::TupleVecImpl<AllocatorA, Indices, Ts...>& a,
					   const TupleVecInternal::TupleVecImpl<AllocatorB, Indices, Ts...>& b)
{
	return !(b < a);
}

template <typename AllocatorA, typename AllocatorB, typename Indices, typename... Ts>
inline bool operator>=(const TupleVecInternal::TupleVecImpl<AllocatorA, Indices, Ts...>& a,
					   const TupleVecInternal::TupleVecImpl<AllocatorB, Indices, Ts...>& b)
{
	return !(a < b);
}

template <typename AllocatorA, typename AllocatorB, typename Indices, typename... Ts>
inline void swap(TupleVecInternal::TupleVecImpl<AllocatorA, Indices, Ts...>& a,
				TupleVecInternal::TupleVecImpl<AllocatorB, Indices, Ts...>& b)
{
	a.swap(b);
}

// A customization of swap is made for r-values of tuples-of-references -
// normally, swapping rvalues doesn't make sense, but in this case, we do want to
// swap the contents of what the tuple-of-references are referring to
//
// This is required due to TupleVecIter returning a value-type for its dereferencing,
// as opposed to an actual real reference of some sort
template<typename... Ts>
inline
typename enable_if<conjunction<is_swappable<Ts>...>::value>::type
swap(tuple<Ts&...>&& a, tuple<Ts&...>&& b)
{
	a.swap(b);
}

template<typename... Ts>
inline
typename enable_if<!conjunction<is_swappable<Ts>...>::value>::type
swap(tuple<Ts&...>&& a, tuple<Ts&...>&& b) = delete;

// External interface of tuple_vector
template <typename... Ts>
class tuple_vector : public TupleVecInternal::TupleVecImpl<EASTLAllocatorType, make_index_sequence<sizeof...(Ts)>, Ts...>
{
	typedef tuple_vector<Ts...> this_type;
	typedef TupleVecInternal::TupleVecImpl<EASTLAllocatorType, make_index_sequence<sizeof...(Ts)>, Ts...> base_type;
	using base_type::base_type;

public:
	this_type& operator=(std::initializer_list<typename base_type::value_tuple> iList)
	{
		base_type::operator=(iList);
		return *this;
	}
};

// Variant of tuple_vector that allows a user-defined allocator type (can't mix default template params with variadics)
template <typename AllocatorType, typename... Ts>
class tuple_vector_alloc
	: public TupleVecInternal::TupleVecImpl<AllocatorType, make_index_sequence<sizeof...(Ts)>, Ts...>
{
	typedef tuple_vector_alloc<AllocatorType, Ts...> this_type;
	typedef TupleVecInternal::TupleVecImpl<AllocatorType, make_index_sequence<sizeof...(Ts)>, Ts...> base_type;
	using base_type::base_type;

public:

	this_type& operator=(std::initializer_list<typename base_type::value_tuple> iList)
	{
		base_type::operator=(iList);
		return *this;
	}
};

}  // namespace eastl

EA_RESTORE_VC_WARNING()
EA_RESTORE_VC_WARNING()
EA_RESTORE_VC_WARNING()
EA_RESTORE_VC_WARNING()

#endif  // EASTL_TUPLEVECTOR_H


text:
Why Akula
Kavitha Akula
Toki Olowo
Shirin Rahmani
Daniele Volfe
Katrina D. Moore
Monique Ndaya Mutombo
Anita Gandavadi
Christie Sourivong
Clare Vega
Inella Coleman
Niku Karki
Yezenia Jimenez
Employment-Based Visas
J Visas
Labor Condition Application
O Visas, P Visas
R-Visas
TN/TD
K-1 Visas
Legal Permanent Resident
Immigration Links
Decades of Experience in Immigration Law.
F-1 Student Alert for Students at University of Farmington, MI
Posted By Akula & Associates P.C.
The University of Farmington ("Farmington") was set up by DHS, set up to entice students who were looking for employment authorization with Curricular Practical Training (CPT) from day one, even though no classroom attendance was required for enrolling at the University. DHS alleges that students who had obtained employment authorization had, in fact, never enrolled in or attended any classes physically and should have known that this arrangement was in violation of U.S. immigration laws and regulations.
Based on information obtained so far, all the students' Student and Exchange Visitor Information System (SEVIS) records were terminated by the DHS on or about January 28, 2019. The basis for this termination of SEVIS records was the belief that the University's students willfully violated their F-1 status. Therefore, all such students with terminated SEVIS records are subject to removal (also referred to as deportation) from the U.S. Any CPT authorization issued by a school that was set up by the government to entrap students is not valid. In addition, it is believed that the SEVIS records for all students previously enrolled at Farmington have already been terminated, which leaves all such students of this University, without valid status in the U.S.
From some information acquired by our Firm it looks like the students were notified about the fake university around 15 days back and gave them an opportunity to leave. It now appears that those students who did not depart the U.S. became subject to detention.
We expect that each student will receive a Notice to Appear (NTA), which is the charging document for removal proceedings in immigration court. Students subject to detention by ICE are expected to be released after the issuance of their NTAs and posting their bond with the respective immigration courts with jurisdiction over their cases. Law requires that the government must indicate the place and the date for the first master calendar hearing on the NTA. Those NTAs that do not contain this information can and should be challenged with the immigration court as improperly issued and invalid. You should discuss this strategy with your immigration counsel.
Those F-1 students who were enrolled at the University and have not yet been apprehended in the first several days after the shutdown of the University, should expect to be detained and served with NTAs at a later date. Those whom the government is unable or unwilling to apprehend may be served by mail with NTAs delivered to last known addresses.
Those students neither detained nor served with NTAs immediately following the shutdown nonetheless should expect difficulty when they attempt to change or adjust status, transfer to other schools, and/or apply for visas at U.S. consulates abroad, as explained below.
If the student is detained by ICE, they are subject to U.S. Immigration court proceedings. The proceedings give the student an opportunity to defend her/himself before an immigration judge. If a person departs after the NTA is issued, without Voluntary departure granted by the court, that individual will be subject to a minimum 5-year bar to reenter the U.S.
On the other hand, if a student leaves the U.S. before an NTA is issued, s/he is no longer within the jurisdiction of the immigration court. It is advisable in this case to have someone check the student's mail and, if the NTA was issued by mail in the name of a student who already has departed the U.S., the departure should be communicated to the immigration court and the Immigration and Customs Enforcement (ICE) to terminate the removal proceedings.
Based on the Unlawful Presence Memo, the DHS is likely to argue that these students started accruing unlawful presence as far back as August 9, 2018, on the date that the memo was issued. Those students who do not depart the U.S. prior to February 5, 2019, which is the 180-day mark from August 9, 2018, likely will be subject to a 3 or 10-year bar. A departure after the issuance of the NTA will result in a 5-year bar. In the event that the government makes a finding of fraud against all or some of these students, they potentially could be subject to a permanent bar on admission to the U.S.
Please see the link for CPT/OPT requirements https://www.ice.gov/sevis/practical-training.
Which Employment Visa is Right for Me?
USCIS Announces Implementation of Electronic H-1B Registration Process
What is a K-1 Fiance(e) Visa?
Filing DACA Applications in the Wake of Federal Court Rulings
USCIS Implements $10 Fee for H-1B Registration
Akula & Associates P.C.- Dallas Immigration Lawyer
17400 Dallas Parkway, Suite 216,
Dallas, TX 75287 View Map
Website: https://www.akulalaw.com/
Global Business & Family Immigration Lawyers (844) 299-5003

redpajama_set_name: RedPajamaCommonCrawl


Rajan Samuel, Habitat for Humanity wins Asia Innovator of the Year Award!
Aid & International Development Forum is delighted to announce the winner of the Innovator of the Year Award 2018 at the AIDF Asia Summit taking place on 20-21 June 2018 in Bangkok, Thailand.
The Asia Innovator of the Year Award 2018 celebrates individuals as well as teams who have introduced game-changing initiatives, created research or inventions that have made an impact on the humanitarian aid and development sectors in Asia over the past year.
The nominees were judged on their inspiring innovation, proven impact and success. Nominees were also expected to exhibit a thoughtful, creative and innovative approach to resolving humanitarian and development challenges in Asia over the past year.
A shortlist of 10 was released earlier this month.
The winner, Rajan Samuel, Habitat for Humanity, was chosen because of his commitment to spearhead the design and implementation of several creative and impactful projects aimed at improving the living conditions of millions of the most vulnerable families in India.
Through his leadership, Habitat India inspires partners in government, the private sector and civil society to volunteer, donate, invest and advocate for decent, affordable housing, for access to clean water and for better hygiene and sanitation practices. Through Rajan's able leadership, Habitat for Humanity India serves as a voice for people in need of decent housing by working to change laws and shape policies that affect access to housing.
Adequate and affordable housing not only improves outcomes for individuals, but affects communities and the global economy at large. Rajan and Habitat India is instrumental in operationalising Habitat's global advocacy for smart systems and policies that improve access to decent and affordable shelter on the ground. Indeed, Habitat for Humanity's interventions in India contributes not only to India's but to the Asia-Pacific region's progress towards achieving sustainable development.
Rajan's work with Habitat India is contributing primarily to Goal 11: Sustainable Cities and Communities—in particular target 11.1 to ensure access for all to adequate, safe and affordable housing and basic services, and upgrade slums and Goal 6: Water and Sanitation. With housing's role as an integrating factor for most of the SDGs, Rajan and Habitat India is also contributing towards Goal 1: No Poverty, Goal 5: Gender Equity, and Goal 7: Energy.
Find out more about the AIDF Asia Summit here.
Nominations are now open for our Global Innovator of the Year Award, you can nominate someone here. The winner of the Global Innovator of the Year Award will be announced at the 10th anniversary AIDF Global Summit.


text:
Q: table sorter not working for date format with time zone my html table column has a date formatted in ( MMM dd HH:mm:ss z yyyy ) which looks like  ( Jan 25 04:31:59 IST 2020 ) . once we add timezone sorting is not working as expected . it's sorting by alphabetical order after adding timezone .
It works well we remove timezone .
  $("#mediaTable").tablesorter({headers: {
     4 : {sorter: false},
     1 : {sorter: "shortDate",dateFormat:'MMM dd HH:mm:ss z yyyy'}},
  });

I have tried below combinations
1 : {sorter: true ,dateFormat:'MMM dd HH:mm:ss z yyyy'}
1 : {sorter: "longDate" ,dateFormat:'MMM dd HH:mm:ss z yyyy'}
1 : {sorter: "usLongDate" ,dateFormat:'MMM dd HH:mm:ss z yyyy'}

A: Answer available in github.com/Mottie/tablesorter/issues/1728

redpajama_set_name: RedPajamaStackExchange


Maquis (French) or macchia (Italian: macchia mediterranea) is a shrubland biome in the Mediterranean region, typically consisting of densely growing evergreen shrubs. Macchia also means spot in Italian. A perfect segue to Gerard Manley Hopkins' lovely poem Pied Beauty.
According to a website with compilations of historical weather reports, it was actually rather cold in Istria in June 1920. Well, looks like the temperature is about to drop in the Goldenbird timeline, too.
I saw Anna Magnani make Falco's gesture in a film, so it can't be that bad? Old Italian films are a treasure trove of interesting body language.
I don't know why Mayann is so savvy about nautical terms. Cf. previously revealed pirate obsession.


Success is rarely coincidental. The companies that enjoy large ROIs are usually the companies that have developed well thought out strategies for every stage and every process. They have toiled over the designs of their products, can tell you a hundred reasons why their product is superior to that of their competitors, and know buyer personas as well as they know their best friends.
One of the most distinctive traits of a successful company can be found in its marketing funnel. Every company's funnel looks different. Prosperous companies have funnels that are closer to the shapes of cylinders, while under-prepared companies are thinner and leaking leads all throughout because they are ill-equipped to nurture them. You can determine what your marketing funnel is saying about your company by analyzing the number of leads you have in each stage of the funnel. You can learn where it's strong and where it needs improvements.
However, funnels are so much more complicated than that. If you believe that your work is done at the purchasing stage, you're missing out on opportunities to compound your success and really amplify your brand.
To reach out to your target audience and show them that you have a solution to their problem.
Your top of the funnel is wide and acquiring many qualified leads. Companies successful in the Awareness Stage have a strong social media presence and are able to get people reading blog posts and watching viral videos about their products. You will see high levels of traffic, downloads, likes, shares, views, and click-throughs. When done well, there will be enough to drive leads to the Evaluation Stage.
Your top of the funnel is small, or you are acquiring weak leads who aren't interested in your product and can't be encouraged to buy. You are not only receiving low traffic, but people aren't watching your full videos, reading your full blog posts, and aren't interacting with your content.
Create content that makes people curious about your brand without selling to them. People on social media are looking for entertainment, not a sales pitch. If you can construct a creative, informative blog or an intriguing video that stops people from scrolling through their news feed, you have got your first foot in the door.
Expedia's Out There Starts Here blog is an excellent example of the kind of content that will attract leads. While Expedia is known for selling flights, hotels, and other accommodations, their blog is full of guides, tips, and inspiring images of the many destinations you can visit when booking your next vacation. Each post incentivizes readers to plan their next getaway, complete with sights to see, places to stay, and where to eat. After a lead is drawn in by posts such as their Luxury Guide to Queenstown, they don't even have to leave Expedia's site to start booking their next vacation.
To prove to leads that your product can solve their problem better than your competitor's.
Your leads have a wide variety of information about your product and company that they can easily access, which encourages them to decide to buy from you. Among this is social proof that your product is worth buying, via user-generated content, case studies, and demonstrations among other forms of content. All of this leads to a large number of leads continuing onto the Purchasing Stage.
The middle of your funnel will go from wide to thin. Either your company is trying to push leads through to the Evaluation Stage before they are ready, or lack the information that leads need to feel comfortable with continuing their buyer's journey. If you aren't there to help them along their way, your company will atrophy in this stage.
Create an easy-to-find FAQ section and how-to blog to address the most common concerns, and make yourself readily available to answer any questions to make potential customers feel comfortable and confident about your product. Also, provide a wealth of content that shows why your product is right for them—including case studies and white papers.
According to Angie Mansfield, the self-proclaimed "case study and white paper geek," case studies are essentially customer success stories that give your prospects the experience of using your product before ever laying a hand on it. Meanwhile, white papers are ranked second in terms of the most influential content buyers can read before making a purchase. Her portfolio is full of excellent examples of both covering a wide variety of niches.
To guide the lead to buy your product.
Your company will enjoy a high number of converted customers, and your Evaluation and Purchase Stages will resemble a cylinder more than it does a funnel. A combination of easy-to-find web pages and purchase pages, testimonials, reviews, and offers have convinced your leads that your product is a must-have.
Your company is failing to recognize that your potential leads still need a little more coaxing before buying from you. They may be suspicious by a lack of positive reviews or testimonials, and if you aren't offering them any special promotion or discount to make up for it, they may be led astray. Also, if your website is poorly designed with too many graphics, slow load screens, and confusing toolbars, they may not be able to navigate your page.
Think about what would entice you to hit the 'buy' button. Chances are, your leads are in the same boat. Have the necessary social proof needed to make your leads feel comfortable with the final stage of their buyer's journey, and provide special offers to sweeten the deal. Also, have a simple, easy-to-navigate website like Big Apple Hot Dogs or Anet Design.
You have around a 5% chance to sell something to a new customer, but a 60%-70% chance to sell something to a repeat customer. As a result, 65% or more of an average small business' revenue comes from existing customers.
Customers that trust your content don't have to go through the Awareness and Evaluation stages with them. They already know that your product is great and was convinced by the content you have shown them to buy! Smart e-mail marketing, such as campaigns that the Inn at Seaside has conducted, can drive repeat business by offering timely specials, attract design, and customer raves.
Catering to happy customers saves you money on marketing material and shortens long sales cycles. If your company doesn't have a strategy in place to encourage customers to become repeat purchasers, you are missing on a significant opportunity.
Take a minute to analyze the strengths and weaknesses of your marketing funnel. Chances are that the improvements you need to make have simpler solutions than you think.


text:
Q: How to pack APIs into JARs I have a GUI program that returns CPU values, this requires a external API. I have the JAR made, but the program will not return the CPU unless I run the program within netbeans IDE. My question is how can I pack APIs into a JAR file.
private class getCpu extends Thread {
        @Override
        public void run() {
            while(true) {
                try {
                Sigar sigar = new Sigar();
                Cpu cpu = new Cpu();
                CpuPerc perc = sigar.getCpuPerc();

                DecimalFormat df = new DecimalFormat("###.###");
                //df.format(100-(perc.getIdle()*100));
                cpuLabel.setText("CPU : "+df.format(100-(perc.getIdle()*100))+"%");

                try{Thread.sleep(1000);}catch(Exception e2){}
                }catch(SigarException e1){}
                catch(Exception e){}
            }
        }
    }

A: Your program isn't working because you have no "external API"  in your classpath when you run the program from command line (and you got ClassDefNotFoundException)
To solve this problem you can do one of:

*

*add the external API jar to classpath:
java -cp externalAPI.jar -jar jourProgram.jar

*pack all necessary classes into your jar. There is a good maven plugin it can take all your dependencies and pack into a single jar file - https://maven.apache.org/plugins/maven-assembly-plugin/

A: When using sigar's API you must add the log4j.jar and sigar.jar to your class-path. But also you need to add sigar-amd64-winnt.dll, sigar-x86-winnt.dll, and sigar-x86-winnt.lib to the final folder with the final build otherwise Sigar will not work properly.


text:
Home » Scenari politico economici » The Belt and the Road Initiative's opportunity for Italian future.
The Belt and the Road Initiative's opportunity for Italian future.
da Redazione | 9 Apr 2019 | Scenari politico economici
The partnership between Italy and China is built on sound roots,
inspired by natural convergences between two ancient civilizations.
These relations are constantly enriched with new areas of cooperation.
Italy and China are two great bearers of ancient civilizations, whose
artistic heritage arouses admiration throughout the world.
They share a millennial history, marked by a lively intertwining of art,
literature, music, trade, high craftsmanship, since ancient times. This
historical cultural affinity between the two civilizations is a precious
asset, which has reached our days.
The two countries represent, for each other, a great driving force for
development that can be put to good use through the promotion, and
enhancement, also of the respective cultural and creative industries.
These dynamics must be facilitated to realize their enormous potential.
The Belt and the Road Initiative will be an opportunity not only from
China in Europe, but from Europe and from Italy to China. It is, indeed,
a great infrastructure that we will have to use to better connect to the
Asian market through agreements that are advantageous for both parties.
The Italian participation in the creation of the so-called "New Silk
Road" therefore assumes significance, and importance, on the economical
level and above all on the cultural level and on that of relations
between people, through cultural projects, ideas, exchange of knowledge,
new travel, scientific and technological opportunities. For a long time,
Italy has seen in China not only its own economic partner of the highest
level, but also driving force of the world economy and trade.
Italy has to focus on the sectors in which it has excellent experiences,
in terms of advanced technologies and solutions. From energy,
environmental protection, sustainable urbanization, mechanics, food
security, health services, fashion, design. The Italian way of life,
with its leading products, attracts attention in all countries, affected
by a growing increase in living standards.
The intensification of economic relations have to pass through the
creation of a context that is as open and transparent as possible; in
which the economic actors of the two countries can act in an equivalent
manner, mutually free and balanced, with the removal of barriers, which
still stand in the way of trade flows: promoting access to the
respective markets, protecting in particular the security of investments
and intellectual property, opening to foreign companies of Chinese
public tenders.


text:
#S02E08 - Quantum Leap: How Quantum Computers Could Solve The World's Biggest Problems
From weather forecasting to artificial intelligence, chemical engineering, and drug design, quantum computers have the potential to completely change the way we think about solving complex problems. But how far away are we from seeing quantum computers used to tackle the world's biggest problems?
An Interview with Jaunt Motors CEO Dave Budge
There are all kinds of new electric cars making their way onto the market. Whether it's a passenger car, or even a truck, you can probably find an EV that suits your lifestyle. But what if you're someone who loves classic cars? It turns out, there might be a perfect vehicle for you.
Sky Lanes
Autonomous drone delivery has the potential to change the way businesses operate. In this episode of Moonshot, we speak with Hannan Parvizian the CEO of Volansi, a Bay Area company building long-range drones for B2B deliveries.
They Go Up So Fast
The commercial space race is heating up. Whether it's big rockets, or small, there's been significant progress achieved by many companies across the sector. In this episode of Moonshot, we update two space stories to see how far the companies we featured have come.
Moonshot is proudly sponsored by Nexo - Hyundai's next generation range of fuel cell electric vehicles. Find out more at https://hyundai.com/au/nexo.
Lawson Media created amazing narrative podcasts for editorial and brands.
© Lawson Media Pty Ltd. ABN: 17 627 544 950


text:
Disporella buskiana är en mossdjursart som först beskrevs av Ferdinand Canu och Ray Smith Bassler 1928.  Disporella buskiana ingår i släktet Disporella och familjen Lichenoporidae. Inga underarter finns listade i Catalogue of Life.

Källor

Mossdjur
buskiana

redpajama_set_name: RedPajamaWikipedia


May 4, 2016 prompt: In 99 words (no more, no less) include insects in a story. Periwinkles, bees laden with pollen, ants building hills. What can insects add to a story? Do they foreshadow, set a tone, provide a scientific point of interest or a mystical element? Let you inner periwinkles fly!
As I've mentioned before, my childhood was filled with insects.
Dad, a country man to his fingertips, loved all that nature had to offer – pond life and the mysteries of birds, earth's ability to regenerate and restore itself despite man's clumsy attempts to destroy it. But he was at his happiest seeking out butterflies and moths – beetles, too, and dragonflies but lepidoptera – butterflies and moths – were what got him really excited.
Have you ever been on a butterfly egg hunt? Beaten sallows to see what falls on a sheet?
Spent frosty afternoons kneeling by the roots of poplars, pulling back turf in the hope of finding pupae? Believe me, you haven't lived. I learnt the importance of taking care – these are delicate structures; the need for keen eyed recognition; for patience and disappointment – though it wasn't often we were disappointed because there's so much going on at the level of the tiny and delicate that a failure to find what we set out for only meant there was the possibility of the unexpected. And even if we were completely unsuccessful, well that only meant the anticipation for next time was heightened – sort of a rollover for our particular lottery.
One especially joy, for Dad (and the Archaeologist too, as I'm sure he will comment upon), was to read a book, maybe from the Victoria era, maybe from the 1930s describing a 'bug hunt' and replicating it, to see if we could find what the ancients found. There was something deliciously timeless about that connection down the years, the idea we were at one with that distant group, sharing the same thrill that they had.
Wading into the dykes at Grove Ferry in Kent to hunt for small holes in the stems of bull-rushes where the larvae of the china mark moths live followed one such piece of research.
Of course, as with bird nesting, the aim was to create a collection. The breeding that followed the discoveries of eggs and larvae and pupae had a single purpose back then. To bring the butterfly or moth through to its final state, the imago, and kill it – we all had lidded jam jars filled to a third with plaster of Paris soaked in ethyl acetate – that sickly sweet stuff they use in dry cleaners. Killed, they would be set out on a board with pins and paper strips until rigid and then put in a glass case to admire. That death follows life thing seemed entirely normal back then though as species declines became more and more apparent into the 80s Dad's focus changed to breeding and releasing to improve stocks.
You could learn a lot spending time with a naturalist like Dad – about beer and poetry too. I'm glad I can still recall those long passed days when it was always sunny, even when it rained.
As so to the prompt, Mary is still coming to terms with her half brother Rupert moving so close by.
She was delayed and hadn't brought her phone. In the kitchen she found a scribbled note on the fridge said 'hospital' with Rupert's number. There were 8 missed calls on her phone.
Mary sat in traffic her mind a jumble. If she was going to have a guardian angel, why him?
This entry was posted in flash fiction, miscellany, writing and tagged carrot ranch, Charli Mill's prompt, flash fiction, insects. Bookmark the permalink.
Bee stings. I've had my share but never had to go to hospital.
At least there are epi pens now. Fifty and sixty years plus ago, not so.
What a lovely stroll down memory lane, Geoff. I love the pictures. What wonderful memories to have.
Oh no… not a bee sting. I'm allergic that way… LOL this just became a scary story. 😀 Huge hugs!
Loved the story, and…guess what? I spent a lot of my childhood hunting butterflies; at one time I could name every British one (species, that is. Obviously not each individual…that would be silly…) and even made my own butterfly tents for breeding and releasing them.
Rupert is definitely worming his way in to Mary's life, whether she wants it or not. I thought of your Dad when those Periwinkles exploded around me. I became instantly curious about why they were attracted to the sand and how they were dull underneath and brilliant with open wings. I was not one for seeking insects as a child, but seems I'm more curious as an adult. I always enjoy your stories about your childhood bug hunting.
I want to know why Mary does not approve of this Rupert. I want to know how he manages to succeed, or if he even does in watching over her. There is an event brewing. I am also curious as to why Mary seems to loathe him even tho he helped Charlotte this day. My guess is he is slow or something, considering he had to make it a point he recognized the 'signs'. It takes a patient spirit to handle someone like I am imaging Rupert. I will have to follow the link to learn of these characters.
I will have to read it… I am lost and just wants to ask questions. Who has a twin? ok just one.
Is your name really Geoff LePard? I first saw that and thought you made it up like Def Lepard.. Anyways, my media-fed head. That sounds like an intriguing story; mmm do i dare get caught in its web? Thanks!
The chapters are 99 words so at least they take no time. The twin us Mary's. Geoff Le Pard is indeed my given name and the band have given me no credit or royalty share which is just mean. Hope you come along for the ride.
Thats hilarious. Flippin rock stars… ok im in!
So that's what went for entertainment back then, haha! Joking aside, it's a shame more young people aren't so connected with nature. Shame about killing them, though. Thats the part I don't understand. Why does a butterfly or dragonfly look better dead under glass then shimmying it's gorgeous wings as it flies from blossom to blossom? I'd rather see them alive and free, personally.
🐝🐝🐝 Bee careful. (Now the question becomes whether or not I'll actually press 'post comment'.) Eh. What the hell. 🐝 Zzzzz!
Great memoir, great photos. Mary was just lucky she had a guardian angel. Bee stings allergies are not pleasant.
I love reading of your butterfly adventures. Though I must admit I was rather perturbed to hear of the butterflies' fate, I was relieved when Father took to breeding and releasing them.
This is a wonderful episode in Mary's story. How wonderful that Rupert has moved close by and was able to help out in this emergency. It's not fun being allergic to bee stings, or any other stings for that matter. I hope Mary is softening a little towards Rupert. The children are not accountable for their father's deeds after all.
no, that last is so true but it is easy to know and not so easy to accept sometimes..
The butterflies have just started to appear for the season in my neck of the woods, which makes me infinitely happy. Moths are out too, which makes the birds ecstatic (when they can catch one!). It seems like everyone in my family is allergic to bees, so I know that "she's been stung" fear all too well. I'm look forward to reading more about Mary and Rupert.