// xlocinfo internal header for Microsoft
#pragma once
#ifndef _XLOCINFO_
#define _XLOCINFO_
#include <xlocinfo.h>
#include <cstdlib>
#include <xstddef>

#pragma pack(push,8)
#pragma warning(push,3)
_STD_BEGIN

		// CLASS _Timevec
class _CRTIMP2 _Timevec
	{	// smart pointer to information used by _Strftime
public:
	_Timevec(void *_Ptr = 0)
		: _Timeptr(_Ptr)
		{	// construct from ptr
		}

	_Timevec(const _Timevec& _Right)
		{	// construct from _Right
		*this = _Right;
		}

	~_Timevec()
		{	// destroy the object
		free(_Timeptr);
		}

	_Timevec& operator=(const _Timevec& _Right)
		{	// transfer ownership of _Timeptr from _Right
		_Timeptr = _Right._Timeptr;
		((_Timevec *)&_Right)->_Timeptr = 0;
		return (*this);
		}

	void *_Getptr() const
		{	// return pointer to time information
		return (_Timeptr);
		}

private:
	void *_Timeptr;	// pointer to time information
	};

		// CLASS _Locinfo
class _CRTIMP2 _Locinfo
	{	// summary of all stuff peculiar to a locale used by standard facets
public:
	typedef ::_Collvec _Collvec;
	typedef ::_Ctypevec _Ctypevec;
	typedef ::_Cvtvec _Cvtvec;
	typedef std::_Timevec _Timevec;

	_Locinfo(const char * = "C");	// construct from named locale

	_Locinfo(int, const char *);	// construct from category

	~_Locinfo();	// destroy the object

	_Locinfo& _Addcats(int, const char *);	// add stuff for a category

	string _Getname() const
		{	// return the new locale name
		return (_Newlocname);
		}

	_Collvec _Getcoll() const
		{	// return collation stuff
		return (::_Getcoll());
		}

	_Ctypevec _Getctype() const
		{	// return ctype stuff
		return (::_Getctype());
		}

	_Cvtvec _Getcvt() const
		{	// return codecvt stuff
		return (::_Getcvt());
		}

	const lconv *_Getlconv() const
		{	// return localeconv stuff
		return (localeconv());
		}

	_Timevec _Gettnames() const
		{	// return names used by _Strftime
		return (_Timevec(::_Gettnames()));
		}

	const char *_Getdays() const
		{	// return names for weekdays
		const char *_Ptr = ::_Getdays();
		if (_Ptr != 0)
			{	// capture names and free allocated C string
			((_Locinfo *)this)->_Days = _Ptr;
			free((void *)_Ptr);
			}
		return (_Days.size() != 0 ? _Days.c_str()
			: ":Sun:Sunday:Mon:Monday:Tue:Tuesday:Wed:Wednesday"
				":Thu:Thursday:Fri:Friday:Sat:Saturday");
		}

	const char *_Getmonths() const
		{	// return names for months
		const char *_Ptr = ::_Getmonths();
		if (_Ptr != 0)
			{	// capture names and free allocated C string
			((_Locinfo *)this)->_Months = _Ptr;
			free((void *)_Ptr);
			}
		return (_Months.size() != 0 ? _Months.c_str()
			: ":Jan:January:Feb:February:Mar:March"
				":Apr:April:May:May:Jun:June"
				":Jul:July:Aug:August:Sep:September"
				":Oct:October:Nov:November:Dec:December");
		}

	const char *_Getfalse() const
		{	// return false name (no C source)
		return ("false");
		}

	const char *_Gettrue() const
		{	// return true name (no C source)
		return ("true");
		}

	int _Getdateorder() const
		{	// return date order
		return ::_Getdateorder();
		}

private:
	_Lockit _Lock;	// thread lock, because global locale is altered
	string _Days;	// weekday names
	string _Months;	// month names
	string _Oldlocname;	// old locale name to revert to on destruction
	string _Newlocname;	// new locale name for this object
	};

		// TEMPLATE FUNCTION _LStrcoll
template<class _Elem> inline
	int __cdecl _LStrcoll(const _Elem *_First1, const _Elem *_Last1,
		const _Elem *_First2, const _Elem *_Last2,
			const _Locinfo::_Collvec *)
	{	// perform locale-specific comparison of _Elem sequences
	for (; _First1 != _Last1 && _First2 != _Last2; ++_First1, ++_First2)
		if (*_First1 < *_First2)
			return (-1);	// [_First1, _Last1) < [_First2, _Last2)
		else if (*_First2 < *_First1)
			return (+1);	// [_First1, _Last1) > [_First2, _Last2)
	return (_First2 != _Last2 ? -1 : _First1 != _Last1 ? +1 : 0);
	}

template<> inline
	int __cdecl _LStrcoll(const char *_First1, const char *_Last1,
		const char *_First2, const char *_Last2,
			const _Locinfo::_Collvec *_Vector)
	{	// perform locale-specific comparison of char sequences
	return (_Strcoll(_First1, _Last1, _First2, _Last2, _Vector));
	}

template<> inline
	int __cdecl _LStrcoll(const wchar_t *_First1, const wchar_t *_Last1,
		const wchar_t *_First2, const wchar_t *_Last2,
			const _Locinfo::_Collvec *_Vector)
	{	// perform locale-specific comparison of wchar_t sequences
	return (_Wcscoll(_First1, _Last1, _First2, _Last2, _Vector));
	}

		// TEMPLATE FUNCTION _LStrxfrm
template<class _Elem> inline
	size_t __cdecl _LStrxfrm(_Elem *_First1, _Elem *_Last1,
		const _Elem *_First2, const _Elem *_Last2,
			const _Locinfo::_Collvec *)
	{	// perform locale-specific transform of _Elems [_First1, _Last1)
	size_t _Count = _Last2 - _First2;
	if (_Count <= (size_t)(_Last1 - _First1))
		memcpy(_First1, _First2, _Count * sizeof (_Elem));
	return (_Count);
	}

template<> inline
	size_t __cdecl _LStrxfrm(char *_First1, char *_Last1,
		const char *_First2, const char *_Last2,
			const _Locinfo::_Collvec *_Vector)
	{	// perform locale-specific transform of chars [_First1, _Last1)
	return (_Strxfrm(_First1, _Last1, _First2, _Last2, _Vector));
	}

template<> inline
	size_t __cdecl _LStrxfrm(wchar_t *_First1, wchar_t *_Last1,
		const wchar_t *_First2, const wchar_t *_Last2,
			const _Locinfo::_Collvec *_Vector)
	{	// perform locale-specific transform of wchar_ts [_First1, _Last1)
	return (_Wcsxfrm(_First1, _Last1, _First2, _Last2, _Vector));
	}
_STD_END
#pragma warning(pop)
#pragma pack(pop)

#endif /* _XLOCINFO_ */

/*
 * Copyright (c) 1992-2002 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
 V3.13:0009 */
