Mercurial > ecos
changeset 2916:64b424f9dc4a
* include/*.h: Move all headers to include/ustl/ except ustl.h and
stdint.h to avoid pollution of the root include directory in the
eCos install tree.
* include/ustl.h: Specify ustl/ directory when including header files.
* cdl/ustl.h: Add include/ustl/ to the header file directory list
using CYGPKG_USTL_CFLAGS_ADD.
line wrap: on
line diff
--- a/packages/language/cxx/ustl/current/ChangeLog +++ b/packages/language/cxx/ustl/current/ChangeLog @@ -1,3 +1,12 @@ +2009-08-30 John Dallaway <john@dallaway.org.uk> + + * include/*.h: Move all headers to include/ustl/ except ustl.h and + stdint.h to avoid pollution of the root include directory in the + eCos install tree. + * include/ustl.h: Specify ustl/ directory when including header files. + * cdl/ustl.h: Add include/ustl/ to the header file directory list + using CYGPKG_USTL_CFLAGS_ADD. + 2009-08-24 Uwe Kindler <uwe_kindler@web.de> * doc/ustl.sgml: Moved documentation from README file into
--- a/packages/language/cxx/ustl/current/cdl/ustl.cdl +++ b/packages/language/cxx/ustl/current/cdl/ustl.cdl @@ -165,7 +165,7 @@ cdl_package CYGPKG_USTL { display "Additional compiler flags" flavor data no_define - default_value { "" } + default_value { "-I$(PREFIX)/include/ustl" } description " This option modifies the set of compiler flags for building the uSTL library. These flags are used in addition
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/bktrace.h +++ /dev/null @@ -1,52 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2006-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef BKTRACE_H_63ABB1E4388CEDD975DBE58B57DE474F -#define BKTRACE_H_63ABB1E4388CEDD975DBE58B57DE474F - -#include "ulimits.h" -#include <stdlib.h> - -namespace ustl { - -class ostringstream; -class istream; -class ostream; - -/// \class CBacktrace bktrace.h ustl.h -/// -/// \brief Stores the backtrace from the point of construction. -/// -/// The backtrace, or callstack, is the listing of functions called to -/// reach the construction of this object. This is useful for debugging, -/// to print the location of an error. To get meaningful output you'll -/// need to use a debug build with symbols and with frame pointers. For -/// GNU ld you will also need to link with the -rdynamic option to see -/// actual function names instead of __gxx_personality0+0xF4800. -/// -class CBacktrace { -public: - CBacktrace (void) throw(); - CBacktrace (const CBacktrace& v) throw(); - inline ~CBacktrace (void) throw() { if (m_Symbols) free (m_Symbols); } - const CBacktrace& operator= (const CBacktrace& v) throw(); - void text_write (ostringstream& os) const; - void read (istream& is); - void write (ostream& os) const; - size_t stream_size (void) const; -private: - void GetSymbols (void) throw() DLL_LOCAL; -private: - void* m_Addresses [64]; ///< Addresses of each function on the stack. - char* m_Symbols; ///< Symbols corresponding to each address. - uint32_t m_nFrames; ///< Number of addresses in m_Addresses. - uint32_t m_SymbolsSize; ///< Size of m_Symbols. -}; - -} // namespace ustl - -ALIGNOF(ustl::CBacktrace, sizeof(void*)) - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/cmemlink.h +++ /dev/null @@ -1,103 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef CMEMLINK_H_7CFAB32C5C6732ED29B34EF00EA40A12 -#define CMEMLINK_H_7CFAB32C5C6732ED29B34EF00EA40A12 - -#include "ualgobase.h" -#include "config.h" - -/// The ustl namespace contains all ustl classes and algorithms. -namespace ustl { - -class istream; -class ostream; -class ostringstream; - -/// \class cmemlink cmemlink.h ustl.h -/// \ingroup MemoryManagement -/// -/// \brief A read-only pointer to a sized block of memory. -/// -/// Use this class the way you would a const pointer to an allocated unstructured block. -/// The pointer and block size are available through member functions and cast operator. -/// -/// Example usage: -/// -/// \code -/// void* p = malloc (46721); -/// cmemlink a, b; -/// a.link (p, 46721); -/// assert (a.size() == 46721)); -/// b = a; -/// assert (b.size() == 46721)); -/// assert (b.DataAt(34) == a.DataAt(34)); -/// assert (0 == memcmp (a, b, 12)); -/// \endcode -/// -class cmemlink { -public: - typedef char value_type; - typedef const value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type reference; - typedef value_type const_reference; - typedef size_t size_type; - typedef uint32_t written_size_type; - typedef ptrdiff_t difference_type; - typedef const_pointer const_iterator; - typedef const_iterator iterator; - typedef const cmemlink& rcself_t; -public: - inline cmemlink (void) : m_Data (NULL), m_Size (0) { } - inline cmemlink (const void* p, size_type n) : m_Data (const_pointer(p)), m_Size (n) { assert (p || !n); } - inline cmemlink (const cmemlink& l) : m_Data (l.m_Data), m_Size (l.m_Size) {} - inline virtual ~cmemlink (void) throw() {} - void link (const void* p, size_type n); - inline void link (const cmemlink& l) { link (l.begin(), l.size()); } - inline void link (const void* first, const void* last) { link (first, distance (first, last)); } - inline void relink (const void* p, size_type n); - virtual void unlink (void) throw(); - inline rcself_t operator= (const cmemlink& l) { link (l); return (*this); } - bool operator== (const cmemlink& l) const; - inline void swap (cmemlink& l) { ::ustl::swap (m_Data, l.m_Data); ::ustl::swap (m_Size, l.m_Size); } - inline size_type size (void) const { return (m_Size); } - inline size_type max_size (void) const { return (size()); } - inline size_type readable_size (void) const { return (size()); } - inline bool empty (void) const { return (!size()); } - inline const_pointer cdata (void) const { return (m_Data); } - inline iterator begin (void) const { return (iterator (cdata())); } - inline iterator iat (size_type i) const { assert (i <= size()); return (begin() + i); } - inline iterator end (void) const { return (iat (size())); } - inline void resize (size_type n) { m_Size = n; } - inline void read (istream&) { assert (!"ustl::cmemlink is a read-only object."); } - void write (ostream& os) const; - size_type stream_size (void) const; - void text_write (ostringstream& os) const; -#ifdef CYGCLS_USTL_FSTREAMS - void write_file (const char* filename, int mode = 0644) const; -#endif -private: - const_pointer m_Data; ///< Pointer to the data block (const) - size_type m_Size; ///< size of the data block -}; - -//---------------------------------------------------------------------- - -/// A fast alternative to link which can be used when relinking to the same block (i.e. when it is resized) -inline void cmemlink::relink (const void* p, size_type n) -{ - m_Data = reinterpret_cast<const_pointer>(p); - m_Size = n; -} - -//---------------------------------------------------------------------- - -/// Use with cmemlink-derived classes to link to a static array -#define static_link(v) link (VectorBlock(v)) - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/config.h +++ /dev/null @@ -1,389 +0,0 @@ -#ifndef CYGONCE_CONFIG_H -#define CYGONCE_CONFIG_H -// ========================================================================== -// -// config.h -// -// Manually constructed uSTL configuration file for eCos RTOS -// -// =========================================================================== -// ####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 2009 Free Software Foundation, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later -// version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License -// along with eCos; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// As a special exception, if other files instantiate templates or use -// macros or inline functions from this file, or you compile this file -// and link it with other works to produce a work based on this file, -// this file does not by itself cause the resulting work to be covered by -// the GNU General Public License. However the source code for this file -// must still be made available in accordance with section (3) of the GNU -// General Public License v2. -// -// This exception does not invalidate any other reasons why a work based -// on this file might be covered by the GNU General Public License. -// ------------------------------------------- -// ####ECOSGPLCOPYRIGHTEND#### -// =========================================================================== -// =========================================================================== -// #####DESCRIPTIONBEGIN#### -// -// Author(s): Uwe Kindler -// Contributors: -// Date: 2009-07-28 -// Purpose: eCos specific uSTL configuration -// Description: -// -// ####DESCRIPTIONEND#### -// -// ========================================================================*/ -#include <stdint.h> -#include <pkgconf/ustl.h> // ustl package configuration - - -// -// If there is no RTTI support (normally this is the default eCos setting) -// C++ typeid keyword is not supported. We hide this by using a macro instead -// of using typeid keyword directly. -// -#ifdef __GXX_RTTI - #define USTL_TYPENAME(_t_) typeid(_t_).name() -#else - #define USTL_TYPENAME(_t_) "unknown type (RTTI disabled)" -#endif - -// -// If there is no exception support (normally this is the default eCos setting) -// C++ keywords try, catch and throw are not supported. To compile uSTL without -// exception support we use macros USLT_TRY, USLT_CATCH_ALL and USLT_THROW -// instead of the real keywords. To handle exceptions in debug builds we define -// a "lightwight" exception handler. This handler is simply a function that -// prints exception information do diagnostic channel. -// -#ifdef __EXCEPTIONS - #define USTL_TRY try - #define USTL_CATCH_ALL catch (...) {} - #define USTL_THROW(_exception_) throw (_exception_) -#else - namespace ustl - { - class exception; - extern void exception_handler(const exception& ex); - } - #define USTL_TRY - #define USTL_CATCH_ALL - #define USTL_THROW(_exception_) ustl::exception_handler(_exception_) -#endif - -// -// There is no eCos header that exports this function so we do it here -// -#ifdef CYGCLS_USTL_FSTREAMS -__externC int ioctl( int fd, CYG_ADDRWORD com, ... ); -#endif - - -/// Define to 1 if you want stream operations to throw exceptions on -/// insufficient data or insufficient space. All these errors should -/// be preventable in output code; the input code should verify the -/// data in a separate step. It slows down stream operations a lot, -/// but it's your call. By default only debug builds throw. -/// -#ifdef CYGSEM_USTL_STREAM_BOUNDS_CHECK -#define WANT_STREAM_BOUNDS_CHECKING 1 -#else -#undef WANT_STREAM_BOUNDS_CHECKING -#endif - -#if !defined(WANT_STREAM_BOUNDS_CHECKING) && !defined(NDEBUG) - #define WANT_STREAM_BOUNDS_CHECKING 1 -#endif - -/// Define to 1 if you want backtrace symbols demangled. -/// This adds some 15k to the library size, and requires that you link it and -/// any executables you make with the -rdynamic flag (increasing library size -/// even more). By default this option is disable. Enabling this option also -/// pulls in __cxa_demangle from libsupc++ -#undef WANT_NAME_DEMANGLING - -/// Define to 1 if you want to build without libstdc++ -#define WITHOUT_LIBSTDCPP 1 - -/// Define GNU extensions if unavailable. -#ifndef __GNUC__ - /// GCC (and some other compilers) define '__attribute__'; ustl is using this - /// macro to alert the compiler to flag inconsistencies in printf/scanf-like - /// function calls. Just in case '__attribute__' is undefined, make a dummy. - /// - #ifndef __attribute__ - #define __attribute__(p) - #endif -#endif -#if defined(__GNUC__) && __GNUC__ >= 4 - #define INLINE __attribute__((always_inline)) -#else - #define INLINE -#endif -#define DLL_EXPORT -#define DLL_LOCAL -#if defined(__GNUC__) && __GNUC__ >= 3 && (__i386__ || __x86_64__) - /// GCC 3+ supports the prefetch directive, which some CPUs use to improve caching - #define prefetch(p,rw,loc) __builtin_prefetch(p,rw,loc) -#else - #define prefetch(p,rw,loc) -#endif -#if !defined(__GNUC__) || __GNUC__ < 3 - /// __alignof__ returns the recommended alignment for the type - #define __alignof__(v) min(sizeof(v), sizeof(void*)) - /// This macro returns 1 if the value of x is known at compile time. - #ifndef __builtin_constant_p - #define __builtin_constant_p(x) 0 - #endif -#endif - -// Define to 1 if you have the `atexit' function. -#define HAVE_ATEXIT 1 - -// Define to 1 if you have the <assert.h> header file. -#define HAVE_ASSERT_H 1 - -// Define to 1 if you have the <ctype.h> header file. -#define HAVE_CTYPE_H 1 - -// Define to 1 if you have the <errno.h> header file. -#define HAVE_ERRNO_H 1 - -// Define to 1 if you have the <fcntl.h> header file. -#define HAVE_FCNTL_H 1 - -// Define to 1 if you have the <float.h> header file. -#define HAVE_FLOAT_H 1 - -// Define to 1 if you have the <limits.h> header file. -#define HAVE_LIMITS_H 1 - -// Define to 1 if you have the <locale.h> header file. -#define HAVE_LOCALE_H 1 - -// Define to 1 if your system has a working `malloc' function. -#define HAVE_MALLOC 1 - -// Define to 1 if you have the `memchr' function. -#define HAVE_MEMCHR 1 - -// Define to 1 if you have the `memmove' function. -#define HAVE_MEMMOVE 1 - -// Define to 1 if you have the `memset' function. -#define HAVE_MEMSET 1 - -// Define to 1 if the system has the type `ptrdiff_t'. -#define HAVE_PTRDIFF_T 1 - -// Define to 1 if you have the <signal.h> header file. -#define HAVE_SIGNAL_H 1 - -// Define to 1 if you have the <stdarg.h> header file. -#define HAVE_STDARG_H 1 - -// Define to 1 if you have the <stddef.h> header file. -#define HAVE_STDDEF_H 1 - -// Define to 1 if you have the <stdint.h> header file. -#define HAVE_STDINT_H 1 - -// Define to 1 if you have the <stdio.h> header file. -#define HAVE_STDIO_H 1 - -// Define to 1 if you have the <stdlib.h> header file. -#define HAVE_STDLIB_H 1 - -// Define to 1 if you have the `strerror' function. -#define HAVE_STRERROR 1 - -// Define to 1 if you have the <string.h> header file. -#define HAVE_STRING_H 1 - -// Define to 1 if you have the `strrchr' function. -#define HAVE_STRRCHR 1 - -// Define to 1 if you have the `strtol' function. -#define HAVE_STRTOL 1 - -// Define to 1 if you have the <sys/stat.h> header file. -#define HAVE_SYS_STAT_H 1 - -// Define to 1 if you have the <sys/types.h> header file. -#define HAVE_SYS_TYPES_H 1 - -// Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. -#define HAVE_SYS_WAIT_H 1 - -// Define to 1 if you have the <time.h> header file. -#define HAVE_TIME_H 1 - -// Define to 1 if you have the <unistd.h> header file. -#define HAVE_UNISTD_H 1 - -// Define to 1 if you have the <math.h> header file. -#define HAVE_MATH_H 1 - -// Define to 1 if you have the long long type -#define HAVE_LONG_LONG 1 - -// Define to 1 if you have 64 bit types available -#define HAVE_INT64_T 1 - -// Define to 1 if your compiler treats char as a separate type along with -// signed char and unsigned char. This will create overloads for char. -#define HAVE_THREE_CHAR_TYPES 1 - -// Define to 1 if you have the <cxxabi.h> header file. -#if __GNUC__ >= 3 - #define HAVE_CXXABI_H 1 -#endif - -// Define to 1 if you have the rintf function. Will use rint otherwise. -#undef HAVE_RINTF - -// Define to 1 if you have the <strings.h> header file. -#undef HAVE_STRINGS_H - -// Define to 1 if you have the `strsignal' function. -#undef HAVE_STRSIGNAL - -// Define to 1 if you have the __va_copy function -#undef HAVE_VA_COPY - -// Define to 1 if you have the <inttypes.h> header file. -#undef HAVE_INTTYPES_H - -// Define to 1 if you have the <malloc.h> header file. -#undef HAVE_MALLOC_H - -// Define to 1 if you have the <memory.h> header file. -#undef HAVE_MEMORY_H - -// Define to 1 if you have the <alloca.h> header file. -#undef HAVE_ALLOCA_H - -// Define to 1 if `stat' has the bug that it succeeds when given the -// zero-length file name argument. -#undef HAVE_STAT_EMPTY_STRING_BUG - -// STDC_HEADERS is defined to 1 on sane systems. -#if defined(HAVE_ASSERT_H) && defined(HAVE_CTYPE_H) &&\ - defined(HAVE_ERRNO_H) && defined(HAVE_FLOAT_H) &&\ - defined(HAVE_LIMITS_H) && defined(HAVE_LOCALE_H) &&\ - defined(HAVE_MATH_H) && defined(HAVE_SIGNAL_H) &&\ - defined(HAVE_STDARG_H) && defined(HAVE_STDDEF_H) &&\ - defined(HAVE_STDIO_H) && defined(HAVE_STDLIB_H) &&\ - defined(HAVE_STRING_H) && defined(HAVE_TIME_H) -#define STDC_HEADERS 1 -#endif - -// STDC_HEADERS is defined to 1 on unix systems. -#if defined(HAVE_FCNTL_H) && defined(HAVE_SYS_STAT_H) && defined(HAVE_UNISTD_H) -#define STDUNIX_HEADERS 1 -#endif - -// Define to 1 if you have the <byteswap.h> header file. -#if (__GNUC__ >= 3) // gcc 2.95 somehow doesn't recognize 'asm volatile' in libc byteswap.h -#undef HAVE_BYTESWAP_H -#endif - -// Define to 1 if `lstat' dereferences a symlink specified with a trailing slash. -#undef LSTAT_FOLLOWS_SLASHED_SYMLINK - -// Define as the return type of signal handlers (`int' or `void'). -#undef RETSIGTYPE - -// Define to 1 if you want unrolled specializations for fill and copy -#undef WANT_UNROLLED_COPY - -// Define to 1 if you want to use MMX/SSE/3dNow! processor instructions -#undef WANT_MMX - -// Define to byte sizes of types -#define SIZE_OF_CHAR 1 -#define SIZE_OF_SHORT 2 -#define SIZE_OF_INT 4 -#define SIZE_OF_LONG 4 -#define SIZE_OF_LONG_LONG 8 -#define SIZE_OF_POINTER 4 -#define SIZE_OF_SIZE_T 4 -#define SIZE_OF_BOOL 1 - - -// Byte order macros, converted in utypes.h -#define USTL_LITTLE_ENDIAN 4321 -#define USTL_BIG_ENDIAN 1234 -#if (CYG_BYTEORDER == CYG_LSBFIRST) -#define USTL_BYTE_ORDER USTL_BIG_ENDIAN -#else -#define USTL_BYTE_ORDER USTL_LITTLE_ENDIAN -#endif - -// Extended CPU capabilities -#undef CPU_HAS_FPU -#undef CPU_HAS_EXT_DEBUG -#undef CPU_HAS_TIMESTAMPC -#undef CPU_HAS_MSR -#undef CPU_HAS_CMPXCHG8 -#undef CPU_HAS_APIC -#undef CPU_HAS_SYSCALL -#undef CPU_HAS_MTRR -#undef CPU_HAS_CMOV -#undef CPU_HAS_FCMOV -#if defined WANT_MMX -#undef CPU_HAS_MMX -#undef CPU_HAS_FXSAVE -#undef CPU_HAS_SSE -#undef CPU_HAS_SSE2 -#undef CPU_HAS_SSE3 -#undef CPU_HAS_EXT_3DNOW -#undef CPU_HAS_3DNOW -#endif - -// GCC vector extensions -#if defined(CPU_HAS_MMX) || defined(CPU_HAS_SSE) - #undef HAVE_VECTOR_EXTENSIONS -#endif - -#if defined(CPU_HAS_SSE) && defined(__GNUC__) - #define __sse_align __attribute__((aligned(16))) -#else - #define __sse_align -#endif - - -// Define to empty if `const' does not conform to ANSI C. -//#undef const - -// Define as `__inline' if that's what the C compiler calls it, or to nothing -// if it is not supported. -//#undef inline - -// Define to `long' if <sys/types.h> does not define. -//#undef off_t - -// Define to `unsigned' if <sys/types.h> does not define. -//#undef size_t - -// --------------------------------------------------------------------------- -#endif // CYGONCE_CONFIG_H -
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/fstream.h +++ /dev/null @@ -1,77 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef FSTREAM_H_056E10F70EAD416443E3B36A2D6B5FA3 -#define FSTREAM_H_056E10F70EAD416443E3B36A2D6B5FA3 - -#include "uios.h" -#include "ustring.h" - -struct stat; - -namespace ustl { - -/// \class fstream fstream.h ustl.h -/// \ingroup DeviceStreams -/// -/// \brief Implements file operations. -/// -/// This is not implemented as a stream, but rather as a base for one. You -/// should use ifstream or ofstream if you want flow operators. Otherwise -/// this only implements functions for binary i/o. -/// -class fstream : public ios_base { -public: - fstream (void); - explicit fstream (const char* filename, openmode mode = in | out); - explicit fstream (int nfd, const char* filename = ""); - ~fstream (void) throw(); - void open (const char* filename, openmode mode, mode_t perms = 0644); - void attach (int nfd, const char* filename = ""); - void detach (void); - void close (void); - void sync (void); - off_t read (void* p, off_t n); - off_t readsome (void* p, off_t n); - off_t write (const void* p, off_t n); - off_t size (void) const; - off_t seek (off_t n, seekdir whence = beg); - off_t pos (void) const; - void stat (struct stat& rs) const; - int ioctl (const char* rname, int request, long argument = 0); - inline int ioctl (const char* rname, int request, int argument) { return (fstream::ioctl (rname, request, long(argument))); } - inline int ioctl (const char* rname, int request, void* argument) { return (fstream::ioctl (rname, request, intptr_t(argument))); } - int fcntl (const char* rname, int request, long argument = 0); - inline int fcntl (const char* rname, int request, int argument) { return (fstream::fcntl (rname, request, long(argument))); } - inline int fcntl (const char* rname, int request, void* argument) { return (fstream::fcntl (rname, request, intptr_t(argument))); } -#if 0 // memory mapped files are not supported in eCos - memlink mmap (off_t n, off_t offset = 0); - void munmap (memlink& l); - void msync (memlink& l); -#endif // #if 0 - void set_nonblock (bool v = true); - inline int fd (void) const { return (m_fd); } - inline bool is_open (void) const { return (fd() >= 0); } - inline off_t tellg (void) const { return (pos()); } - inline off_t tellp (void) const { return (pos()); } - inline void seekg (off_t n, seekdir whence = beg) { seek (n, whence); } - inline void seekp (off_t n, seekdir whence = beg) { seek (n, whence); } - inline void flush (void) { sync(); } - inline const string& name (void) const { return (m_Filename); } -private: - DLL_LOCAL static int om_to_flags (openmode m); - DLL_LOCAL void set_and_throw (iostate s, const char* op); -private: - int m_fd; ///< Currently open file descriptor. - string m_Filename; ///< Currently open filename. -}; - -/// Argument macro for fstream::ioctl. Use like fs.ioctl (IOCTLID (TCGETS), &ts). -#define IOCTLID(r) "ioctl("#r")", r -#define FCNTLID(r) "fcntl("#r")", r - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/memblock.h +++ /dev/null @@ -1,64 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef MEMBLOCK_H_7ED63A891164CC43578E63664D52A196 -#define MEMBLOCK_H_7ED63A891164CC43578E63664D52A196 - -#include "memlink.h" -#include "config.h" - -namespace ustl { - -/// \class memblock memblock.h ustl.h -/// \ingroup MemoryManagement -/// -/// \brief Allocated memory block. -/// -/// Adds memory management capabilities to memlink. Uses malloc and realloc to -/// maintain the internal pointer, but only if allocated using members of this class, -/// or if linked to using the Manage() member function. Managed memory is automatically -/// freed in the destructor. -/// -class memblock : public memlink { -public: - memblock (void); - memblock (const void* p, size_type n); - explicit memblock (size_type n); - explicit memblock (const cmemlink& b); - explicit memblock (const memlink& b); - memblock (const memblock& b); - virtual ~memblock (void) throw(); - virtual void unlink (void) throw(); - inline void assign (const cmemlink& l) { assign (l.cdata(), l.readable_size()); } - inline const memblock& operator= (const cmemlink& l) { assign (l); return (*this); } - inline const memblock& operator= (const memlink& l) { assign (l); return (*this); } - inline const memblock& operator= (const memblock& l) { assign (l); return (*this); } - inline void swap (memblock& l) { memlink::swap (l); ::ustl::swap (m_Capacity, l.m_Capacity); } - void assign (const void* p, size_type n); - void reserve (size_type newSize, bool bExact = true); - void resize (size_type newSize, bool bExact = true); - iterator insert (iterator start, size_type size); - iterator erase (iterator start, size_type size); - inline void clear (void) { resize (0); } - inline size_type capacity (void) const { return (m_Capacity); } - inline bool is_linked (void) const { return (!capacity()); } - inline size_type max_size (void) const { return (is_linked() ? memlink::max_size() : SIZE_MAX); } - inline void manage (memlink& l) { manage (l.begin(), l.size()); } - void deallocate (void) throw(); - void manage (void* p, size_type n); - void copy_link (void); - void read (istream& is); -#ifdef CYGCLS_USTL_FSTREAMS - void read_file (const char* filename); -#endif -protected: - virtual size_type minimumFreeCapacity (void) const throw() __attribute__((const)); -private: - size_type m_Capacity; ///< Number of bytes allocated by Resize. -}; - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/memlink.h +++ /dev/null @@ -1,102 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef MEMLINK_H_798D25827C8E322D2D7E734B169FF5FC -#define MEMLINK_H_798D25827C8E322D2D7E734B169FF5FC - -#include "cmemlink.h" -#include "ualgo.h" - -namespace ustl { - -/// \class memlink memlink.h ustl.h -/// \ingroup MemoryManagement -/// -/// \brief Wrapper for pointer to block with size. -/// -/// Use this class the way you would a pointer to an allocated unstructured block. -/// The pointer and block size are available through member functions and cast operator. -/// -/// Example usage: -/// \code -/// void* p = malloc (46721); -/// memlink a, b; -/// a.link (p, 46721); -/// assert (a.size() == 46721)); -/// b = a; -/// assert (b.size() == 46721)); -/// assert (b.begin() + 34 == a.begin + 34); -/// assert (0 == memcmp (a, b, 12)); -/// a.fill (673, b, 42, 67); -/// b.erase (87, 12); -/// \endcode -/// -class memlink : public cmemlink { -public: - typedef value_type* pointer; - typedef cmemlink::pointer const_pointer; - typedef cmemlink::const_iterator const_iterator; - typedef pointer iterator; - typedef const memlink& rcself_t; -public: - inline memlink (void) : cmemlink() {} - inline memlink (void* p, size_type n) : cmemlink (p, n) {} - inline memlink (const void* p, size_type n) : cmemlink (p, n) {} - inline memlink (rcself_t l) : cmemlink (l) {} - inline explicit memlink (const cmemlink& l) : cmemlink (l) {} - inline pointer data (void) { return (const_cast<pointer>(cdata())); } - inline iterator begin (void) { return (iterator (data())); } - inline iterator iat (size_type i) { assert (i <= size()); return (begin() + i); } - inline iterator end (void) { return (iat (size())); } - inline const_iterator begin (void) const { return (cmemlink::begin()); } - inline const_iterator end (void) const { return (cmemlink::end()); } - inline const_iterator iat (size_type i) const { return (cmemlink::iat (i)); } - size_type writable_size (void) const { return (size()); } - inline rcself_t operator= (const cmemlink& l) { cmemlink::operator= (l); return (*this); } - inline rcself_t operator= (rcself_t l) { cmemlink::operator= (l); return (*this); } - inline void link (const void* p, size_type n) { cmemlink::link (p, n); } - inline void link (void* p, size_type n) { cmemlink::link (p, n); } - inline void link (const cmemlink& l) { cmemlink::link (l); } - inline void link (memlink& l) { cmemlink::link (l); } - inline void link (const void* first, const void* last) { link (first, distance (first, last)); } - inline void link (void* first, void* last) { link (first, distance (first, last)); } - inline void relink (const void* p, size_type n) { cmemlink::relink (p, n); } - inline void relink (void* p, size_type n) { cmemlink::relink (p, n); } - inline void copy (const cmemlink& l) { copy (begin(), l.cdata(), l.size()); } - inline void copy (const void* p, size_type n) { copy (begin(), p, n); } - void copy (iterator offset, const void* p, size_type n); - inline void swap (memlink& l) { cmemlink::swap (l); } - void fill (iterator start, const void* p, size_type elsize, size_type elCount = 1); - inline void insert (iterator start, size_type size); - inline void erase (iterator start, size_type size); - void read (istream& is); -}; - -/// Shifts the data in the linked block from \p start to \p start + \p n. -/// The contents of the uncovered bytes is undefined. -inline void memlink::insert (iterator start, size_type n) -{ - assert (data() || !n); - assert (cmemlink::begin() || !n); - assert (start >= begin() && start + n <= end()); - rotate (start, end() - n, end()); -} - -/// Shifts the data in the linked block from \p start + \p n to \p start. -/// The contents of the uncovered bytes is undefined. -inline void memlink::erase (iterator start, size_type n) -{ - assert (data() || !n); - assert (cmemlink::begin() || !n); - assert (start >= begin() && start + n <= end()); - rotate (start, start + n, end()); -} - -/// Use with memlink-derived classes to allocate and link to stack space. -#define alloca_link(m,n) (m).link (alloca (n), (n)) - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/metamac.h +++ /dev/null @@ -1,92 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. -// -/// \file metamac.h -/// \brief Macros for complex metaprogramming involving pseudoiteration. - -#ifndef METAMAC_H_7235D14A209C29332F2330EF553B81AF -#define METAMAC_H_7235D14A209C29332F2330EF553B81AF - -//---------------------------------------------------------------------- -// Functors and general utilities. -//---------------------------------------------------------------------- - -/// Evaluates to itself -#define ITSELF(x) x - -/// Concatenates \p a and \p b -#define PASTE(a,b) a##b - -//---------------------------------------------------------------------- -// Lists and other iterators -//---------------------------------------------------------------------- - -/// The maximum number of elements in REPEAT, LIST, and COMMA_LIST -#define METAMAC_MAXN 9 - -/// Simple list with no separators. Repeats x N times. -/// @{ -#define REPEAT_1(x) x(1) -#define REPEAT_2(x) REPEAT_1(x) x(2) -#define REPEAT_3(x) REPEAT_2(x) x(3) -#define REPEAT_4(x) REPEAT_3(x) x(4) -#define REPEAT_5(x) REPEAT_4(x) x(5) -#define REPEAT_6(x) REPEAT_5(x) x(6) -#define REPEAT_7(x) REPEAT_6(x) x(7) -#define REPEAT_8(x) REPEAT_7(x) x(8) -#define REPEAT_9(x) REPEAT_8(x) x(9) -#define REPEAT(N,x) PASTE(REPEAT_,N)(x) -/// @} - -/// Simple separated list. Repeats x N times with sep in between. -/// @{ -#define LIST_1(x,sep) x(1) -#define LIST_2(x,sep) LIST_1(x,sep) sep x(2) -#define LIST_3(x,sep) LIST_2(x,sep) sep x(3) -#define LIST_4(x,sep) LIST_3(x,sep) sep x(4) -#define LIST_5(x,sep) LIST_4(x,sep) sep x(5) -#define LIST_6(x,sep) LIST_5(x,sep) sep x(6) -#define LIST_7(x,sep) LIST_6(x,sep) sep x(7) -#define LIST_8(x,sep) LIST_7(x,sep) sep x(8) -#define LIST_9(x,sep) LIST_8(x,sep) sep x(9) -#define LIST(N,x,sep) PASTE(LIST_,N)(x,sep) -/// @} - -/// Comma separated list. A special case of LIST needed because the preprocessor can't substitute commas. -/// @{ -#define COMMA_LIST_1(x) x(1) -#define COMMA_LIST_2(x) COMMA_LIST_1(x), x(2) -#define COMMA_LIST_3(x) COMMA_LIST_2(x), x(3) -#define COMMA_LIST_4(x) COMMA_LIST_3(x), x(4) -#define COMMA_LIST_5(x) COMMA_LIST_4(x), x(5) -#define COMMA_LIST_6(x) COMMA_LIST_5(x), x(6) -#define COMMA_LIST_7(x) COMMA_LIST_6(x), x(7) -#define COMMA_LIST_8(x) COMMA_LIST_7(x), x(8) -#define COMMA_LIST_9(x) COMMA_LIST_8(x), x(9) -#define COMMA_LIST(N,x) PASTE(COMMA_LIST_,N)(x) -/// @} - -//---------------------------------------------------------------------- -// Macros for defining LIST arguments. -//---------------------------------------------------------------------- - -/// Ignores N, producing lists of identically named arguments. -#define LARG_NONE(name,N) name - -/// Appends N to name. -#define LARG_NUMBER(name,N) name##N - -/// name is a reference type. -#define LARG_REF(name,N) name##N& - -/// Sequential parameter passed by value with sequential types. -#define LARG_MT_PARAM_BY_VALUE(type,name,N) type##N name##N - -/// Sequential parameter passed by reference with sequential types. -#define LARG_MT_PARAM_BY_REF(type,name,N) type##N& name##N - -//---------------------------------------------------------------------- - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/mistream.h +++ /dev/null @@ -1,325 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef MISTREAM_H_103AEF1F266C04AA1A817D38705983DA -#define MISTREAM_H_103AEF1F266C04AA1A817D38705983DA - -#include "memlink.h" -#include "uexception.h" -#include "strmsize.h" -#include "utf8.h" -#include "uios.h" -#include "config.h" -#if WANT_STREAM_BOUNDS_CHECKING - #include <typeinfo> -#endif - -namespace ustl { - -class ostream; -class memlink; -class string; - -/// \class istream mistream.h ustl.h -/// \ingroup BinaryStreams -/// -/// \brief Helper class to read packed binary streams. -/// -/// This class contains a set of functions to read integral types from an -/// unstructured memory block. Unpacking binary file data can be done this -/// way, for instance. aligning the data is your responsibility, and can -/// be accomplished by proper ordering of reads and by calling the align() -/// function. Unaligned access is usually slower by orders of magnitude and, -/// on some architectures, such as PowerPC, can cause your program to crash. -/// Therefore, all read functions have asserts to check alignment. -/// Overreading the end of the stream will also cause a crash (an assert in -/// debug builds). Oh, and don't be intimidated by the size of the inlines -/// here. In the assembly code the compiler will usually chop everything down -/// to five instructions each. -/// -/// Alignment rules for your objects: -/// - Assume your writes start off 4-byte aligned. -/// - After completion, \ref istream::align the stream to at least 4. -/// - If data portability between 32bit and 64bit platforms is important -/// (it often is not, in config files and the like), ensure you are always -/// using fixed-size types and are aligning to a fixed grain. Avoid writing -/// 8-byte types, and if you do, manually align before doing so. -/// - Non-default alignment is allowed if you plan to frequently write this -/// object in array form and alignment would be costly. For example, an -/// array of uint16_t-sized objects may leave the stream uint16_t aligned -/// as long as you know about it and will default-align the stream after -/// writing the array (note: \ref vector will already do this for you) -/// -/// Example code: -/// \code -/// memblock b; -/// b.read_file ("test.file"); -/// ostream is (b); -/// is >> boolVar >> ios::talign<int>(); -/// is >> intVar >> floatVar; -/// is.read (binaryData, binaryDataSize); -/// is.align(); -/// \endcode -/// -class istream : public cmemlink, public ios_base { -public: - inline istream (void); - inline istream (const void* p, streamsize n); - inline explicit istream (const cmemlink& source); - explicit istream (const ostream& source); - inline iterator end (void) const { return (cmemlink::end()); } - inline void link (const void* p, streamsize n) { cmemlink::link (p, n); } - inline void link (const cmemlink& l) { cmemlink::link (l.cdata(), l.readable_size()); } - inline void link (const void* f, const void* l) { cmemlink::link (f, l); } - inline void relink (const void* p, streamsize n) { cmemlink::relink (p, n); m_Pos = 0; } - inline void relink (const cmemlink& l) { relink (l.cdata(), l.readable_size()); } - virtual void unlink (void) throw(); - inline virtual streamsize underflow (streamsize = 1) { return (remaining()); } - inline uoff_t pos (void) const { return (m_Pos); } - inline const_iterator ipos (void) const { return (begin() + pos()); } - inline streamsize remaining (void) const { return (size() - pos()); } - inline void seek (uoff_t newPos); - inline void iseek (const_iterator newPos); - inline void skip (streamsize nBytes); - inline bool aligned (streamsize grain = c_DefaultAlignment) const; - inline bool verify_remaining (const char* op, const char* type, streamsize n); - inline streamsize align_size (streamsize grain = c_DefaultAlignment) const; - inline void align (streamsize grain = c_DefaultAlignment); - inline void swap (istream& is); - inline void read (void* buffer, streamsize size); - inline void read (memlink& buf) { read (buf.begin(), buf.writable_size()); } - void read_strz (string& str); - streamsize readsome (void* s, streamsize n); - inline void read (istream&) { } - void write (ostream& os) const; - void text_write (ostringstream& os) const; - inline streamsize stream_size (void) const { return (remaining()); } - template <typename T> - inline void iread (T& v); - inline void ungetc (void) { seek (pos() - 1); } - inline off_t tellg (void) const { return (pos()); } - inline void seekg (off_t p, seekdir d = beg); -private: - streamoff m_Pos; ///< The current read position. -}; - -//---------------------------------------------------------------------- - -template <typename T, typename Stream> -inline streamsize required_stream_size (T, const Stream&) { return (1); } -template <typename T> -inline streamsize required_stream_size (T v, const istream&) { return (stream_size_of(v)); } - -template <typename Stream> -inline bool stream_at_eof (const Stream& stm) { return (stm.eof()); } -template <> -inline bool stream_at_eof (const istream&) { return (false); } - -/// \class istream_iterator -/// \ingroup BinaryStreamIterators -/// -/// \brief An iterator over an istream to use with uSTL algorithms. -/// -template <typename T, typename Stream = istream> -class istream_iterator { -public: - typedef T value_type; - typedef ptrdiff_t difference_type; - typedef const value_type* pointer; - typedef const value_type& reference; - typedef typename Stream::size_type size_type; -public: - istream_iterator (void) : m_pis (NULL), m_v() {} - explicit istream_iterator (Stream& is) : m_pis (&is), m_v() { Read(); } - istream_iterator (const istream_iterator& i) : m_pis (i.m_pis), m_v (i.m_v) {} - /// Reads and returns the next value. - inline const T& operator* (void) { return (m_v); } - inline istream_iterator& operator++ (void) { Read(); return (*this); } - inline istream_iterator& operator-- (void) { m_pis->seek (m_pis->pos() - 2 * stream_size_of(m_v)); return (operator++()); } - inline istream_iterator operator++ (int) { istream_iterator old (*this); operator++(); return (old); } - inline istream_iterator operator-- (int) { istream_iterator old (*this); operator--(); return (old); } - inline istream_iterator& operator+= (streamsize n) { while (n--) operator++(); return (*this); } - inline istream_iterator& operator-= (streamsize n) { m_pis->seek (m_pis->pos() - (n + 1) * stream_size_of(m_v)); return (operator++()); } - inline istream_iterator operator- (streamoff n) const { istream_iterator result (*this); return (result -= n); } - inline difference_type operator- (const istream_iterator& i) const { return (distance (i.m_pis->pos(), m_pis->pos()) / stream_size_of(m_v)); } - inline bool operator== (const istream_iterator& i) const { return ((!m_pis && !i.m_pis) || (m_pis && i.m_pis && m_pis->pos() == i.m_pis->pos())); } - inline bool operator< (const istream_iterator& i) const { return (!i.m_pis || (m_pis && m_pis->pos() < i.m_pis->pos())); } -private: - void Read (void) - { - if (!m_pis) - return; - const streamsize rs (required_stream_size (m_v, *m_pis)); - if (m_pis->remaining() < rs && m_pis->underflow (rs) < rs) { - m_pis = NULL; - return; - } - *m_pis >> m_v; - if (stream_at_eof (*m_pis)) - m_pis = NULL; - } -private: - Stream* m_pis; ///< The host stream. - T m_v; ///< Last read value; cached to be returnable as a const reference. -}; - -//---------------------------------------------------------------------- - -/// \brief Constructs a stream attached to nothing. -/// A stream attached to nothing is not usable. Call Link() functions -/// inherited from cmemlink to attach to some memory block. -/// -inline istream::istream (void) -: cmemlink (), - m_Pos (0) -{ -} - -/// Attaches the stream to a block at \p p of size \p n. -inline istream::istream (const void* p, streamsize n) -: cmemlink (p, n), - m_Pos (0) -{ -} - -/// Attaches to the block pointed to by \p source. -inline istream::istream (const cmemlink& source) -: cmemlink (source), - m_Pos (0) -{ -} - -/// Checks that \p n bytes are available in the stream, or else throws. -inline bool istream::verify_remaining (const char* op, const char* type, streamsize n) -{ - const streamsize rem = remaining(); - bool enough = n <= rem; - if (!enough) overrun (op, type, n, pos(), rem); - return (enough); -} - -/// Sets the current read position to \p newPos -inline void istream::seek (uoff_t newPos) -{ -#if WANT_STREAM_BOUNDS_CHECKING - if (newPos > size()) - USTL_THROW(stream_bounds_exception ("seekg", "byte", pos(), newPos - pos(), size())); -#else - assert (newPos <= size()); -#endif - m_Pos = newPos; -} - -/// Sets the current read position to \p newPos -inline void istream::iseek (const_iterator newPos) -{ - seek (distance (begin(), newPos)); -} - -/// Sets the current write position to \p p based on \p d. -inline void istream::seekg (off_t p, seekdir d) -{ - switch (d) { - case beg: seek (p); break; - case cur: seek (pos() + p); break; - case ios_base::end: seek (size() - p); break; - } -} - -/// Skips \p nBytes without reading them. -inline void istream::skip (streamsize nBytes) -{ - seek (pos() + nBytes); -} - -/// Returns the number of bytes to skip to be aligned on \p grain. -inline streamsize istream::align_size (streamsize grain) const -{ - return (Align (pos(), grain) - pos()); -} - -/// Returns \c true if the read position is aligned on \p grain -inline bool istream::aligned (streamsize grain) const -{ - assert (uintptr_t(begin()) % grain == 0 && "Streams should be attached aligned at the maximum element grain to avoid bus errors."); - return (pos() % grain == 0); -} - -/// aligns the read position on \p grain -inline void istream::align (streamsize grain) -{ - seek (Align (pos(), grain)); -} - -/// Reads type T from the stream via a direct pointer cast. -template <typename T> -inline void istream::iread (T& v) -{ - assert (aligned (alignof (v))); -#if WANT_STREAM_BOUNDS_CHECKING - if (!verify_remaining ("read", USTL_TYPENAME(v), sizeof(T))) - return; -#else - assert (remaining() >= sizeof(T)); -#endif - v = *reinterpret_cast<const T*>(ipos()); - m_Pos += sizeof(T); -} - -/// Swaps contents with \p is -inline void istream::swap (istream& is) -{ - cmemlink::swap (is); - ::ustl::swap (m_Pos, is.m_Pos); -} - -/// Reads \p n bytes into \p buffer. -inline void istream::read (void* buffer, size_type n) -{ -#if WANT_STREAM_BOUNDS_CHECKING - if (!verify_remaining ("read", "binary data", n)) - return; -#else - assert (remaining() >= n && "Reading past end of buffer. Make sure you are reading the right format."); -#endif - memcpy (reinterpret_cast<value_type*>(buffer), ipos(), n); - m_Pos += n; -} - -//---------------------------------------------------------------------- - -template <typename T> struct object_reader { - inline void operator()(istream& is, T& v) const { v.read (is); } -}; -template <typename T> struct integral_object_reader { - inline void operator()(istream& is, T& v) const { is.iread (v); } -}; -template <typename T> -inline istream& operator>> (istream& is, T& v) { - typedef typename tm::Select <numeric_limits<T>::is_integral, - integral_object_reader<T>, object_reader<T> >::Result object_reader_t; - object_reader_t()(is, v); - return (is); -} -template <typename T> -inline istream& operator>> (istream& is, const T& v) { v.read (is); return (is); } - -//---------------------------------------------------------------------- - -typedef istream_iterator<utf8subchar_t> istream_iterator_for_utf8; -typedef utf8in_iterator<istream_iterator_for_utf8> utf8istream_iterator; - -/// Returns a UTF-8 adaptor reading from \p is. -inline utf8istream_iterator utf8in (istream& is) -{ - istream_iterator_for_utf8 si (is); - return (utf8istream_iterator (si)); -} - -//---------------------------------------------------------------------- - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/mostream.h +++ /dev/null @@ -1,294 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef MOSTREAM_H_24A8C5397E0848216573E5670930FC9A -#define MOSTREAM_H_24A8C5397E0848216573E5670930FC9A - -#include "memlink.h" -#include "uexception.h" -#include "utf8.h" -#include "uios.h" -#include "config.h" -#if WANT_STREAM_BOUNDS_CHECKING - #include <typeinfo> -#endif - -namespace ustl { - -class istream; -class string; - -/// \class ostream mostream.h ustl.h -/// \ingroup BinaryStreams -/// -/// \brief Helper class to write packed binary streams. -/// -/// This class contains a set of functions to write integral types into an -/// unstructured memory block. Packing binary file data can be done this -/// way, for instance. aligning the data is your responsibility, and can -/// be accomplished by proper ordering of writes and by calling \ref ostream::align. -/// Unaligned access is usually slower by orders of magnitude and, -/// on some architectures, such as PowerPC, can cause your program to crash. -/// Therefore, all write functions have asserts to check alignment. -/// See \ref istream documentation for rules on designing your data format. -/// Overwriting the end of the stream will also cause a crash (an assert in -/// debug builds). Oh, and don't be intimidated by the size of the inlines -/// here. In the assembly code the compiler will usually chop everything down -/// to five instructions each. -/// -/// Example code: -/// \code -/// memblock b; -/// ostream os (b); -/// os << boolVar << ios::talign<int>(); -/// os << intVar << floatVar; -/// os.write (binaryData, binaryDataSize); -/// os.align(); -/// b.resize (os.pos()); -/// b.write_file ("test.file"); -/// \endcode -/// -class ostream : public memlink, public ios_base { -public: - inline ostream (void); - inline ostream (void* p, streamsize n); - inline explicit ostream (const memlink& source); - inline iterator end (void) { return (memlink::end()); } - inline const_iterator end (void) const { return (memlink::end()); } - inline void seek (uoff_t newPos); - inline void iseek (const_iterator newPos); - inline void skip (streamsize nBytes); - inline uoff_t pos (void) const { return (m_Pos); } - inline iterator ipos (void) { return (begin() + pos()); } - inline const_iterator ipos (void) const { return (begin() + pos()); } - inline streamsize remaining (void) const; - inline bool aligned (streamsize grain = c_DefaultAlignment) const; - bool verify_remaining (const char* op, const char* type, size_t n); - inline streamsize align_size (streamsize grain = c_DefaultAlignment) const; - void align (streamsize grain = c_DefaultAlignment); - inline void write (const void* buffer, streamsize size); - inline void write (const cmemlink& buf); - void write_strz (const char* str); - void read (istream& is); - inline void write (ostream& os) const { os.write (begin(), pos()); } - void text_write (ostringstream& os) const; - inline size_t stream_size (void) const { return (pos()); } - void insert (iterator start, streamsize size); - void erase (iterator start, streamsize size); - inline void swap (ostream& os); - template <typename T> - inline void iwrite (const T& v); - inline virtual streamsize overflow (streamsize = 1){ return (remaining()); } - virtual void unlink (void) throw(); - inline void link (void* p, streamsize n) { memlink::link (p, n); } - inline void link (memlink& l) { memlink::link (l.data(), l.writable_size()); } - inline void link (void* f, void* l) { memlink::link (f, l); } - inline void relink (void* p, streamsize n) { memlink::relink (p, n); m_Pos = 0; } - inline void relink (memlink& l) { relink (l.data(), l.writable_size()); } - inline void seekp (off_t p, seekdir d = beg); - inline off_t tellp (void) const { return (pos()); } -protected: - inline void SetPos (uoff_t newPos) { m_Pos = newPos; } -private: - streamoff m_Pos; ///< Current write position. -}; - -//---------------------------------------------------------------------- - -/// \class ostream_iterator mostream.h ustl.h -/// \ingroup BinaryStreamIterators -/// -/// \brief An iterator over an ostream to use with uSTL algorithms. -/// -template <typename T, typename Stream = ostream> -class ostream_iterator { -public: - typedef T value_type; - typedef ptrdiff_t difference_type; - typedef value_type* pointer; - typedef value_type& reference; - typedef typename Stream::size_type size_type; -public: - inline explicit ostream_iterator (Stream& os) - : m_Os (os) {} - inline ostream_iterator (const ostream_iterator& iter) - : m_Os (iter.m_Os) {} - /// Writes \p v into the stream. - inline ostream_iterator& operator= (const T& v) - { m_Os << v; return (*this); } - inline ostream_iterator& operator* (void) { return (*this); } - inline ostream_iterator& operator++ (void) { return (*this); } - inline ostream_iterator operator++ (int) { return (*this); } - inline ostream_iterator& operator+= (streamsize n) { m_Os.skip (n); return (*this); } - inline bool operator== (const ostream_iterator& i) const - { return (m_Os.pos() == i.m_Os.pos()); } - inline bool operator< (const ostream_iterator& i) const - { return (m_Os.pos() < i.m_Os.pos()); } -private: - Stream& m_Os; -}; - -//---------------------------------------------------------------------- - -typedef ostream_iterator<utf8subchar_t> ostream_iterator_for_utf8; -typedef utf8out_iterator<ostream_iterator_for_utf8> utf8ostream_iterator; - -/// Returns a UTF-8 adaptor writing to \p os. -inline utf8ostream_iterator utf8out (ostream& os) -{ - ostream_iterator_for_utf8 si (os); - return (utf8ostream_iterator (si)); -} - -//---------------------------------------------------------------------- - -/// \brief Constructs a stream attached to nothing. -/// A stream attached to nothing is not usable. Call Link() functions -/// inherited from memlink to attach to some memory block. -/// -inline ostream::ostream (void) -: memlink (), - m_Pos (0) -{ -} - -/// Attaches the stream to a block at \p p of size \p n. -inline ostream::ostream (void* p, streamsize n) -: memlink (p, n), - m_Pos (0) -{ -} - -/// Attaches to the block pointed to by \p source. -inline ostream::ostream (const memlink& source) -: memlink (source), - m_Pos (0) -{ -} - -/// Checks that \p n bytes are available in the stream, or else throws. -inline bool ostream::verify_remaining (const char* op, const char* type, size_t n) -{ - const size_t rem = remaining(); - bool enough = n <= rem; - if (!enough) overrun (op, type, n, pos(), rem); - return (enough); -} - -/// Move the write pointer to \p newPos -inline void ostream::seek (uoff_t newPos) -{ -#if WANT_STREAM_BOUNDS_CHECKING - if (newPos > size()) - USTL_THROW(stream_bounds_exception ("seekp", "byte", pos(), newPos - pos(), size())); -#else - assert (newPos <= size()); -#endif - SetPos (newPos); -} - -/// Sets the current write position to \p newPos -inline void ostream::iseek (const_iterator newPos) -{ - seek (distance (begin(), const_cast<iterator>(newPos))); -} - -/// Sets the current write position to \p p based on \p d. -inline void ostream::seekp (off_t p, seekdir d) -{ - switch (d) { - case beg: seek (p); break; - case cur: seek (pos() + p); break; - case ios_base::end: seek (size() - p); break; - } -} - -/// Skips \p nBytes without writing anything. -inline void ostream::skip (streamsize nBytes) -{ - seek (pos() + nBytes); -} - -/// Returns number of bytes remaining in the write buffer. -inline streamsize ostream::remaining (void) const -{ - return (size() - pos()); -} - -/// Returns \c true if the write pointer is aligned on \p grain -inline bool ostream::aligned (streamsize grain) const -{ - assert (uintptr_t(begin()) % grain == 0 && "Streams should be attached aligned at the maximum element grain to avoid bus errors."); - return (pos() % grain == 0); -} - -/// Returns the number of bytes to skip to be aligned on \p grain. -inline streamsize ostream::align_size (streamsize grain) const -{ - return (Align (pos(), grain) - pos()); -} - -/// Writes \p n bytes from \p buffer. -inline void ostream::write (const void* buffer, size_type n) -{ -#if WANT_STREAM_BOUNDS_CHECKING - if (!verify_remaining ("write", "binary data", n)) - return; -#else - assert (remaining() >= n && "Buffer overrun. Check your stream size calculations."); -#endif - memcpy (ipos(), const_iterator(buffer), n); - m_Pos += n; -} - -/// Writes the contents of \p buf into the stream as a raw dump. -inline void ostream::write (const cmemlink& buf) -{ - write (buf.begin(), buf.size()); -} - -/// Writes type T into the stream via a direct pointer cast. -template <typename T> -inline void ostream::iwrite (const T& v) -{ - assert (aligned (alignof (v))); -#if WANT_STREAM_BOUNDS_CHECKING - if (!verify_remaining ("write", USTL_TYPENAME(v), sizeof(T))) - return; -#else - assert (remaining() >= sizeof(T)); -#endif - *reinterpret_cast<T*>(ipos()) = v; - SetPos (pos() + sizeof(T)); -} - -/// Swaps with \p os -inline void ostream::swap (ostream& os) -{ - memlink::swap (os); - ::ustl::swap (m_Pos, os.m_Pos); -} - -//---------------------------------------------------------------------- - -template <typename T> struct object_writer { - inline void operator()(ostream& os, const T& v) const { v.write (os); } -}; -template <typename T> struct integral_object_writer { - inline void operator()(ostream& os, const T& v) const { os.iwrite (v); } -}; -template <typename T> -inline ostream& operator<< (ostream& os, const T& v) { - typedef typename tm::Select <numeric_limits<T>::is_integral, - integral_object_writer<T>, object_writer<T> >::Result object_writer_t; - object_writer_t()(os, v); - return (os); -} - -//---------------------------------------------------------------------- - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/ofstream.h +++ /dev/null @@ -1,81 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef FDOSTREAM_H_5E27FC3D530BF3CA04D6C73F5700EECC -#define FDOSTREAM_H_5E27FC3D530BF3CA04D6C73F5700EECC - -#include "sistream.h" -#include "sostream.h" -#include "fstream.h" -#include "config.h" - -namespace ustl { - -/// \class ofstream fdostream.h ustl.h -/// \ingroup DeviceStreams -/// \brief A string stream that writes to an fd. Implements cout and cerr. -class ofstream : public ostringstream { -public: - ofstream (void); - explicit ofstream (int Fd); - explicit ofstream (const char* filename, openmode mode = out); - virtual ~ofstream (void) throw(); - inline void open (const char* filename, openmode mode = out) { m_File.open (filename, mode); clear (m_File.rdstate()); } - void close (void); - inline bool is_open (void) const { return (m_File.is_open()); } - inline iostate exceptions (iostate v) { ostringstream::exceptions(v); return (m_File.exceptions(v)); } - inline void setstate (iostate v) { ostringstream::setstate(v); m_File.setstate(v); } - inline void clear (iostate v = goodbit) { ostringstream::clear(v); m_File.clear(v); } - inline off_t tellp (void) const { return (m_File.tellp() + ostringstream::tellp()); } - inline int fd (void) const { return (m_File.fd()); } - inline void stat (struct stat& rs) const { m_File.stat (rs); } - inline void set_nonblock (bool v = true) { m_File.set_nonblock (v); } - inline int ioctl (const char* rname, int request, long argument = 0) { return (m_File.ioctl (rname, request, argument)); } - inline int ioctl (const char* rname, int request, int argument) { return (m_File.ioctl (rname, request, argument)); } - inline int ioctl (const char* rname, int request, void* argument) { return (m_File.ioctl (rname, request, argument)); } - ofstream& seekp (off_t p, seekdir d = beg); - ofstream& flush (void); - virtual size_type overflow (size_type n = 1); -private: - fstream m_File; -}; - -/// \class ifstream fdostream.h ustl.h -/// \ingroup DeviceStreams -/// \brief A string stream that reads from an fd. Implements cin. -class ifstream : public istringstream { -public: - ifstream (void); - explicit ifstream (int Fd); - explicit ifstream (const char* filename, openmode mode = in); - inline void open (const char* filename, openmode mode = in) { m_File.open (filename, mode); clear (m_File.rdstate()); } - inline void close (void) { m_File.close(); clear (m_File.rdstate()); } - inline bool is_open (void) const { return (m_File.is_open()); } - inline iostate exceptions (iostate v) { istringstream::exceptions(v); return (m_File.exceptions(v)); } - inline void setstate (iostate v) { istringstream::setstate(v); m_File.setstate(v); } - inline void clear (iostate v = goodbit) { istringstream::clear(v); m_File.clear(v); } - inline off_t tellg (void) const { return (m_File.tellg() - remaining()); } - inline int fd (void) const { return (m_File.fd()); } - inline void stat (struct stat& rs) const { m_File.stat (rs); } - inline void set_nonblock (bool v = true) { m_File.set_nonblock (v); } - inline int ioctl (const char* rname, int request, long argument = 0) { return (m_File.ioctl (rname, request, argument)); } - inline int ioctl (const char* rname, int request, int argument) { return (m_File.ioctl (rname, request, argument)); } - inline int ioctl (const char* rname, int request, void* argument) { return (m_File.ioctl (rname, request, argument)); } - ifstream& seekg (off_t p, seekdir d = beg); - int sync (void); - virtual size_type underflow (size_type n = 1); -private: - string m_Buffer; - fstream m_File; -}; - -#ifdef CYGVAR_USTL_CIN_COUT_CERR -extern ofstream cout, cerr; -extern ifstream cin; -#endif - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/simd.h +++ /dev/null @@ -1,466 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. -// -/// \file simd.h -/// \brief SIMD-type algorithms, with hardware acceleration, if available. -/// -/// All algorithms are container-based because iterator syntax is just too -/// damn verbose and because the specializations need to be able to tell -/// how many elements are in the container in order to choose proper SIMD -/// instruction set (i.e.: 4 floats select SSE, while 2 floats select 3dNow!) -/// Specializations are only for the tuple template because the container -/// must be of a fixed and compile-time-known size for the compiler to be -/// able to choose the specialization. - -#ifndef SIMD_H_39BE2D970DF4BD00508CCFFB482496F9 -#define SIMD_H_39BE2D970DF4BD00508CCFFB482496F9 - -#include "ulimits.h" -#if HAVE_MATH_H - #include <math.h> -#endif - -namespace ustl { -namespace simd { - -//---------------------------------------------------------------------- -// Generic algorithms -//---------------------------------------------------------------------- - -/// Applies \p op to each element in \p op1. -template <typename Ctr, typename UnaryOperation> -inline void packop (Ctr& op1, UnaryOperation op) -{ - foreach (typename Ctr::iterator, i, op1) - op (*i); -} - -/// Applies \p op to each element in \p op1 and \p op2 and stores in \p op2. -template <typename Ctr, typename BinaryOperation> -inline void packop (const Ctr& op1, Ctr& op2, BinaryOperation op) -{ - assert (op2.size() <= op1.size()); - typename Ctr::const_iterator i1 (op1.begin()); - typename Ctr::iterator i2 (op2.begin()); - for (; i2 != op2.end(); ++i1, ++i2) - *i2 = op (*i2, *i1); -} - -/// Applies \p op to corresponding elements in \p op1 and \p op2 and stores in \p result. -template <typename Ctr, typename BinaryOperation> -inline void packop (const Ctr& op1, const Ctr& op2, Ctr& result, BinaryOperation op) -{ - assert (op1.size() <= op2.size() && op1.size() <= result.size()); - passign (op1, result); - packop (op2, result); -} - -/// Copies \p op1 into \p result. -template <typename Ctr> -inline void passign (const Ctr& op1, Ctr& result) -{ - assert (op1.size() <= result.size()); - typename Ctr::iterator d (result.begin()); - foreach (typename Ctr::const_iterator, s, op1) - *d++ = *s; -} - -/// Copies \p result.size() elements from \p op1 to \p result. -template <typename Ctr> -inline void ipassign (typename Ctr::const_iterator op1, Ctr& result) -{ - foreach (typename Ctr::iterator, d, result) - *d = *op1++; -} - -template <typename Ctr1, typename Ctr2, typename ConvertFunction> -inline void pconvert (const Ctr1& op1, Ctr2& op2, ConvertFunction f) -{ - assert (op1.size() <= op2.size()); - typename Ctr1::const_iterator i1 (op1.begin()); - typename Ctr2::iterator i2 (op2.begin()); - for (; i1 != op1.end(); ++i1, ++i2) - *i2 = f (*i1); -} - -// Functionoids for SIMD operations, like saturation arithmetic, shifts, etc. -STD_BINARY_FUNCTOR (fpadds, T, ((b > numeric_limits<T>::max() - a) ? numeric_limits<T>::max() : a + b)) -STD_BINARY_FUNCTOR (fpsubs, T, ((a < numeric_limits<T>::min() + b) ? numeric_limits<T>::min() : a - b)) -STD_BINARY_FUNCTOR (fpshl, T, (a << b)) -STD_BINARY_FUNCTOR (fpshr, T, (a >> b)) -STD_BINARY_FUNCTOR (fpmin, T, (min (a, b))) -STD_BINARY_FUNCTOR (fpmax, T, (max (a, b))) -STD_BINARY_FUNCTOR (fpavg, T, ((a + b + 1) / 2)) -STD_CONVERSION_FUNCTOR (fcast, (D(a))) -#if HAVE_MATH_H -STD_UNARY_FUNCTOR (fpreciprocal,T, (1 / a)) -STD_UNARY_FUNCTOR (fpsqrt, T, (reset_mmx(), T (sqrt (a)))) -STD_UNARY_FUNCTOR (fprecipsqrt, T, (reset_mmx(), 1 / T(sqrt (a)))) -STD_UNARY_FUNCTOR (fsin, T, (reset_mmx(), T (sin (a)))) -STD_UNARY_FUNCTOR (fcos, T, (reset_mmx(), T (cos (a)))) -STD_UNARY_FUNCTOR (ftan, T, (reset_mmx(), T (tan (a)))) -#if HAVE_RINTF -STD_CONVERSION_FUNCTOR (fround, (reset_mmx(), D(rintf(a)))) -#else -STD_CONVERSION_FUNCTOR (fround, (reset_mmx(), D(rint(a)))) -#endif -template <> inline int32_t fround<double,int32_t>::operator()(const double& a) const { reset_mmx(); return (int32_t(rint(a))); } -#endif -template <> inline float fpavg<float>::operator()(const float& a, const float& b) const { return ((a + b) / 2); } -template <> inline double fpavg<double>::operator()(const double& a, const double& b) const { return ((a + b) / 2); } - -#define SIMD_PACKEDOP1(name, operation) \ -template <typename Ctr> \ -inline void name (Ctr& op1) \ -{ \ - typedef typename Ctr::value_type value_t; \ - packop (op1, operation<value_t>()); \ -} -#define SIMD_PACKEDOP2(name, operation) \ -template <typename Ctr> \ -inline void name (const Ctr& op1, Ctr& op2) \ -{ \ - typedef typename Ctr::value_type value_t; \ - packop (op1, op2, operation<value_t>()); \ -} -#define SIMD_PACKEDOP3(name, operation) \ -template <typename Ctr> \ -inline void name (const Ctr& op1, const Ctr& op2, Ctr& result) \ -{ \ - typedef typename Ctr::value_type value_t; \ - packop (op1, op2, result, operation<value_t>()); \ -} -#define SIMD_SINGLEOP1(name, operation) \ -template <typename T> \ -inline T name (T op) \ -{ \ - operation<T> obj; \ - return (obj(op)); \ -} -#define SIMD_CONVERTOP(name, operation) \ -template <typename Ctr1, typename Ctr2> \ -inline void name (const Ctr1& op1, Ctr2& op2) \ -{ \ - typedef typename Ctr1::value_type value1_t; \ - typedef typename Ctr2::value_type value2_t; \ - pconvert (op1, op2, operation<value1_t, value2_t>());\ -} - -SIMD_PACKEDOP2 (padd, plus) -SIMD_PACKEDOP2 (psub, minus) -SIMD_PACKEDOP2 (pmul, multiplies) -SIMD_PACKEDOP2 (pdiv, divides) -SIMD_PACKEDOP2 (pand, bitwise_and) -SIMD_PACKEDOP2 (por, bitwise_or) -SIMD_PACKEDOP2 (pxor, bitwise_xor) -SIMD_PACKEDOP2 (pshl, fpshl) -SIMD_PACKEDOP2 (pshr, fpshr) -SIMD_PACKEDOP2 (psubs, fpsubs) -SIMD_PACKEDOP2 (pmin, fpmin) -SIMD_PACKEDOP2 (pmax, fpmax) -SIMD_PACKEDOP2 (pavg, fpavg) - -SIMD_PACKEDOP3 (padd, plus) -SIMD_PACKEDOP3 (psub, minus) -SIMD_PACKEDOP3 (pmul, multiplies) -SIMD_PACKEDOP3 (pdiv, divides) -SIMD_PACKEDOP3 (pand, bitwise_and) -SIMD_PACKEDOP3 (por, bitwise_or) -SIMD_PACKEDOP3 (pxor, bitwise_xor) -SIMD_PACKEDOP3 (pshl, fpshl) -SIMD_PACKEDOP3 (pshr, fpshr) -SIMD_PACKEDOP3 (padds, fpadds) -SIMD_PACKEDOP3 (psubs, fpsubs) -SIMD_PACKEDOP3 (pmin, fpmin) -SIMD_PACKEDOP3 (pmax, fpmax) -SIMD_PACKEDOP3 (pavg, fpavg) - -#if HAVE_MATH_H -SIMD_PACKEDOP1 (precip, fpreciprocal) -SIMD_PACKEDOP1 (psqrt, fpsqrt) -SIMD_PACKEDOP1 (precipsqrt, fprecipsqrt) -SIMD_PACKEDOP1 (psin, fsin) -SIMD_PACKEDOP1 (pcos, fcos) -SIMD_PACKEDOP1 (ptan, ftan) - -SIMD_SINGLEOP1 (srecip, fpreciprocal) -SIMD_SINGLEOP1 (ssqrt, fpsqrt) -SIMD_SINGLEOP1 (srecipsqrt, fprecipsqrt) -SIMD_SINGLEOP1 (ssin, fsin) -SIMD_SINGLEOP1 (scos, fcos) -SIMD_SINGLEOP1 (stan, ftan) - -SIMD_CONVERTOP (pround, fround) - -template <typename T> inline int32_t sround (T op) { fround<T,int32_t> obj; return (obj (op)); } -#endif - -#undef SIMD_SINGLEOP1 -#undef SIMD_PACKEDOP3 -#undef SIMD_PACKEDOP2 -#undef SIMD_PACKEDOP1 - -//---------------------------------------------------------------------- -// Vector types to cast tuple data to -//---------------------------------------------------------------------- - -#if HAVE_VECTOR_EXTENSIONS && __GNUC__ >= 4 -#define VECTOR_ATTRIBUTE(mode,vs) __attribute__((vector_size(vs))) -#else -#define VECTOR_ATTRIBUTE(mode,vs) -#endif -typedef uint8_t v8qi_t VECTOR_ATTRIBUTE (V8QI,8); -typedef uint16_t v4hi_t VECTOR_ATTRIBUTE (V4HI,8); -typedef uint16_t v8hi_t VECTOR_ATTRIBUTE (V8HI,16); -typedef uint32_t v2si_t VECTOR_ATTRIBUTE (V2SI,8); -typedef uint32_t v4si_t VECTOR_ATTRIBUTE (V4SI,16); -#if HAVE_INT64_T -typedef uint64_t v1di_t VECTOR_ATTRIBUTE (V1DI,8); -#endif -typedef float v2sf_t VECTOR_ATTRIBUTE (V2SF,8); -typedef float v4sf_t VECTOR_ATTRIBUTE (V4SF,16); -typedef double v2df_t VECTOR_ATTRIBUTE (V2DF,16); -#undef VECTOR_ATTRIBUTE - -#define SIMDA_RI(n) "m"(oin[n]) -#define SIMDA_RO(n) "m"(oout[n]) -#define SIMDA_WI(n) "=m"(oin[n]) -#define SIMDA_WO(n) "=m"(oout[n]) - -//---------------------------------------------------------------------- -// Hardware accelerated specializations -//---------------------------------------------------------------------- - -#define SIMD_PKOP2_SPEC(n, type, optype) \ -template <> \ -inline void packop (const tuple<n,type>& oin, tuple<n,type>& oout, optype<type>) -#define SIMD_PASSIGN_SPEC(n, type) \ -template <> \ -inline void passign (const tuple<n,type>& oin, tuple<n,type>& oout) -#define SIMD_IPASSIGN_SPEC(n, type) \ -template <> \ -inline void ipassign (tuple<n,type>::const_iterator oin, tuple<n,type>& oout) -#define SIMD_CONVERT_SPEC(n, type1, type2, optype) \ -template <> \ -inline void pconvert (const tuple<n,type1>& oin, tuple<n,type2>& oout, optype<type1,type2>) - -#if CPU_HAS_MMX -#define STD_MMX_ARGS : "m"(oout[0]), "m"(oin[0]) : "mm0", "st", "memory" -#define DBL_MMX_ARGS : "m"(oout[0]), "m"(oout[2]), "m"(oin[0]), "m"(oin[2]) : "mm0", "mm1", "st", "st(1)", "memory" -#define MMX_PKOP2_SPEC(n,type,optype,instruction) \ -SIMD_PKOP2_SPEC(n,type,optype) \ -{ asm ("movq %0, %%mm0\n\t" #instruction " %1, %%mm0\n\tmovq %%mm0, %0" : STD_MMX_ARGS); reset_mmx(); } -#define MMX_DBL_PKOP2_SPEC(n,type,optype,instruction) \ -SIMD_PKOP2_SPEC(n,type,optype) \ -{ asm ("movq %0, %%mm0\n\tmovq %1, %%mm1\n\t" #instruction " %2, %%mm0\n\t" #instruction " %3, %%mm1\n\tmovq %%mm0, %0\n\tmovq %%mm1, %1" : DBL_MMX_ARGS); reset_mmx(); } -#define MMX_PASSIGN_SPEC(n,type) \ -SIMD_PASSIGN_SPEC(n,type) \ -{ asm ("movq %1, %%mm0\n\tmovq %%mm0, %0" : STD_MMX_ARGS); reset_mmx(); } -#define MMX_DBL_PASSIGN_SPEC(n,type) \ -SIMD_PASSIGN_SPEC(n,type) \ -{ asm ("movq %2, %%mm0\n\tmovq %3, %%mm1\n\tmovq %%mm0, %0\n\tmovq %%mm1, %1" : DBL_MMX_ARGS); reset_mmx(); } -#define MMX_IPASSIGN_SPEC(n,type) \ -SIMD_IPASSIGN_SPEC(n,type) \ -{ asm ("movq %1, %%mm0\n\tmovq %%mm0, %0" : STD_MMX_ARGS); reset_mmx(); } -#define MMX_DBL_IPASSIGN_SPEC(n,type) \ -SIMD_IPASSIGN_SPEC(n,type) \ -{ asm ("movq %2, %%mm0\n\tmovq %3, %%mm1\n\tmovq %%mm0, %0\n\tmovq %%mm1, %1" : DBL_MMX_ARGS); reset_mmx(); } - -MMX_PASSIGN_SPEC(8,uint8_t) -MMX_PKOP2_SPEC(8,uint8_t,plus,paddb) -MMX_PKOP2_SPEC(8,uint8_t,minus,psubb) -MMX_PKOP2_SPEC(8,uint8_t,bitwise_and,pand) -MMX_PKOP2_SPEC(8,uint8_t,bitwise_or,por) -MMX_PKOP2_SPEC(8,uint8_t,bitwise_xor,pxor) -MMX_PKOP2_SPEC(8,uint8_t,fpadds,paddusb) -MMX_PKOP2_SPEC(8,uint8_t,fpsubs,psubusb) - -MMX_PASSIGN_SPEC(8,int8_t) -MMX_PKOP2_SPEC(8,int8_t,plus,paddb) -MMX_PKOP2_SPEC(8,int8_t,minus,psubb) -MMX_PKOP2_SPEC(8,int8_t,bitwise_and,pand) -MMX_PKOP2_SPEC(8,int8_t,bitwise_or,por) -MMX_PKOP2_SPEC(8,int8_t,bitwise_xor,pxor) -MMX_PKOP2_SPEC(8,int8_t,fpadds,paddsb) -MMX_PKOP2_SPEC(8,int8_t,fpsubs,psubsb) - -MMX_PASSIGN_SPEC(4,uint16_t) -MMX_PKOP2_SPEC(4,uint16_t,plus,paddw) -MMX_PKOP2_SPEC(4,uint16_t,minus,psubw) -MMX_PKOP2_SPEC(4,uint16_t,bitwise_and,pand) -MMX_PKOP2_SPEC(4,uint16_t,bitwise_or,por) -MMX_PKOP2_SPEC(4,uint16_t,bitwise_xor,pxor) -/// \todo psllw does not work like other operations, it uses the first element for shift count. -//MMX_PKOP2_SPEC(4,uint16_t,fpshl,psllw) -//MMX_PKOP2_SPEC(4,uint16_t,fpshr,psrlw) -MMX_PKOP2_SPEC(4,uint16_t,fpadds,paddusw) -MMX_PKOP2_SPEC(4,uint16_t,fpsubs,psubusw) - -MMX_PASSIGN_SPEC(4,int16_t) -MMX_PKOP2_SPEC(4,int16_t,plus,paddw) -MMX_PKOP2_SPEC(4,int16_t,minus,psubw) -MMX_PKOP2_SPEC(4,int16_t,bitwise_and,pand) -MMX_PKOP2_SPEC(4,int16_t,bitwise_or,por) -MMX_PKOP2_SPEC(4,int16_t,bitwise_xor,pxor) -//MMX_PKOP2_SPEC(4,int16_t,fpshl,psllw) -//MMX_PKOP2_SPEC(4,int16_t,fpshr,psrlw) -MMX_PKOP2_SPEC(4,int16_t,fpadds,paddsw) -MMX_PKOP2_SPEC(4,int16_t,fpsubs,psubsw) - -MMX_PASSIGN_SPEC(2,uint32_t) -MMX_PKOP2_SPEC(2,uint32_t,plus,paddd) -MMX_PKOP2_SPEC(2,uint32_t,minus,psubd) -MMX_PKOP2_SPEC(2,uint32_t,bitwise_and,pand) -MMX_PKOP2_SPEC(2,uint32_t,bitwise_or,por) -MMX_PKOP2_SPEC(2,uint32_t,bitwise_xor,pxor) -//MMX_PKOP2_SPEC(2,uint32_t,fpshl,pslld) -//MMX_PKOP2_SPEC(2,uint32_t,fpshr,psrld) - -MMX_PASSIGN_SPEC(2,int32_t) -MMX_PKOP2_SPEC(2,int32_t,plus,paddd) -MMX_PKOP2_SPEC(2,int32_t,minus,psubd) -MMX_PKOP2_SPEC(2,int32_t,bitwise_and,pand) -MMX_PKOP2_SPEC(2,int32_t,bitwise_or,por) -MMX_PKOP2_SPEC(2,int32_t,bitwise_xor,pxor) -//MMX_PKOP2_SPEC(2,int32_t,fpshl,pslld) -//MMX_PKOP2_SPEC(2,int32_t,fpshr,psrld) - -MMX_DBL_PKOP2_SPEC(4,uint32_t,plus,paddd) -MMX_DBL_PKOP2_SPEC(4,uint32_t,minus,psubd) -MMX_DBL_PKOP2_SPEC(4,uint32_t,bitwise_and,pand) -MMX_DBL_PKOP2_SPEC(4,uint32_t,bitwise_or,por) -MMX_DBL_PKOP2_SPEC(4,uint32_t,bitwise_xor,pxor) -//MMX_DBL_PKOP2_SPEC(2,uint32_t,fpshl,pslld) -//MMX_DBL_PKOP2_SPEC(2,uint32_t,fpshr,psrld) - -MMX_DBL_PKOP2_SPEC(4,int32_t,plus,paddd) -MMX_DBL_PKOP2_SPEC(4,int32_t,minus,psubd) -MMX_DBL_PKOP2_SPEC(4,int32_t,bitwise_and,pand) -MMX_DBL_PKOP2_SPEC(4,int32_t,bitwise_or,por) -MMX_DBL_PKOP2_SPEC(4,int32_t,bitwise_xor,pxor) -//MMX_DBL_PKOP2_SPEC(2,int32_t,fpshl,pslld) -//MMX_DBL_PKOP2_SPEC(2,int32_t,fpshr,psrld) - -#if CPU_HAS_SSE || CPU_HAS_3DNOW -MMX_PKOP2_SPEC(8,uint8_t,fpavg,pavgb) -MMX_PKOP2_SPEC(8,int8_t,fpavg,pavgb) -MMX_PKOP2_SPEC(4,uint16_t,fpavg,pavgw) -MMX_PKOP2_SPEC(4,int16_t,fpavg,pavgw) -MMX_PKOP2_SPEC(8,uint8_t,fpmin,pminub) -MMX_PKOP2_SPEC(8,uint8_t,fpmax,pmaxub) -MMX_PKOP2_SPEC(4,int16_t,fpmax,pmaxsw) -MMX_PKOP2_SPEC(4,int16_t,fpmin,pminsw) -#endif // CPU_HAS_SSE || CPU_HAS_3DNOW - -#if CPU_HAS_3DNOW -MMX_PASSIGN_SPEC(2,float) -MMX_PKOP2_SPEC(2,float,plus,pfadd) -MMX_PKOP2_SPEC(2,float,minus,pfsub) -MMX_PKOP2_SPEC(2,float,multiplies,pfmul) -MMX_PKOP2_SPEC(2,float,fpmin,pfmin) -MMX_PKOP2_SPEC(2,float,fpmax,pfmax) -#ifndef CPU_HAS_SSE -MMX_DBL_PKOP2_SPEC(4,float,plus,pfadd) -MMX_DBL_PKOP2_SPEC(4,float,minus,pfsub) -MMX_DBL_PKOP2_SPEC(4,float,multiplies,pfmul) -MMX_DBL_PKOP2_SPEC(4,float,fpmin,pfmin) -MMX_DBL_PKOP2_SPEC(4,float,fpmax,pfmax) -#endif -#endif // CPU_HAS_3DNOW - -MMX_IPASSIGN_SPEC(8,uint8_t) -MMX_IPASSIGN_SPEC(4,uint16_t) -MMX_IPASSIGN_SPEC(2,uint32_t) -MMX_IPASSIGN_SPEC(2,float) - -#ifndef CPU_HAS_SSE -MMX_DBL_PASSIGN_SPEC(4,float) -MMX_DBL_PASSIGN_SPEC(4,uint32_t) -MMX_DBL_PASSIGN_SPEC(4,int32_t) -MMX_DBL_IPASSIGN_SPEC(4,float) -MMX_DBL_IPASSIGN_SPEC(4,uint32_t) -MMX_DBL_IPASSIGN_SPEC(4,int32_t) -#endif - -#undef MMX_IPASSIGN_SPEC -#undef MMX_PASSIGN_SPEC -#undef MMX_PKOP2_SPEC -#undef STD_MMX_ARGS -#endif // CPU_HAS_MMX - -#if CPU_HAS_SSE -#define STD_SSE_ARGS : "m"(oout[0]), "m"(oin[0]) : "xmm0", "memory" -#define SSE_PKOP2_SPEC(n,type,optype,instruction) \ -SIMD_PKOP2_SPEC(n,type,optype) \ -{ asm ("movups %0, %%xmm0\n\tmovups %1, %%xmm1\n\t" #instruction " %%xmm1, %%xmm0\n\tmovups %%xmm0, %0" : STD_SSE_ARGS);} -#define SSE_PASSIGN_SPEC(n,type) \ -SIMD_PASSIGN_SPEC(n,type) \ -{ asm ("movups %1, %%xmm0\n\tmovups %%xmm0, %0" : STD_SSE_ARGS);} -#define SSE_IPASSIGN_SPEC(n,type) \ -SIMD_IPASSIGN_SPEC(n,type) \ -{ asm ("movups %1, %%xmm0\n\tmovups %%xmm0, %0" : STD_SSE_ARGS);} -SSE_PASSIGN_SPEC(4,float) -SSE_PASSIGN_SPEC(4,int32_t) -SSE_PASSIGN_SPEC(4,uint32_t) -SSE_PKOP2_SPEC(4,float,plus,addps) -SSE_PKOP2_SPEC(4,float,minus,subps) -SSE_PKOP2_SPEC(4,float,multiplies,mulps) -SSE_PKOP2_SPEC(4,float,divides,divps) -SSE_PKOP2_SPEC(4,float,bitwise_and,andps) -SSE_PKOP2_SPEC(4,float,bitwise_or,orps) -SSE_PKOP2_SPEC(4,float,bitwise_xor,xorps) -SSE_PKOP2_SPEC(4,float,fpmax,maxps) -SSE_PKOP2_SPEC(4,float,fpmin,minps) - -SIMD_CONVERT_SPEC(4,float,int32_t,fround) { - asm ("cvtps2pi %2, %%mm0\n\t" - "cvtps2pi %3, %%mm1\n\t" - "movq %%mm0, %0\n\t" - "movq %%mm1, %1" - : DBL_MMX_ARGS); - reset_mmx(); -} -SIMD_CONVERT_SPEC(4,int32_t,float,fround) { - asm ("cvtpi2ps %2, %%xmm0\n\t" - "shufps $0x4E,%%xmm0,%%xmm0\n\t" - "cvtpi2ps %1, %%xmm0\n\t" - "movups %%xmm0, %0" - :: "m"(oout[0]), "m"(oin[0]), "m"(oin[2]) : "xmm0", "memory"); -} -template <> inline int32_t fround<float,int32_t>::operator()(const float& a) const { - register int32_t rv; - asm ("movss %1, %%xmm0\n\t" - "cvtss2si %%xmm0, %0" - : "=r"(rv) : "m"(a) : "xmm0" ); - return (rv); -} -template <> inline uint32_t fround<float,uint32_t>::operator()(const float& a) const { - register uint32_t rv; - asm ("movss %1, %%xmm0\n\t" - "cvtss2si %%xmm0, %0" - : "=r"(rv) : "m"(a) : "xmm0" ); - return (rv); -} - -SSE_IPASSIGN_SPEC(4,float) -SSE_IPASSIGN_SPEC(4,int32_t) -SSE_IPASSIGN_SPEC(4,uint32_t) - -#undef SSE_IPASSIGN_SPEC -#undef SSE_PASSIGN_SPEC -#undef SSE_PKOP2_SPEC -#undef STD_SSE_ARGS -#endif // CPU_HAS_SSE - -#undef SIMDA_RI -#undef SIMDA_RO -#undef SIMDA_WI -#undef SIMDA_WO -#undef SIMD_PACKEDOP_SPEC - -} // namespace simd -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/sistream.h +++ /dev/null @@ -1,153 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef SISTREAM_H_0CCA102229A49F5D65EE852E62B27CE2 -#define SISTREAM_H_0CCA102229A49F5D65EE852E62B27CE2 - -#include "mistream.h" -#include "ustring.h" - -namespace ustl { - -/// \class istringstream sistream.h ustl.h -/// \ingroup TextStreams -/// -/// \brief A stream that reads textual data from a memory block. -/// -class istringstream : public istream { -public: - static const size_type c_MaxDelimiters = 16; ///< Maximum number of word delimiters. -public: - istringstream (void); - istringstream (const void* p, size_type n); - explicit istringstream (const cmemlink& source); - void iread (int8_t& v) { v = skip_delimiters(); } - void iread (int32_t& v); - void iread (double& v); - void iread (bool& v); - void iread (wchar_t& v); - void iread (string& v); -#if HAVE_INT64_T - void iread (int64_t& v); -#endif -#if HAVE_LONG_LONG && (!HAVE_INT64_T || SIZE_OF_LONG_LONG > 8) - void iread (long long& v); -#endif - inline string str (void) const { string s; s.link (*this); return (s); } - inline istringstream& str (const string& s) { link (s); return (*this); } - inline istringstream& get (char& c) { return (read (&c, sizeof(c))); } - inline int get (void) { char c; get(c); return (c); } - istringstream& get (char* p, size_type n, char delim = '\n'); - istringstream& get (string& s, char delim = '\n'); - istringstream& getline (char* p, size_type n, char delim = '\n'); - istringstream& getline (string& s, char delim = '\n'); - istringstream& ignore (size_type n, char delim = '\0'); - inline char peek (void) { int8_t v; iread (v); ungetc(); return (v); } - inline istringstream& putback (char) { ungetc(); return (*this); } - inline istringstream& unget (void) { ungetc(); return (*this); } - inline void set_delimiters (const char* delimiters); - inline void set_base (short base); - inline void set_decimal_separator (char) { } - inline void set_thousand_separator (char) { } - istringstream& read (void* buffer, size_type size); - inline istringstream& read (memlink& buf) { return (read (buf.begin(), buf.size())); } - inline istringstream& seekg (off_t p, seekdir d =beg) { istream::seekg(p,d); return (*this); } - inline int sync (void) { skip (remaining()); return (0); } -protected: - char skip_delimiters (void); -private: - inline void read_strz (string&) { assert (!"Reading nul characters is not allowed from text streams"); } - inline bool is_delimiter (char c) const; - template <typename T> void read_number (T& v); -private: - char m_Delimiters [c_MaxDelimiters]; - uint8_t m_Base; -}; - -//---------------------------------------------------------------------- - -/// Sets the numeric base used to read numbers. -inline void istringstream::set_base (short base) -{ - m_Base = base; -} - -/// Sets delimiters to the contents of \p delimiters. -inline void istringstream::set_delimiters (const char* delimiters) -{ -#if (__i386__ || __x86_64__) && CPU_HAS_SSE && HAVE_VECTOR_EXTENSIONS - typedef uint32_t v16ud_t __attribute__((vector_size(16))); - asm("xorps\t%%xmm0, %%xmm0\n\tmovups\t%%xmm0, %0":"=m"(*noalias_cast<v16ud_t*>(m_Delimiters))::"xmm0"); -#else - memset (m_Delimiters, 0, sizeof(m_Delimiters)); -#endif - memcpy (m_Delimiters, delimiters, min (strlen(delimiters),sizeof(m_Delimiters)-1)); -} - -/// Reads one type as another. -template <typename RealT, typename CastT> -inline void _cast_read (istringstream& is, RealT& v) -{ - CastT cv; - is.iread (cv); - v = RealT (cv); -} - -/// Reads a line of text from \p is into \p s -inline istringstream& getline (istringstream& is, string& s) - { return (is.getline (s)); } - -//---------------------------------------------------------------------- - -template <typename T> struct object_text_reader { - inline void operator()(istringstream& is, T& v) const { v.text_read (is); } -}; -template <typename T> struct integral_text_object_reader { - inline void operator()(istringstream& is, T& v) const { is.iread (v); } -}; -template <typename T> -inline istringstream& operator>> (istringstream& is, T& v) { - typedef typename tm::Select <numeric_limits<T>::is_integral, - integral_text_object_reader<T>, object_text_reader<T> >::Result object_reader_t; - object_reader_t()(is, v); - return (is); -} - -//---------------------------------------------------------------------- - -template <> struct object_text_reader<string> { - inline void operator()(istringstream& is, string& v) const { is.iread (v); } -}; -#define ISTRSTREAM_CAST_OPERATOR(RealT, CastT) \ -template <> struct integral_text_object_reader<RealT> { \ - inline void operator() (istringstream& is, RealT& v) const \ - { _cast_read<RealT,CastT>(is, v); } \ -}; -ISTRSTREAM_CAST_OPERATOR (uint8_t, int8_t) -ISTRSTREAM_CAST_OPERATOR (int16_t, int32_t) -ISTRSTREAM_CAST_OPERATOR (uint16_t, int32_t) -ISTRSTREAM_CAST_OPERATOR (uint32_t, int32_t) -ISTRSTREAM_CAST_OPERATOR (float, double) -#if HAVE_THREE_CHAR_TYPES -ISTRSTREAM_CAST_OPERATOR (char, int8_t) -#endif -#if HAVE_INT64_T -ISTRSTREAM_CAST_OPERATOR (uint64_t, int64_t) -#endif -#if SIZE_OF_LONG == SIZE_OF_INT -// This works only properly if stdint.h typedefs int to int32_t. If stdint.h -// typedefs long to int32_t then this causes compiler errors. So make shure -// that your stdint.h file typedefs int to int32_t. -ISTRSTREAM_CAST_OPERATOR (long, int) -ISTRSTREAM_CAST_OPERATOR (unsigned long,int) -#endif -#if HAVE_LONG_LONG && (!HAVE_INT64_T || SIZE_OF_LONG_LONG > 8) -ISTRSTREAM_CAST_OPERATOR (unsigned long long, long long) -#endif -#undef ISTRSTREAM_CAST_OPERATOR - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/sostream.h +++ /dev/null @@ -1,161 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef SOSTREAM_H_5323DC8C26E181D43278F2F53FDCF19F -#define SOSTREAM_H_5323DC8C26E181D43278F2F53FDCF19F - -#include "ustring.h" -#include "mostream.h" - -namespace ustl { - -class string; - -/// \class ostringstream sostream.h ustl.h -/// \ingroup TextStreams -/// -/// \brief This stream writes textual data into a memory block. -/// -class ostringstream : public ostream { -public: - ostringstream (const string& v = ""); - ostringstream (void* p, size_t n); - void iwrite (uint8_t v); - void iwrite (wchar_t v); - inline void iwrite (int v) { iformat (v); } - inline void iwrite (unsigned int v) { iformat (v); } - inline void iwrite (long int v) { iformat (v); } - inline void iwrite (unsigned long int v) { iformat (v); } - inline void iwrite (float v) { iformat (v); } - inline void iwrite (double v) { iformat (v); } - void iwrite (bool v); - inline void iwrite (const char* s) { write (s, strlen(s)); } - inline void iwrite (const string& v) { write (v.begin(), v.size()); } - inline void iwrite (fmtflags f); -#if HAVE_LONG_LONG - inline void iwrite (long long v) { iformat (v); } - inline void iwrite (unsigned long long v) { iformat (v); } -#endif - inline size_type max_size (void) const { return (m_Buffer.max_size()); } - inline ostringstream& put (char c) { iwrite (uint8_t(c)); return (*this); } - int vformat (const char* fmt, va_list args); - int format (const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))); - inline void set_base (uint16_t b) { m_Base = b; } - inline void set_width (uint16_t w) { m_Width = w; } - inline void set_decimal_separator (char) { } - inline void set_thousand_separator (char) { } - inline void set_precision (uint16_t v) { m_Precision = v; } - void link (void* p, size_type n); - inline void link (memlink& l) { link (l.data(), l.writable_size()); } - inline const string& str (void) { flush(); return (m_Buffer); } - void str (const string& s); - ostringstream& write (const void* buffer, size_type size); - inline ostringstream& write (const cmemlink& buf) { return (write (buf.begin(), buf.size())); } - inline ostringstream& seekp (off_t p, seekdir d =beg) { ostream::seekp(p,d); return (*this); } - ostringstream& flush (void) { m_Buffer.resize (pos()); return (*this); } - virtual size_type overflow (size_type n = 1); -protected: - inline void reserve (size_type n) { m_Buffer.reserve (n, false); } - inline size_type capacity (void) const { return (m_Buffer.capacity()); } -private: - inline void write_strz (const char*) { assert (!"Writing nul characters into a text stream is not allowed"); } - inline char* encode_dec (char* fmt, uint32_t n) const; - void fmtstring (char* fmt, const char* typestr, bool bInteger) const; - template <typename T> - void iformat (T v); -private: - string m_Buffer; ///< The output buffer. - uint32_t m_Flags; ///< See ios_base::fmtflags. - uint16_t m_Width; ///< Field width. - uint8_t m_Base; ///< Numeric base for writing numbers. - uint8_t m_Precision; ///< Number of digits after the decimal separator. -}; - -//---------------------------------------------------------------------- - -template <typename T> -inline const char* printf_typestring (const T&) { return (""); } -#define PRINTF_TYPESTRING_SPEC(type,str) \ -template <> inline const char* printf_typestring (const type&) { return (str); } -PRINTF_TYPESTRING_SPEC (int, "d") -PRINTF_TYPESTRING_SPEC (unsigned int, "u") -PRINTF_TYPESTRING_SPEC (long, "ld") -PRINTF_TYPESTRING_SPEC (unsigned long, "lu") -PRINTF_TYPESTRING_SPEC (float, "f") -PRINTF_TYPESTRING_SPEC (double, "lf") -#if HAVE_LONG_LONG -PRINTF_TYPESTRING_SPEC (long long, "lld") -PRINTF_TYPESTRING_SPEC (unsigned long long, "llu") -#endif -#undef PRINTF_TYPESTRING_SPEC - -template <typename T> -void ostringstream::iformat (T v) -{ - char fmt [16]; - fmtstring (fmt, printf_typestring(v), numeric_limits<T>::is_integer); - format (fmt, v); -} - -/// Sets the flag \p f in the stream. -inline void ostringstream::iwrite (fmtflags f) -{ - switch (f) { - case oct: set_base (8); break; - case dec: set_base (10); break; - case hex: set_base (16); break; - case left: m_Flags |= left; m_Flags &= ~right; break; - case right: m_Flags |= right; m_Flags &= ~left; break; - default: m_Flags |= f; break; - } -} - -//---------------------------------------------------------------------- - -template <typename T> struct object_text_writer { - inline void operator()(ostringstream& os, const T& v) const { v.text_write (os); } -}; -template <typename T> struct integral_text_object_writer { - inline void operator()(ostringstream& os, const T& v) const { os.iwrite (v); } -}; -template <typename T> -inline ostringstream& operator<< (ostringstream& os, const T& v) { - typedef typename tm::Select <numeric_limits<T>::is_integral, - integral_text_object_writer<T>, object_text_writer<T> >::Result object_writer_t; - object_writer_t()(os, v); - return (os); -} -// Needed because if called with a char[], numeric_limits will not work. Should be removed if I find out how to partial specialize for arrays... -inline ostringstream& operator<< (ostringstream& os, const char* v) - { os.iwrite (v); return (os); } -inline ostringstream& operator<< (ostringstream& os, char* v) - { os.iwrite (v); return (os); } - -//---------------------------------------------------------------------- - -template <> struct object_text_writer<string> { - inline void operator()(ostringstream& os, const string& v) const { os.iwrite (v); } -}; -template <typename T> struct integral_text_object_writer<T*> { - inline void operator() (ostringstream& os, const T* const& v) const - { os.iwrite ((uintptr_t)(v)); } -}; -#define OSTRSTREAM_CAST_OPERATOR(RealT, CastT) \ -template <> inline ostringstream& operator<< (ostringstream& os, const RealT& v) \ - { os.iwrite ((CastT)(v)); return (os); } -OSTRSTREAM_CAST_OPERATOR (uint8_t* const, const char*) -OSTRSTREAM_CAST_OPERATOR (int8_t, uint8_t) -OSTRSTREAM_CAST_OPERATOR (short int, int) -OSTRSTREAM_CAST_OPERATOR (unsigned short, unsigned int) -#if HAVE_THREE_CHAR_TYPES -OSTRSTREAM_CAST_OPERATOR (char, uint8_t) -#endif -#undef OSTRSTREAM_CAST_OPERATOR - -//---------------------------------------------------------------------- - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/strmsize.h +++ /dev/null @@ -1,82 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. -// -/// \file strmsize.h -/// \brief This file contains stream_size_of functions for basic types and *STREAMABLE macros. -/// stream_size_of functions return the size of the object's data that is written or -/// read from a stream. - -#ifndef STRMSIZE_H_052FF16B2D8A608761BF10333D065073 -#define STRMSIZE_H_052FF16B2D8A608761BF10333D065073 - -namespace ustl { - -/// For partial specialization of stream_size_of for objects -template <typename T> struct object_stream_size { - inline streamsize operator()(const T& v) const { return (v.stream_size()); } -}; -template <typename T> struct integral_object_stream_size { - inline streamsize operator()(const T& v) const { return (sizeof(v)); } -}; -/// Returns the size of the given object. Overloads for standard types are available. -template <typename T> -inline streamsize stream_size_of (const T& v) { - typedef typename tm::Select <numeric_limits<T>::is_integral, - integral_object_stream_size<T>, object_stream_size<T> >::Result stream_sizer_t; - return (stream_sizer_t()(v)); -} - -} // namespace ustl - -// -// Extra overloads in this macro are needed because it is the one used for -// marshalling pointers. Passing a pointer to stream_size_of creates a -// conversion ambiguity between converting to const pointer& and converting -// to bool; the compiler always chooses the bool conversion (because it -// requires 1 conversion instead of 2 for the other choice). There is little -// point in adding the overloads to other macros, since they are never used -// for pointers. -// -/// Declares that T is to be written as is into binary streams. -#define INTEGRAL_STREAMABLE(T) \ - namespace ustl { \ - inline istream& operator>> (istream& is, T& v) { is.iread(v); return (is); } \ - inline ostream& operator<< (ostream& os, const T& v) { os.iwrite(v); return (os); } \ - inline ostream& operator<< (ostream& os, T& v) { os.iwrite(v); return (os); } \ - template <> inline streamsize stream_size_of (const T& v) { return (sizeof(v)); } \ - } - -/// Declares that T contains read, write, and stream_size methods. This is no longer needed and is deprecated. -#define STD_STREAMABLE(T) - -/// Declares \p T to be writable to text streams. This is no longer needed and is deprecated. -#define TEXT_STREAMABLE(T) - -/// Declares that T is to be cast into TSUB for streaming. -#define CAST_STREAMABLE(T,TSUB) \ - namespace ustl { \ - inline istream& operator>> (istream& is, T& v) { TSUB sv; is >> sv; v = (T)(sv); return (is); } \ - inline ostream& operator<< (ostream& os, const T& v) { os << TSUB(v); return (os); } \ - template <> inline streamsize stream_size_of (const T& v) { return (stream_size_of (TSUB(v))); } \ - } - -/// Placed into a class it declares the methods required by STD_STREAMABLE. Syntactic sugar. -#define DECLARE_STD_STREAMABLE \ - public: \ - void read (istream& is); \ - void write (ostream& os) const; \ - streamsize stream_size (void) const - -/// Specifies that \p T is printed by using it as an index into \p Names string array. -#define LOOKUP_TEXT_STREAMABLE(T,Names,nNames) \ - namespace ustl { \ - inline ostringstream& operator<< (ostringstream& os, const T& v) \ - { \ - os << Names[min(uoff_t(v),uoff_t(nNames-1))]; \ - return (os); \ - } \ - } - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/traits.h +++ /dev/null @@ -1,251 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2007-2009 by Mike Sharov <msharov@users.sourceforge.net> -// -// This implementation is adapted from the Loki library, distributed under -// the MIT license with Copyright (c) 2001 by Andrei Alexandrescu. - -#ifndef TRAITS_H_4AA3DDE15E16C947392711ED08FB1FF6 -#define TRAITS_H_4AA3DDE15E16C947392711ED08FB1FF6 - -#include "typelist.h" - -namespace ustl { -namespace tm { -namespace { - -//---------------------------------------------------------------------- -// Type classes and type modifiers -//---------------------------------------------------------------------- - -typedef tl::Seq<unsigned char, unsigned short, unsigned, unsigned long>::Type - StdUnsignedInts; -typedef tl::Seq<signed char, short, int, long>::Type StdSignedInts; -typedef tl::Seq<bool, char, wchar_t>::Type StdOtherInts; -typedef tl::Seq<float, double>::Type StdFloats; - -template <typename U> struct AddPointer { typedef U* Result; }; -template <typename U> struct AddPointer<U&> { typedef U* Result; }; -template <typename U> struct AddReference { typedef U& Result; }; -template <typename U> struct AddReference<U&> { typedef U& Result; }; -template <> struct AddReference<void> { typedef NullType Result; }; -template <typename U> struct AddParameterType { typedef const U& Result; }; -template <typename U> struct AddParameterType<U&> { typedef U& Result; }; -template <> struct AddParameterType<void> { typedef NullType Result; }; - -//---------------------------------------------------------------------- -// Function pointer testers -//---------------------------------------------------------------------- -// Macros expand to numerous parameters - -template <typename T> -struct IsFunctionPointerRaw { enum { result = false}; }; -template <typename T> -struct IsMemberFunctionPointerRaw { enum { result = false}; }; - -#define TM_FPR_MAXN 9 -#define TM_FPR_TYPE(n) PASTE(T,n) -#define TM_FPR_TYPENAME(n) typename TM_FPR_TYPE(n) - -// First specialize for regular functions -template <typename T> -struct IsFunctionPointerRaw<T(*)(void)> -{enum {result = true};}; - -#define TM_FPR_SPEC(n) \ -template <typename T, COMMA_LIST(n, TM_FPR_TYPENAME)> \ -struct IsFunctionPointerRaw<T(*)(COMMA_LIST(n, TM_FPR_TYPE))> \ -{ enum { result = true }; } - -LIST (TM_FPR_MAXN, TM_FPR_SPEC, ;); - -// Then for those with an ellipsis argument -template <typename T> -struct IsFunctionPointerRaw<T(*)(...)> -{enum {result = true};}; - -#define TM_FPR_SPEC_ELLIPSIS(n) \ -template <typename T, COMMA_LIST(n, TM_FPR_TYPENAME)> \ -struct IsFunctionPointerRaw<T(*)(COMMA_LIST(n, TM_FPR_TYPE), ...)> \ -{ enum { result = true }; } - -LIST (TM_FPR_MAXN, TM_FPR_SPEC_ELLIPSIS, ;); - -// Then for member function pointers -template <typename T, typename S> -struct IsMemberFunctionPointerRaw<T (S::*)(void)> -{ enum { result = true }; }; - -#define TM_MFPR_SPEC(n) \ -template <typename T, typename S, COMMA_LIST(n, TM_FPR_TYPENAME)> \ -struct IsMemberFunctionPointerRaw<T (S::*)(COMMA_LIST(n, TM_FPR_TYPE))> \ -{ enum { result = true };}; - -LIST (TM_FPR_MAXN, TM_MFPR_SPEC, ;); - -// Then for member function pointers with an ellipsis argument -template <typename T, typename S> -struct IsMemberFunctionPointerRaw<T (S::*)(...)> -{ enum { result = true }; }; - -#define TM_MFPR_SPEC_ELLIPSIS(n) \ -template <typename T, typename S, COMMA_LIST(n, TM_FPR_TYPENAME)> \ -struct IsMemberFunctionPointerRaw<T (S::*)(COMMA_LIST(n, TM_FPR_TYPE), ...)> \ -{ enum { result = true }; }; - -LIST (TM_FPR_MAXN, TM_MFPR_SPEC_ELLIPSIS, ;); - -// Then for const member function pointers (getting tired yet?) -template <typename T, typename S> -struct IsMemberFunctionPointerRaw<T (S::*)(void) const> -{ enum { result = true }; }; - -#define TM_CMFPR_SPEC(n) \ -template <typename T, typename S, COMMA_LIST(n, TM_FPR_TYPENAME)> \ -struct IsMemberFunctionPointerRaw<T (S::*)(COMMA_LIST(n, TM_FPR_TYPE)) const> \ -{ enum { result = true };}; - -LIST (TM_FPR_MAXN, TM_CMFPR_SPEC, ;); - -// Finally for const member function pointers with an ellipsis argument (whew!) -template <typename T, typename S> -struct IsMemberFunctionPointerRaw<T (S::*)(...) const> -{ enum { result = true }; }; - -#define TM_CMFPR_SPEC_ELLIPSIS(n) \ -template <typename T, typename S, COMMA_LIST(n, TM_FPR_TYPENAME)> \ -struct IsMemberFunctionPointerRaw<T (S::*)(COMMA_LIST(n, TM_FPR_TYPE), ...) const> \ -{ enum { result = true }; }; - -LIST (TM_FPR_MAXN, TM_CMFPR_SPEC_ELLIPSIS, ;); - -#undef TM_FPR_SPEC -#undef TM_FPR_SPEC_ELLIPSIS -#undef TM_MFPR_SPEC -#undef TM_MFPR_SPEC_ELLIPSIS -#undef TM_CMFPR_SPEC -#undef TM_CMFPR_SPEC_ELLIPSIS -#undef TM_FPR_TYPENAME -#undef TM_FPR_TYPE -#undef TM_FPR_MAXN - -} // namespace - -//---------------------------------------------------------------------- -// Type traits template -//---------------------------------------------------------------------- - -/// Figures out at compile time various properties of any given type -/// Invocations (T is a type, TypeTraits<T>::Propertie): -/// -/// - isPointer : returns true if T is a pointer type -/// - PointeeType : returns the type to which T points if T is a pointer -/// type, NullType otherwise -/// - isReference : returns true if T is a reference type -/// - ReferredType : returns the type to which T refers if T is a reference -/// type, NullType otherwise -/// - isMemberPointer : returns true if T is a pointer to member type -/// - isStdUnsignedInt: returns true if T is a standard unsigned integral type -/// - isStdSignedInt : returns true if T is a standard signed integral type -/// - isStdIntegral : returns true if T is a standard integral type -/// - isStdFloat : returns true if T is a standard floating-point type -/// - isStdArith : returns true if T is a standard arithmetic type -/// - isStdFundamental: returns true if T is a standard fundamental type -/// - isUnsignedInt : returns true if T is a unsigned integral type -/// - isSignedInt : returns true if T is a signed integral type -/// - isIntegral : returns true if T is a integral type -/// - isFloat : returns true if T is a floating-point type -/// - isArith : returns true if T is a arithmetic type -/// - isFundamental : returns true if T is a fundamental type -/// - ParameterType : returns the optimal type to be used as a parameter for -/// functions that take Ts -/// - isConst : returns true if T is a const-qualified type -/// - NonConstType : Type with removed 'const' qualifier from T, if any -/// - isVolatile : returns true if T is a volatile-qualified type -/// - NonVolatileType : Type with removed 'volatile' qualifier from T, if any -/// - UnqualifiedType : Type with removed 'const' and 'volatile' qualifiers from -/// T, if any -/// - ConstParameterType: returns the optimal type to be used as a parameter -/// for functions that take 'const T's -/// -template <typename T> -class TypeTraits { -private: - #define TMTT1 template <typename U> struct - #define TMTT2 template <typename U, typename V> struct - TMTT1 ReferenceTraits { enum { result = false }; typedef U ReferredType; }; - TMTT1 ReferenceTraits<U&> { enum { result = true }; typedef U ReferredType; }; - TMTT1 PointerTraits { enum { result = false }; typedef NullType PointeeType; }; - TMTT1 PointerTraits<U*> { enum { result = true }; typedef U PointeeType; }; - TMTT1 PointerTraits<U*&> { enum { result = true }; typedef U PointeeType; }; - TMTT1 PToMTraits { enum { result = false }; }; - TMTT2 PToMTraits<U V::*> { enum { result = true }; }; - TMTT2 PToMTraits<U V::*&> { enum { result = true }; }; - TMTT1 FunctionPointerTraits { enum { result = IsFunctionPointerRaw<U>::result }; }; - TMTT1 PToMFunctionTraits { enum { result = IsMemberFunctionPointerRaw<U>::result }; }; - TMTT1 UnConst { typedef U Result; enum { isConst = false }; }; - TMTT1 UnConst<const U> { typedef U Result; enum { isConst = true }; }; - TMTT1 UnConst<const U&> { typedef U& Result; enum { isConst = true }; }; - TMTT1 UnVolatile { typedef U Result; enum { isVolatile = false }; }; - TMTT1 UnVolatile<volatile U>{ typedef U Result; enum { isVolatile = true }; }; - TMTT1 UnVolatile<volatile U&> {typedef U& Result;enum { isVolatile = true }; }; - #undef TMTT2 - #undef TMTT1 -public: - typedef typename UnConst<T>::Result - NonConstType; - typedef typename UnVolatile<T>::Result - NonVolatileType; - typedef typename UnVolatile<typename UnConst<T>::Result>::Result - UnqualifiedType; - typedef typename PointerTraits<UnqualifiedType>::PointeeType - PointeeType; - typedef typename ReferenceTraits<T>::ReferredType - ReferredType; - - enum { isConst = UnConst<T>::isConst }; - enum { isVolatile = UnVolatile<T>::isVolatile }; - enum { isReference = ReferenceTraits<UnqualifiedType>::result }; - enum { isFunction = FunctionPointerTraits<typename AddPointer<T>::Result >::result }; - enum { isFunctionPointer= FunctionPointerTraits< - typename ReferenceTraits<UnqualifiedType>::ReferredType >::result }; - enum { isMemberFunctionPointer= PToMFunctionTraits< - typename ReferenceTraits<UnqualifiedType>::ReferredType >::result }; - enum { isMemberPointer = PToMTraits< - typename ReferenceTraits<UnqualifiedType>::ReferredType >::result || - isMemberFunctionPointer }; - enum { isPointer = PointerTraits< - typename ReferenceTraits<UnqualifiedType>::ReferredType >::result || - isFunctionPointer }; - enum { isStdUnsignedInt = tl::IndexOf<StdUnsignedInts, UnqualifiedType>::value >= 0 || - tl::IndexOf<StdUnsignedInts, - typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0}; - enum { isStdSignedInt = tl::IndexOf<StdSignedInts, UnqualifiedType>::value >= 0 || - tl::IndexOf<StdSignedInts, - typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0}; - enum { isStdIntegral = isStdUnsignedInt || isStdSignedInt || - tl::IndexOf<StdOtherInts, UnqualifiedType>::value >= 0 || - tl::IndexOf<StdOtherInts, - typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0}; - enum { isStdFloat = tl::IndexOf<StdFloats, UnqualifiedType>::value >= 0 || - tl::IndexOf<StdFloats, - typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0}; - enum { isStdArith = isStdIntegral || isStdFloat }; - enum { isStdFundamental = isStdArith || isStdFloat || Conversion<T, void>::sameType }; - - enum { isUnsignedInt = isStdUnsignedInt }; - enum { isSignedInt = isStdSignedInt }; - enum { isIntegral = isStdIntegral || isUnsignedInt || isSignedInt }; - enum { isFloat = isStdFloat }; - enum { isArith = isIntegral || isFloat }; - enum { isFundamental = isStdFundamental || isArith }; - - typedef typename Select<isStdArith || isPointer || isMemberPointer, T, - typename AddParameterType<T>::Result>::Result - ParameterType; -}; - -} // namespace tm -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/typelist.h +++ /dev/null @@ -1,223 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2007-2009 by Mike Sharov <msharov@users.sourceforge.net> -// -// This implementation is adapted from the Loki library, distributed under -// the MIT license with Copyright (c) 2001 by Andrei Alexandrescu. - -#ifndef TYPELIST_H_2A8F84704780530D531716D41B3EA3FE -#define TYPELIST_H_2A8F84704780530D531716D41B3EA3FE - -#include "metamac.h" -#include "typet.h" - -namespace ustl { -namespace tm { - -/// The building block of typelists. Use it throught the Seq templates. -template <typename T, typename U> -struct Typelist { - typedef T Head; - typedef U Tail; -}; - -/// Namespace containing typelist-related functionality. -namespace tl { - -//---------------------------------------------------------------------- -// Seq template definitions. The macros expand to a spec per arg count -// -#define TL_MAX_SEQ_TYPES 9 -#define TL_MAX_SEQ_SPECS 8 -#define TL_SEQ_TYPE(n) T##n -#define TL_SEQ_TYPENAME(n) typename TL_SEQ_TYPE(n) -#define TL_SEQ_NULLTYPE_DEFAULT(n) TL_SEQ_TYPENAME(n)=NullType -#define TL_SEQ_TL_END(n) > -#define TL_SEQ_ONE_TYPELIST(n) Typelist<TL_SEQ_TYPE(n) - -/// Creates a typelist from a sequence of types -template <COMMA_LIST(TL_MAX_SEQ_TYPES,TL_SEQ_NULLTYPE_DEFAULT)> -struct Seq { - typedef COMMA_LIST(TL_MAX_SEQ_TYPES,TL_SEQ_ONE_TYPELIST), - NullType REPEAT(TL_MAX_SEQ_TYPES,TL_SEQ_TL_END) Type; -}; - -#define TL_SEQ_SPEC(n) \ -template <COMMA_LIST (n, TL_SEQ_TYPENAME)> \ -struct Seq<COMMA_LIST (n, TL_SEQ_TYPE)> { \ - typedef COMMA_LIST(n,TL_SEQ_ONE_TYPELIST), \ - NullType REPEAT(n,TL_SEQ_TL_END) Type; \ -} -LIST(TL_MAX_SEQ_SPECS,TL_SEQ_SPEC, ;); - -#undef TL_SEQ_SPEC -#undef TL_SEQ_TL_END -#undef TL_SEQ_ONE_TYPELIST -#undef TL_SEQ_NULLTYPE_DEFAULT -#undef TL_SEQ_TYPE -#undef TL_MAX_SEQ_SPECS - -//---------------------------------------------------------------------- -// Various utility functions follow. - -/// Length<List>::value is the number of types in the typelist. -template <typename List> struct Length { }; -template <> struct Length<NullType> { enum { value = 0 }; }; -template <typename T, typename U> -struct Length<Typelist<T, U> > { enum { value = 1 + Length<U>::value }; }; - -/// TypeAt<List, i>::Result is the ith type in List -template <typename List, unsigned index> struct TypeAt { }; -template <class Head, class Tail> -struct TypeAt<Typelist<Head, Tail>, 0> { - typedef Head Result; -}; -template <class Head, class Tail, unsigned index> -struct TypeAt<Typelist<Head, Tail>, index> { - typedef typename TypeAt<Tail, index-1>::Result Result; -}; - -/// TypeAtNonStrict<List,i,DefaultType>::Result is List[i] or DefaultType if out of range. -template <typename List, unsigned index, typename DefaultType = NullType> -struct TypeAtNonStrict { - typedef DefaultType Result; -}; -template <typename Head, typename Tail, typename DefaultType> -struct TypeAtNonStrict<Typelist<Head, Tail>, 0, DefaultType> { - typedef Head Result; -}; -template <typename Head, typename Tail, unsigned index, typename DefaultType> -struct TypeAtNonStrict<Typelist<Head, Tail>, index, DefaultType> { - typedef typename TypeAtNonStrict<Tail, index-1, DefaultType>::Result Result; -}; - -/// IndexOf<List,T>::value is the position of T in List, or -1 if not found. -template <typename List, typename T> struct IndexOf; -template <typename T> -struct IndexOf<NullType, T> { enum { value = -1 }; }; -template <typename T, typename Tail> -struct IndexOf<Typelist<T, Tail>, T> { enum { value = 0 }; }; -template <typename Head, typename Tail, typename T> -struct IndexOf<Typelist<Head, Tail>, T> { -private: - enum { iintail = IndexOf<Tail, T>::value }; -public: - enum { value = (iintail == -1 ? -1 : 1+iintail) }; -}; - -/// Appends a type or a typelist to another in Append<TList, T>::Result -template <typename List, typename T> struct Append; -template <> struct Append<NullType, NullType> { typedef NullType Result; }; -template <typename T> struct Append<NullType, T> { - typedef Typelist<T,NullType> Result; -}; -template <typename Head, typename Tail> -struct Append<NullType, Typelist<Head, Tail> > { - typedef Typelist<Head, Tail> Result; -}; -template <typename Head, typename Tail, typename T> -struct Append<Typelist<Head, Tail>, T> { - typedef Typelist<Head, typename Append<Tail, T>::Result> Result; -}; - -// Erase<List, T>::Result contains List without the first T. -template <typename TList, typename T> struct Erase; -template <typename T> -struct Erase<NullType, T> { typedef NullType Result; }; -template <typename T, typename Tail> -struct Erase<Typelist<T, Tail>, T> { typedef Tail Result; }; -template <typename Head, typename Tail, typename T> -struct Erase<Typelist<Head, Tail>, T> { - typedef Typelist<Head, typename Erase<Tail, T>::Result> Result; -}; - -// EraseAll<List, T>::Result contains List without any T. -template <typename List, typename T> struct EraseAll; -template <typename T> -struct EraseAll<NullType, T> { typedef NullType Result; }; -template <typename T, typename Tail> -struct EraseAll<Typelist<T, Tail>, T> { - typedef typename EraseAll<Tail, T>::Result Result; -}; -template <typename Head, typename Tail, typename T> -struct EraseAll<Typelist<Head, Tail>, T> { - typedef Typelist<Head, typename EraseAll<Tail, T>::Result> Result; -}; - -/// Removes all duplicate types in a typelist -template <typename List> struct NoDuplicates; -template <> struct NoDuplicates<NullType> { typedef NullType Result; }; -template <typename Head, typename Tail> -struct NoDuplicates< Typelist<Head, Tail> > { -private: - typedef typename NoDuplicates<Tail>::Result L1; - typedef typename Erase<L1, Head>::Result L2; -public: - typedef Typelist<Head, L2> Result; -}; - -// Replaces the first occurence of a type in a typelist, with another type -template <typename List, typename T, typename U> struct Replace; -template <typename T, typename U> -struct Replace<NullType, T, U> { typedef NullType Result; }; -template <typename T, typename Tail, typename U> -struct Replace<Typelist<T, Tail>, T, U> { - typedef Typelist<U, Tail> Result; -}; -template <typename Head, typename Tail, typename T, typename U> -struct Replace<Typelist<Head, Tail>, T, U> { - typedef Typelist<Head, typename Replace<Tail, T, U>::Result> Result; -}; - -// Replaces all occurences of a type in a typelist, with another type -template <typename List, typename T, typename U> struct ReplaceAll; -template <typename T, typename U> -struct ReplaceAll<NullType, T, U> { typedef NullType Result; }; -template <typename T, typename Tail, typename U> -struct ReplaceAll<Typelist<T, Tail>, T, U> { - typedef Typelist<U, typename ReplaceAll<Tail, T, U>::Result> Result; -}; -template <typename Head, typename Tail, typename T, typename U> -struct ReplaceAll<Typelist<Head, Tail>, T, U> { - typedef Typelist<Head, typename ReplaceAll<Tail, T, U>::Result> Result; -}; - -// Reverses a typelist -template <typename List> struct Reverse; -template <> struct Reverse<NullType> { typedef NullType Result; }; -template <typename Head, typename Tail> -struct Reverse< Typelist<Head, Tail> > { - typedef typename Append<typename Reverse<Tail>::Result, Head>::Result Result; -}; - -// Finds the type in a typelist that is the most derived from a given type -template <typename List, typename T> struct MostDerived; -template <typename T> struct MostDerived<NullType, T> { typedef T Result; }; -template <typename Head, typename Tail, typename T> -struct MostDerived<Typelist<Head, Tail>, T> { -private: - typedef typename MostDerived<Tail, T>::Result Candidate; -public: - typedef typename Select<SuperSubclass<Candidate,Head>::value, Head, Candidate>::Result Result; -}; - -// Arranges the types in a typelist so that the most derived types appear first -template <typename List> struct DerivedToFront; -template <> struct DerivedToFront<NullType> { typedef NullType Result; }; -template <typename Head, typename Tail> -struct DerivedToFront< Typelist<Head, Tail> > { -private: - typedef typename MostDerived<Tail, Head>::Result TheMostDerived; - typedef typename Replace<Tail, TheMostDerived, Head>::Result Temp; - typedef typename DerivedToFront<Temp>::Result L; -public: - typedef Typelist<TheMostDerived, L> Result; -}; - -//---------------------------------------------------------------------- - -} // namespace tl -} // namespace tm -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/typet.h +++ /dev/null @@ -1,98 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2007-2009 by Mike Sharov <msharov@users.sourceforge.net> -// -// This implementation is adapted from the Loki library, distributed under -// the MIT license with Copyright (c) 2001 by Andrei Alexandrescu. - -#ifndef TYPET_H_70B4C9693A05E0B405B225F356DE5450 -#define TYPET_H_70B4C9693A05E0B405B225F356DE5450 - -namespace ustl { -/// Template metaprogramming tools -namespace tm { - -/// An empty type useful as a placeholder. -class NullType { }; - -/// Converts an integer to a type. -template <int v> struct Int2Type { enum { value = v }; }; - -/// Converts an type to a unique empty type. -template <typename T> struct Type2Type { typedef T OriginalType; }; - -/// Selects type Result = flag ? T : U -template <bool flag, typename T, typename U> -struct Select { typedef T Result; }; -template <typename T, typename U> -struct Select<false, T, U> { typedef U Result; }; - -/// IsSameType<T,U>::value is true when T=U -template <typename T, typename U> -struct IsSameType { enum { value = false }; }; -template <typename T> -struct IsSameType<T,T> { enum { value = true }; }; - -/// \brief Checks for conversion possibilities between T and U -/// Conversion<T,U>::exists is true if T is convertible to U -/// Conversion<T,U>::exists2Way is true if U is also convertible to T -/// Conversion<T,U>::sameType is true if U is T -template <typename T, typename U> -class Conversion { - typedef char UT; - typedef short TT; - static UT Test (U); - static TT Test (...); - static T MakeT (void); -public: - enum { - exists = sizeof(UT) == sizeof(Test(MakeT())), - exists2Way = exists && Conversion<U,T>::exists, - sameType = false - }; -}; -template <typename T> -struct Conversion<T, T> { enum { exists = true, exists2Way = true, sameType = true }; }; -template <typename T> -struct Conversion<void, T> { enum { exists = false, exists2Way = false, sameType = false }; }; -template <typename T> -struct Conversion<T, void> { enum { exists = false, exists2Way = false, sameType = false }; }; -template <> -struct Conversion<void, void> { enum { exists = true, exists2Way = true, sameType = true }; }; - -/// SuperSubclass<T,U>::value is true when U is derived from T, or when U is T -template <typename T, typename U> -struct SuperSubclass { - enum { value = (::ustl::tm::Conversion<const volatile U*, const volatile T*>::exists && - !::ustl::tm::Conversion<const volatile T*, const volatile void*>::sameType) }; - enum { dontUseWithIncompleteTypes = sizeof(T)==sizeof(U) }; // Dummy enum to make sure that both classes are fully defined. -}; -template <> -struct SuperSubclass<void, void> { enum { value = false }; }; -template <typename U> -struct SuperSubclass<void, U> { - enum { value = false }; - enum { dontUseWithIncompleteTypes = 0==sizeof(U) }; -}; -template <typename T> -struct SuperSubclass<T, void> { - enum { value = false }; - enum { dontUseWithIncompleteTypes = 0==sizeof(T) }; -}; - -/// SuperSubclassStrict<T,U>::value is true when U is derived from T -template <typename T, typename U> -struct SuperSubclassStrict { - enum { value = SuperSubclass<T,U>::value && - !::ustl::tm::Conversion<const volatile T*, const volatile U*>::sameType }; -}; - -// static assert support -template <bool> struct CompileTimeError; -template <> struct CompileTimeError<true> {}; -#define static_assert(cond,msg) { ::ustl::tm::CompileTimeError<!!(cond)> ERROR_##msg; (void) ERROR_##msg; } - -} // namespace tm -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/ualgo.h +++ /dev/null @@ -1,667 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UALGO_H_711AB4214D417A51166694D47A662D6E -#define UALGO_H_711AB4214D417A51166694D47A662D6E - -#include "upair.h" -#include "ualgobase.h" -#include "ufunction.h" -#include "upredalgo.h" -#include "umemory.h" -#include <stdlib.h> // for rand() - -namespace ustl { - -/// Swaps corresponding elements of [first, last) and [result,) -/// \ingroup SwapAlgorithms -/// -template <typename ForwardIterator1, typename ForwardIterator2> -inline ForwardIterator2 swap_ranges (ForwardIterator1 first, ForwardIterator2 last, ForwardIterator2 result) -{ - for (; first != last; ++first, ++result) - iter_swap (first, result); - return (result); -} - -/// Returns the first iterator i in the range [first, last) such that -/// *i == value. Returns last if no such iterator exists. -/// \ingroup SearchingAlgorithms -/// -template <typename InputIterator, typename EqualityComparable> -inline InputIterator find (InputIterator first, InputIterator last, const EqualityComparable& value) -{ - while (first != last && !(*first == value)) - ++ first; - return (first); -} - -/// Returns the first iterator such that *i == *(i + 1) -/// \ingroup SearchingAlgorithms -/// -template <typename ForwardIterator> -ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last) -{ - if (first != last) - for (ForwardIterator prev = first; ++first != last; ++ prev) - if (*prev == *first) - return (prev); - return (last); -} - -/// Returns the pointer to the first pair of unequal elements. -/// \ingroup SearchingAlgorithms -/// -template <typename InputIterator> -pair<InputIterator,InputIterator> -mismatch (InputIterator first1, InputIterator last1, InputIterator first2) -{ - while (first1 != last1 && *first1 == *first2) - ++ first1, ++ first2; - return (make_pair (first1, first2)); -} - -/// \brief Returns true if two ranges are equal. -/// This is an extension, present in uSTL and SGI STL. -/// \ingroup SearchingAlgorithms -/// -template <typename InputIterator> -inline bool equal (InputIterator first1, InputIterator last1, InputIterator first2) -{ - return (mismatch (first1, last1, first2).first == last1); -} - -/// Count finds the number of elements in [first, last) that are equal -/// to value. More precisely, the first version of count returns the -/// number of iterators i in [first, last) such that *i == value. -/// \ingroup SearchingAlgorithms -/// -template <typename InputIterator, typename EqualityComparable> -inline size_t count (InputIterator first, InputIterator last, const EqualityComparable& value) -{ - size_t total = 0; - for (; first != last; ++first) - if (*first == value) - ++ total; - return (total); -} - -/// -/// The first version of transform performs the operation op(*i) for each -/// iterator i in the range [first, last), and assigns the result of that -/// operation to *o, where o is the corresponding output iterator. That is, -/// for each n such that 0 <= n < last - first, it performs the assignment -/// *(result + n) = op(*(first + n)). -/// The return value is result + (last - first). -/// \ingroup MutatingAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename InputIterator, typename OutputIterator, typename UnaryFunction> -inline OutputIterator transform (InputIterator first, InputIterator last, OutputIterator result, UnaryFunction op) -{ - for (; first != last; ++result, ++first) - *result = op (*first); - return (result); -} - -/// -/// The second version of transform is very similar, except that it uses a -/// Binary Function instead of a Unary Function: it performs the operation -/// op(*i1, *i2) for each iterator i1 in the range [first1, last1) and assigns -/// the result to *o, where i2 is the corresponding iterator in the second -/// input range and where o is the corresponding output iterator. That is, -/// for each n such that 0 <= n < last1 - first1, it performs the assignment -/// *(result + n) = op(*(first1 + n), *(first2 + n). -/// The return value is result + (last1 - first1). -/// \ingroup MutatingAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename InputIterator1, typename InputIterator2, typename OutputIterator, typename BinaryFunction> -inline OutputIterator transform (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryFunction op) -{ - for (; first1 != last1; ++result, ++first1, ++first2) - *result = op (*first1, *first2); - return (result); -} - -/// Replace replaces every element in the range [first, last) equal to -/// old_value with new_value. That is: for every iterator i, -/// if *i == old_value then it performs the assignment *i = new_value. -/// \ingroup MutatingAlgorithms -/// -template <typename ForwardIterator, typename T> -inline void replace (ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value) -{ - for (; first != last; ++first) - if (*first == old_value) - *first = new_value; -} - -/// Replace_copy copies elements from the range [first, last) to the range -/// [result, result + (last-first)), except that any element equal to old_value -/// is not copied; new_value is copied instead. More precisely, for every -/// integer n such that 0 <= n < last-first, replace_copy performs the -/// assignment *(result+n) = new_value if *(first+n) == old_value, and -/// *(result+n) = *(first+n) otherwise. -/// \ingroup MutatingAlgorithms -/// -template <typename InputIterator, typename OutputIterator, typename T> -inline OutputIterator replace_copy (InputIterator first, InputIterator last, OutputIterator result, const T& old_value, const T& new_value) -{ - for (; first != last; ++result, ++first) - *result = (*first == old_value) ? new_value : *first; -} - -/// Generate assigns the result of invoking gen, a function object that -/// takes no arguments, to each element in the range [first, last). -/// \ingroup GeneratorAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename ForwardIterator, typename Generator> -inline void generate (ForwardIterator first, ForwardIterator last, Generator gen) -{ - for (; first != last; ++first) - *first = gen(); -} - -/// Generate_n assigns the result of invoking gen, a function object that -/// takes no arguments, to each element in the range [first, first+n). -/// The return value is first + n. -/// \ingroup GeneratorAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename OutputIterator, typename Generator> -inline OutputIterator generate_n (OutputIterator first, size_t n, Generator gen) -{ - for (uoff_t i = 0; i != n; ++i, ++first) - *first = gen(); - return (first); -} - -/// \brief Reverse reverses a range. -/// That is: for every i such that 0 <= i <= (last - first) / 2), -/// it exchanges *(first + i) and *(last - (i + 1)). -/// \ingroup MutatingAlgorithms -/// -template <typename BidirectionalIterator> -inline void reverse (BidirectionalIterator first, BidirectionalIterator last) -{ - for (; distance (first, --last) > 0; ++first) - iter_swap (first, last); -} - -/// \brief Reverses [first,last) and writes it to \p output. -/// \ingroup MutatingAlgorithms -/// -template <typename BidirectionalIterator, typename OutputIterator> -inline OutputIterator reverse_copy (BidirectionalIterator first, BidirectionalIterator last, OutputIterator result) -{ - for (; first != last; ++result) - *result = *--last; - return (result); -} - -/// \brief Exchanges ranges [first, middle) and [middle, last) -/// \ingroup MutatingAlgorithms -/// -template <typename ForwardIterator> -ForwardIterator rotate (ForwardIterator first, ForwardIterator middle, ForwardIterator last) -{ - if (first == middle || middle == last) - return (first); - reverse (first, middle); - reverse (middle, last); - for (;first != middle && middle != last; ++first) - iter_swap (first, --last); - reverse (first, (first == middle ? last : middle)); - return (first); -} - -/// Specialization for pointers, which can be treated identically. -template <typename T> -inline T* rotate (T* first, T* middle, T* last) -{ - rotate_fast (first, middle, last); - return (first); -} - - -/// \brief Exchanges ranges [first, middle) and [middle, last) into \p result. -/// \ingroup MutatingAlgorithms -/// -template <typename ForwardIterator, typename OutputIterator> -inline OutputIterator rotate_copy (ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator result) -{ - return (copy (first, middle, copy (middle, last, result))); -} - -/// \brief Combines two sorted ranges. -/// \ingroup SortingAlgorithms -/// -template <typename InputIterator1, typename InputIterator2, typename OutputIterator> -OutputIterator merge (InputIterator1 first1, InputIterator1 last1, - InputIterator2 first2, InputIterator2 last2, OutputIterator result) -{ - for (; first1 != last1 && first2 != last2; ++result) { - if (*first1 < *first2) - *result = *first1++; - else - *result = *first2++; - } - if (first1 < last1) - return (copy (first1, last1, result)); - else - return (copy (first2, last2, result)); -} - -/// Combines two sorted ranges from the same container. -/// \ingroup SortingAlgorithms -/// -template <typename InputIterator> -void inplace_merge (InputIterator first, InputIterator middle, InputIterator last) -{ - for (; middle != last; ++first) { - while (*first < *middle) - ++ first; - reverse (first, middle); - reverse (first, ++middle); - } -} - -/// Remove_copy copies elements that are not equal to value from the range -/// [first, last) to a range beginning at result. The return value is the -/// end of the resulting range. This operation is stable, meaning that the -/// relative order of the elements that are copied is the same as in the -/// range [first, last). -/// \ingroup MutatingAlgorithms -/// -template <typename InputIterator, typename OutputIterator, typename T> -OutputIterator remove_copy (InputIterator first, InputIterator last, OutputIterator result, const T& value) -{ - for (; first != last; ++first) { - if (!(*first == value)) { - *result = *first; - ++ result; - } - } - return (result); -} - -/// Remove_copy copies elements pointed to by iterators in [rfirst, rlast) -/// from the range [first, last) to a range beginning at result. The return -/// value is the end of the resulting range. This operation is stable, meaning -/// that the relative order of the elements that are copied is the same as in the -/// range [first, last). Range [rfirst, rlast) is assumed to be sorted. -/// This algorithm is a uSTL extension. -/// \ingroup MutatingAlgorithms -/// -template <typename InputIterator, typename OutputIterator, typename RInputIterator> -OutputIterator remove_copy (InputIterator first, InputIterator last, OutputIterator result, RInputIterator rfirst, RInputIterator rlast) -{ - for (; first != last; ++first) { - while (rfirst != rlast && *rfirst < first) - ++ rfirst; - if (rfirst == rlast || first != *rfirst) { - *result = *first; - ++ result; - } - } - return (result); -} - -/// Remove removes from the range [first, last) all elements that are equal to -/// value. That is, remove returns an iterator new_last such that the range -/// [first, new_last) contains no elements equal to value. [1] The iterators -/// in the range [new_last, last) are all still dereferenceable, but the -/// elements that they point to are unspecified. Remove is stable, meaning -/// that the relative order of elements that are not equal to value is -/// unchanged. -/// \ingroup MutatingAlgorithms -/// -template <typename ForwardIterator, typename T> -inline ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& value) -{ - return (remove_copy (first, last, first, value)); -} - -/// Unique_copy copies elements from the range [first, last) to a range -/// beginning with result, except that in a consecutive group of duplicate -/// elements only the first one is copied. The return value is the end of -/// the range to which the elements are copied. This behavior is similar -/// to the Unix filter uniq. -/// \ingroup MutatingAlgorithms -/// -template <typename InputIterator, typename OutputIterator> -OutputIterator unique_copy (InputIterator first, InputIterator last, OutputIterator result) -{ - if (first != last) { - *result = *first; - while (++first != last) - if (!(*first == *result)) - *++result = *first; - ++ result; - } - return (result); -} - -/// Every time a consecutive group of duplicate elements appears in the range -/// [first, last), the algorithm unique removes all but the first element. -/// That is, unique returns an iterator new_last such that the range [first, -/// new_last) contains no two consecutive elements that are duplicates. -/// The iterators in the range [new_last, last) are all still dereferenceable, -/// but the elements that they point to are unspecified. Unique is stable, -/// meaning that the relative order of elements that are not removed is -/// unchanged. -/// \ingroup MutatingAlgorithms -/// -template <typename ForwardIterator> -inline ForwardIterator unique (ForwardIterator first, ForwardIterator last) -{ - return (unique_copy (first, last, first)); -} - -/// Returns the furthermost iterator i in [first, last) such that, -/// for every iterator j in [first, i), *j < value -/// Assumes the range is sorted. -/// \ingroup SearchingAlgorithms -/// -template <typename ForwardIterator, typename LessThanComparable> -ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const LessThanComparable& value) -{ - ForwardIterator mid; - while (first != last) { - mid = advance (first, distance (first,last) / 2); - if (*mid < value) - first = mid + 1; - else - last = mid; - } - return (first); -} - -/// Performs a binary search inside the sorted range. -/// \ingroup SearchingAlgorithms -/// -template <typename ForwardIterator, typename LessThanComparable> -inline bool binary_search (ForwardIterator first, ForwardIterator last, const LessThanComparable& value) -{ - ForwardIterator found = lower_bound (first, last, value); - return (found != last && !(value < *found)); -} - -/// Returns the furthermost iterator i in [first,last) such that for -/// every iterator j in [first,i), value < *j is false. -/// \ingroup SearchingAlgorithms -/// -template <typename ForwardIterator, typename LessThanComparable> -ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const LessThanComparable& value) -{ - ForwardIterator mid; - while (first != last) { - mid = advance (first, distance (first,last) / 2); - if (value < *mid) - last = mid; - else - first = mid + 1; - } - return (last); -} - -/// Returns pair<lower_bound,upper_bound> -/// \ingroup SearchingAlgorithms -/// -template <typename ForwardIterator, typename LessThanComparable> -inline pair<ForwardIterator,ForwardIterator> equal_range (ForwardIterator first, ForwardIterator last, const LessThanComparable& value) -{ - pair<ForwardIterator,ForwardIterator> rv; - rv.second = rv.first = lower_bound (first, last, value); - while (rv.second != last && !(value < *(rv.second))) - ++ rv.second; - return (rv); -} - -/// Randomly permute the elements of the container. -/// \ingroup GeneratorAlgorithms -/// -template <typename RandomAccessIterator> -void random_shuffle (RandomAccessIterator first, RandomAccessIterator last) -{ - for (; first != last; ++ first) - iter_swap (first, first + (rand() % distance (first, last))); -} - -/// \brief Generic compare function adaptor to pass to qsort -/// \ingroup FunctorObjects -template <typename ConstPointer, typename Compare> -int qsort_adapter (const void* p1, const void* p2) -{ - ConstPointer i1 = reinterpret_cast<ConstPointer>(p1); - ConstPointer i2 = reinterpret_cast<ConstPointer>(p2); - Compare comp; - return (comp (*i1, *i2) ? -1 : (comp (*i2, *i1) ? 1 : 0)); -} - -/// Sorts the container -/// \ingroup SortingAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename RandomAccessIterator, typename Compare> -void sort (RandomAccessIterator first, RandomAccessIterator last, Compare) -{ - typedef typename iterator_traits<RandomAccessIterator>::value_type value_type; - typedef typename iterator_traits<RandomAccessIterator>::const_pointer const_pointer; - qsort (first, distance (first, last), sizeof(value_type), - &qsort_adapter<const_pointer, Compare>); -} - -/// Sorts the container -/// \ingroup SortingAlgorithms -/// -template <typename RandomAccessIterator> -inline void sort (RandomAccessIterator first, RandomAccessIterator last) -{ - typedef typename iterator_traits<RandomAccessIterator>::value_type value_type; - sort (first, last, less<value_type>()); -} - -/// Sorts the container preserving order of equal elements. -/// \ingroup SortingAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename RandomAccessIterator, typename Compare> -void stable_sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp) -{ - for (RandomAccessIterator j, i = first; ++i < last;) { // Insertion sort - for (j = i; j-- > first && comp(*i, *j);) ; - if (++j != i) rotate (j, i, i + 1); - } -} - -/// Sorts the container -/// \ingroup SortingAlgorithms -/// -template <typename RandomAccessIterator> -inline void stable_sort (RandomAccessIterator first, RandomAccessIterator last) -{ - typedef typename iterator_traits<RandomAccessIterator>::value_type value_type; - stable_sort (first, last, less<value_type>()); -} - -/// \brief Searches for the first subsequence [first2,last2) in [first1,last1) -/// \ingroup SearchingAlgorithms -template <typename ForwardIterator1, typename ForwardIterator2> -inline ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) -{ - typedef typename iterator_traits<ForwardIterator1>::value_type value_type; - return (search (first1, last1, first2, last2, equal_to<value_type>())); -} - -/// \brief Searches for the last subsequence [first2,last2) in [first1,last1) -/// \ingroup SearchingAlgorithms -template <typename ForwardIterator1, typename ForwardIterator2> -inline ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) -{ - typedef typename iterator_traits<ForwardIterator1>::value_type value_type; - return (find_end (first1, last1, first2, last2, equal_to<value_type>())); -} - -/// \brief Searches for the first occurence of \p count \p values in [first, last) -/// \ingroup SearchingAlgorithms -template <typename Iterator, typename T> -inline Iterator search_n (Iterator first, Iterator last, size_t count, const T& value) -{ - typedef typename iterator_traits<Iterator>::value_type value_type; - return (search_n (first, last, count, value, equal_to<value_type>())); -} - -/// \brief Searches [first1,last1) for the first occurrence of an element from [first2,last2) -/// \ingroup SearchingAlgorithms -template <typename InputIterator, typename ForwardIterator> -inline InputIterator find_first_of (InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2) -{ - typedef typename iterator_traits<InputIterator>::value_type value_type; - return (find_first_of (first1, last1, first2, last2, equal_to<value_type>())); -} - -/// \brief Returns true if [first2,last2) is a subset of [first1,last1) -/// \ingroup ConditionAlgorithms -/// \ingroup SetAlgorithms -template <typename InputIterator1, typename InputIterator2> -inline bool includes (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2) -{ - typedef typename iterator_traits<InputIterator1>::value_type value_type; - return (includes (first1, last1, first2, last2, less<value_type>())); -} - -/// \brief Merges [first1,last1) with [first2,last2) -/// -/// Result will contain every element that is in either set. If duplicate -/// elements are present, max(n,m) is placed in the result. -/// -/// \ingroup SetAlgorithms -template <typename InputIterator1, typename InputIterator2, typename OutputIterator> -inline OutputIterator set_union (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) -{ - typedef typename iterator_traits<InputIterator1>::value_type value_type; - return (set_union (first1, last1, first2, last2, result, less<value_type>())); -} - -/// \brief Creates a set containing elements shared by the given ranges. -/// \ingroup SetAlgorithms -template <typename InputIterator1, typename InputIterator2, typename OutputIterator> -inline OutputIterator set_intersection (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) -{ - typedef typename iterator_traits<InputIterator1>::value_type value_type; - return (set_intersection (first1, last1, first2, last2, result, less<value_type>())); -} - -/// \brief Removes from [first1,last1) elements present in [first2,last2) -/// \ingroup SetAlgorithms -template <typename InputIterator1, typename InputIterator2, typename OutputIterator> -inline OutputIterator set_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) -{ - typedef typename iterator_traits<InputIterator1>::value_type value_type; - return (set_difference (first1, last1, first2, last2, result, less<value_type>())); -} - -/// \brief Performs union of sets A-B and B-A. -/// \ingroup SetAlgorithms -template <typename InputIterator1, typename InputIterator2, typename OutputIterator> -inline OutputIterator set_symmetric_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) -{ - typedef typename iterator_traits<InputIterator1>::value_type value_type; - return (set_symmetric_difference (first1, last1, first2, last2, result, less<value_type>())); -} - -/// \brief Returns true if the given range is sorted. -/// \ingroup ConditionAlgorithms -template <typename ForwardIterator> -inline bool is_sorted (ForwardIterator first, ForwardIterator last) -{ - typedef typename iterator_traits<ForwardIterator>::value_type value_type; - return (is_sorted (first, last, less<value_type>())); -} - -/// \brief Compares two given containers like strcmp compares strings. -/// \ingroup ConditionAlgorithms -template <typename InputIterator1, typename InputIterator2> -inline bool lexicographical_compare (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2) -{ - typedef typename iterator_traits<InputIterator1>::value_type value_type; - return (lexicographical_compare (first1, last1, first2, last2, less<value_type>())); -} - -/// \brief Creates the next lexicographical permutation of [first,last). -/// Returns false if no further permutations can be created. -/// \ingroup GeneratorAlgorithms -template <typename BidirectionalIterator> -inline bool next_permutation (BidirectionalIterator first, BidirectionalIterator last) -{ - typedef typename iterator_traits<BidirectionalIterator>::value_type value_type; - return (next_permutation (first, last, less<value_type>())); -} - -/// \brief Creates the previous lexicographical permutation of [first,last). -/// Returns false if no further permutations can be created. -/// \ingroup GeneratorAlgorithms -template <typename BidirectionalIterator> -inline bool prev_permutation (BidirectionalIterator first, BidirectionalIterator last) -{ - typedef typename iterator_traits<BidirectionalIterator>::value_type value_type; - return (prev_permutation (first, last, less<value_type>())); -} - -/// \brief Returns iterator to the max element in [first,last) -/// \ingroup SearchingAlgorithms -template <typename ForwardIterator> -inline ForwardIterator max_element (ForwardIterator first, ForwardIterator last) -{ - typedef typename iterator_traits<ForwardIterator>::value_type value_type; - return (max_element (first, last, less<value_type>())); -} - -/// \brief Returns iterator to the min element in [first,last) -/// \ingroup SearchingAlgorithms -template <typename ForwardIterator> -inline ForwardIterator min_element (ForwardIterator first, ForwardIterator last) -{ - typedef typename iterator_traits<ForwardIterator>::value_type value_type; - return (min_element (first, last, less<value_type>())); -} - -/// \brief Makes [first,middle) a part of the sorted array. -/// Contents of [middle,last) is undefined. This implementation just calls stable_sort. -/// \ingroup SortingAlgorithms -template <typename RandomAccessIterator> -inline void partial_sort (RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last) -{ - typedef typename iterator_traits<RandomAccessIterator>::value_type value_type; - partial_sort (first, middle, last, less<value_type>()); -} - -/// \brief Puts \p nth element into its sorted position. -/// In this implementation, the entire array is sorted. I can't think of any -/// use for it where the time gained would be useful. -/// \ingroup SortingAlgorithms -/// \ingroup SearchingAlgorithms -/// -template <typename RandomAccessIterator> -inline void nth_element (RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last) -{ - partial_sort (first, nth, last); -} - -/// \brief Like partial_sort, but outputs to [result_first,result_last) -/// \ingroup SortingAlgorithms -template <typename InputIterator, typename RandomAccessIterator> -inline RandomAccessIterator partial_sort_copy (InputIterator first, InputIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last) -{ - typedef typename iterator_traits<InputIterator>::value_type value_type; - return (partial_sort_copy (first, last, result_first, result_last, less<value_type>())); -} - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/ualgobase.h +++ /dev/null @@ -1,321 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UALGOBASE_H_683A0BE77546133C4CE0E3622CFAA2EB -#define UALGOBASE_H_683A0BE77546133C4CE0E3622CFAA2EB - -#include "uutility.h" -#include <string.h> - -namespace ustl { - -/// Assigns the contents of a to b and the contents of b to a. -/// This is used as a primitive operation by many other algorithms. -/// \ingroup SwapAlgorithms -/// -template <typename Assignable> -inline void swap (Assignable& a, Assignable& b) -{ - Assignable tmp = a; - a = b; - b = tmp; -} - -/// Equivalent to swap (*a, *b) -/// \ingroup SwapAlgorithms -/// -template <typename Iterator> -inline void iter_swap (Iterator a, Iterator b) -{ - swap (*a, *b); -} - -/// Copy copies elements from the range [first, last) to the range -/// [result, result + (last - first)). That is, it performs the assignments -/// *result = *first, *(result + 1) = *(first + 1), and so on. [1] Generally, -/// for every integer n from 0 to last - first, copy performs the assignment -/// *(result + n) = *(first + n). Assignments are performed in forward order, -/// i.e. in order of increasing n. -/// \ingroup MutatingAlgorithms -/// -template <typename InputIterator, typename OutputIterator> -inline OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result) -{ - for (; first != last; ++result, ++first) - *result = *first; - return (result); -} - -/// Copy_n copies elements from the range [first, first + n) to the range -/// [result, result + n). That is, it performs the assignments -/// *result = *first, *(result + 1) = *(first + 1), and so on. Generally, -/// for every integer i from 0 up to (but not including) n, copy_n performs -/// the assignment *(result + i) = *(first + i). Assignments are performed -/// in forward order, i.e. in order of increasing n. -/// \ingroup MutatingAlgorithms -/// -template <typename InputIterator, typename OutputIterator> -inline OutputIterator copy_n (InputIterator first, size_t count, OutputIterator result) -{ - for (; count; --count, ++result, ++first) - *result = *first; - return (result); -} - -/// \brief Copy copies elements from the range (last, first] to result. -/// \ingroup MutatingAlgorithms -/// Copies elements starting at last, decrementing both last and result. -/// -template <typename InputIterator, typename OutputIterator> -inline OutputIterator copy_backward (InputIterator first, InputIterator last, OutputIterator result) -{ - while (first != last) - *--result = *--last; - return (result); -} - -/// For_each applies the function object f to each element in the range -/// [first, last); f's return value, if any, is ignored. Applications are -/// performed in forward order, i.e. from first to last. For_each returns -/// the function object after it has been applied to each element. -/// \ingroup MutatingAlgorithms -/// -template <typename InputIterator, typename UnaryFunction> -inline UnaryFunction for_each (InputIterator first, InputIterator last, UnaryFunction f) -{ - for (; first != last; ++first) - f (*first); - return (f); -} - -/// Fill assigns the value value to every element in the range [first, last). -/// That is, for every iterator i in [first, last), -/// it performs the assignment *i = value. -/// \ingroup GeneratorAlgorithms -/// -template <typename ForwardIterator, typename T> -inline void fill (ForwardIterator first, ForwardIterator last, const T& value) -{ - for (; first != last; ++first) - *first = value; -} - -/// Fill_n assigns the value value to every element in the range -/// [first, first+count). That is, for every iterator i in [first, first+count), -/// it performs the assignment *i = value. The return value is first + count. -/// \ingroup GeneratorAlgorithms -/// -template <typename OutputIterator, typename T> -inline OutputIterator fill_n (OutputIterator first, size_t count, const T& value) -{ - for (; count; --count, ++first) - *first = value; - return (first); -} - -#if CPU_HAS_MMX -extern "C" void copy_n_fast (const void* src, size_t count, void* dest) throw(); -#else -inline void copy_n_fast (const void* src, size_t count, void* dest) throw() - { memcpy (dest, src, count); } -#endif -#if __i386__ || __x86_64__ -extern "C" void copy_backward_fast (const void* first, const void* last, void* result) throw(); -#else -inline void copy_backward_fast (const void* first, const void* last, void* result) throw() -{ - const size_t nBytes (distance (first, last)); - memmove (advance (result, -nBytes), first, nBytes); -} -#endif -extern "C" void fill_n8_fast (uint8_t* dest, size_t count, uint8_t v) throw(); -extern "C" void fill_n16_fast (uint16_t* dest, size_t count, uint16_t v) throw(); -extern "C" void fill_n32_fast (uint32_t* dest, size_t count, uint32_t v) throw(); -extern "C" void rotate_fast (void* first, void* middle, void* last) throw(); - -#if __GNUC__ >= 4 -/// \brief Computes the number of 1 bits in a number. -/// \ingroup ConditionAlgorithms -inline size_t popcount (uint32_t v) { return (__builtin_popcount (v)); } -#if HAVE_INT64_T -inline size_t popcount (uint64_t v) { return (__builtin_popcountll (v)); } -#endif -#else -size_t popcount (uint32_t v); -#if HAVE_INT64_T -size_t popcount (uint64_t v); -#endif // HAVE_INT64_T -#endif // __GNUC__ - -//---------------------------------------------------------------------- -// Optimized versions for standard types -//---------------------------------------------------------------------- - -#if WANT_UNROLLED_COPY - -template <typename T> -inline T* unrolled_copy (const T* first, size_t count, T* result) -{ - copy_n_fast (first, count * sizeof(T), result); - return (advance (result, count)); -} - -template <> -inline uint8_t* copy_backward (const uint8_t* first, const uint8_t* last, uint8_t* result) -{ - copy_backward_fast (first, last, result); - return (result); -} - -template <typename T> -inline T* unrolled_fill (T* result, size_t count, T value) -{ - for (; count; --count, ++result) - *result = value; - return (result); -} -template <> inline uint8_t* unrolled_fill (uint8_t* result, size_t count, uint8_t value) - { fill_n8_fast (result, count, value); return (advance (result, count)); } -template <> inline uint16_t* unrolled_fill (uint16_t* result, size_t count, uint16_t value) - { fill_n16_fast (result, count, value); return (advance (result, count)); } -template <> inline uint32_t* unrolled_fill (uint32_t* result, size_t count, uint32_t value) - { fill_n32_fast (result, count, value); return (advance (result, count)); } -template <> inline float* unrolled_fill (float* result, size_t count, float value) - { fill_n32_fast ((uint32_t*) result, count, *noalias_cast<uint32_t*>(&value)); return (advance (result, count)); } - -#if CPU_HAS_MMX -#define UNROLLED_COPY_SPECIALIZATION(type) \ -template <> inline type* copy (const type* first, const type* last, type* result) \ -{ return (unrolled_copy (first, distance (first, last), result)); } \ -template <> inline type* copy_n (const type* first, size_t count, type* result) \ -{ return (unrolled_copy (first, count, result)); } -#define UNROLLED_FILL_SPECIALIZATION(type) \ -template <> inline void fill (type* first, type* last, const type& value) \ -{ unrolled_fill (first, distance (first, last), value); } \ -template <> inline type* fill_n (type* first, size_t count, const type& value) \ -{ return (unrolled_fill (first, count, value)); } -UNROLLED_COPY_SPECIALIZATION(uint8_t) -UNROLLED_FILL_SPECIALIZATION(uint8_t) -UNROLLED_COPY_SPECIALIZATION(uint16_t) -UNROLLED_FILL_SPECIALIZATION(uint16_t) -UNROLLED_COPY_SPECIALIZATION(uint32_t) -UNROLLED_FILL_SPECIALIZATION(uint32_t) -UNROLLED_COPY_SPECIALIZATION(float) -UNROLLED_FILL_SPECIALIZATION(float) -#undef UNROLLED_FILL_SPECIALIZATION -#undef UNROLLED_COPY_SPECIALIZATION -#endif // WANT_UNROLLED_COPY -#endif // CPU_HAS_MMX - -// Specializations for void* and char*, aliasing the above optimized versions. -// -// All these need duplication with const and non-const arguments, since -// otherwise the compiler will default to the unoptimized version for -// pointers not const in the caller's context, such as local variables. -// These are all inline, but they sure slow down compilation... :( -// -#define COPY_ALIAS_FUNC(ctype, type, alias_type) \ -template <> inline type* copy (ctype* first, ctype* last, type* result) \ -{ return ((type*) copy ((const alias_type*) first, (const alias_type*) last, (alias_type*) result)); } -#if WANT_UNROLLED_COPY -#if HAVE_THREE_CHAR_TYPES -COPY_ALIAS_FUNC(const char, char, uint8_t) -COPY_ALIAS_FUNC(char, char, uint8_t) -#endif -COPY_ALIAS_FUNC(const int8_t, int8_t, uint8_t) -COPY_ALIAS_FUNC(int8_t, int8_t, uint8_t) -COPY_ALIAS_FUNC(uint8_t, uint8_t, uint8_t) -COPY_ALIAS_FUNC(const int16_t, int16_t, uint16_t) -COPY_ALIAS_FUNC(int16_t, int16_t, uint16_t) -COPY_ALIAS_FUNC(uint16_t, uint16_t, uint16_t) -#if CPU_HAS_MMX || (SIZE_OF_LONG > 4) -COPY_ALIAS_FUNC(const int32_t, int32_t, uint32_t) -COPY_ALIAS_FUNC(int32_t, int32_t, uint32_t) -COPY_ALIAS_FUNC(uint32_t, uint32_t, uint32_t) -#endif -#endif -COPY_ALIAS_FUNC(const void, void, uint8_t) -COPY_ALIAS_FUNC(void, void, uint8_t) -#undef COPY_ALIAS_FUNC -#define COPY_BACKWARD_ALIAS_FUNC(ctype, type, alias_type) \ -template <> inline type* copy_backward (ctype* first, ctype* last, type* result) \ -{ return ((type*) copy_backward ((const alias_type*) first, (const alias_type*) last, (alias_type*) result)); } -#if WANT_UNROLLED_COPY -#if HAVE_THREE_CHAR_TYPES -COPY_BACKWARD_ALIAS_FUNC(char, char, uint8_t) -#endif -COPY_BACKWARD_ALIAS_FUNC(uint8_t, uint8_t, uint8_t) -COPY_BACKWARD_ALIAS_FUNC(int8_t, int8_t, uint8_t) -COPY_BACKWARD_ALIAS_FUNC(uint16_t, uint16_t, uint8_t) -COPY_BACKWARD_ALIAS_FUNC(const uint16_t, uint16_t, uint8_t) -COPY_BACKWARD_ALIAS_FUNC(int16_t, int16_t, uint8_t) -COPY_BACKWARD_ALIAS_FUNC(const int16_t, int16_t, uint8_t) -#endif -COPY_BACKWARD_ALIAS_FUNC(void, void, uint8_t) -COPY_BACKWARD_ALIAS_FUNC(const void, void, uint8_t) -#undef COPY_BACKWARD_ALIAS_FUNC -#define FILL_ALIAS_FUNC(type, alias_type, v_type) \ -template <> inline void fill (type* first, type* last, const v_type& value) \ -{ fill ((alias_type*) first, (alias_type*) last, (const alias_type&) value); } -FILL_ALIAS_FUNC(void, uint8_t, char) -FILL_ALIAS_FUNC(void, uint8_t, uint8_t) -#if WANT_UNROLLED_COPY -#if HAVE_THREE_CHAR_TYPES -FILL_ALIAS_FUNC(char, uint8_t, char) -FILL_ALIAS_FUNC(char, uint8_t, uint8_t) -#endif -FILL_ALIAS_FUNC(int8_t, uint8_t, int8_t) -FILL_ALIAS_FUNC(int16_t, uint16_t, int16_t) -#if CPU_HAS_MMX || (SIZE_OF_LONG > 4) -FILL_ALIAS_FUNC(int32_t, uint32_t, int32_t) -#endif -#endif -#undef FILL_ALIAS_FUNC -#define COPY_N_ALIAS_FUNC(ctype, type, alias_type) \ -template <> inline type* copy_n (ctype* first, size_t count, type* result) \ -{ return ((type*) copy_n ((const alias_type*) first, count, (alias_type*) result)); } -COPY_N_ALIAS_FUNC(const void, void, uint8_t) -COPY_N_ALIAS_FUNC(void, void, uint8_t) -#if WANT_UNROLLED_COPY -#if HAVE_THREE_CHAR_TYPES -COPY_N_ALIAS_FUNC(const char, char, uint8_t) -COPY_N_ALIAS_FUNC(char, char, uint8_t) -#endif -COPY_N_ALIAS_FUNC(int8_t, int8_t, uint8_t) -COPY_N_ALIAS_FUNC(uint8_t, uint8_t, uint8_t) -COPY_N_ALIAS_FUNC(const int8_t, int8_t, uint8_t) -COPY_N_ALIAS_FUNC(int16_t, int16_t, uint16_t) -COPY_N_ALIAS_FUNC(uint16_t, uint16_t, uint16_t) -COPY_N_ALIAS_FUNC(const int16_t, int16_t, uint16_t) -#if CPU_HAS_MMX || (SIZE_OF_LONG > 4) -COPY_N_ALIAS_FUNC(int32_t, int32_t, uint32_t) -COPY_N_ALIAS_FUNC(uint32_t, uint32_t, uint32_t) -COPY_N_ALIAS_FUNC(const int32_t, int32_t, uint32_t) -#endif -#endif -#undef COPY_N_ALIAS_FUNC -#define FILL_N_ALIAS_FUNC(type, alias_type, v_type) \ -template <> inline type* fill_n (type* first, size_t n, const v_type& value) \ -{ return ((type*) fill_n ((alias_type*) first, n, (const alias_type&) value)); } -FILL_N_ALIAS_FUNC(void, uint8_t, char) -FILL_N_ALIAS_FUNC(void, uint8_t, uint8_t) -#if WANT_UNROLLED_COPY -#if HAVE_THREE_CHAR_TYPES -FILL_N_ALIAS_FUNC(char, uint8_t, char) -FILL_N_ALIAS_FUNC(char, uint8_t, uint8_t) -#endif -FILL_N_ALIAS_FUNC(int8_t, uint8_t, int8_t) -FILL_N_ALIAS_FUNC(int16_t, uint16_t, int16_t) -#if CPU_HAS_MMX || (SIZE_OF_LONG > 4) -FILL_N_ALIAS_FUNC(int32_t, uint32_t, int32_t) -#endif -#endif -#undef FILL_N_ALIAS_FUNC - -extern const char _FmtPrtChr[2][8]; - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/ubitset.h +++ /dev/null @@ -1,129 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UBITSET_H_7B6450EC1400CBA45DCE0127739F82EE -#define UBITSET_H_7B6450EC1400CBA45DCE0127739F82EE - -#include "ustring.h" -#include "ufunction.h" - -namespace ustl { - -typedef uint32_t bitset_value_type; - -void convert_to_bitstring (const bitset_value_type* v, size_t n, string& buf); -void convert_from_bitstring (const string& buf, bitset_value_type* v, size_t n); - -/// \class bitset ubitset.h ustl.h -/// \ingroup Sequences -/// -/// \brief bitset is a fixed-size block of memory with addressable bits. -/// -/// Normally used for state flags; allows setting and unsetting of individual -/// bits as well as bitwise operations on the entire set. The interface is -/// most like that of unsigned integers, and is intended to be used as such. -/// If you were using begin() and end() functions in STL's bitset, you would -/// not be able to do the same thing here, because those functions return -/// host type iterators, not bits. -/// -template <size_t Size> -class bitset { -public: - typedef bitset_value_type value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef pointer iterator; - typedef const_pointer const_iterator; - typedef size_t difference_type; - typedef size_t size_type; -private: - static const size_t s_WordBits = BitsInType (value_type); - static const size_t s_nWords = Size / s_WordBits + ((Size % s_WordBits) != 0); - static const size_t s_nBits = s_nWords * s_WordBits; -private: - inline value_type& BitRef (uoff_t n) { assert (n < Size); return (m_Bits [n / s_WordBits]); } - inline value_type BitRef (uoff_t n) const { assert (n < Size); return (m_Bits [n / s_WordBits]); } - inline value_type Mask (uoff_t n) const { assert (n < Size); return (1 << (n % s_WordBits)); } -public: - inline bitset (value_type v = 0) { fill_n (m_Bits, s_nWords, 0); m_Bits[0] = v; } - inline bitset (const string& buf) { convert_from_bitstring (buf, m_Bits, s_nWords); } - inline void flip (uoff_t n) { BitRef(n) ^= Mask(n); } - inline void reset (void) { fill_n (m_Bits, s_nWords, 0); } - inline void clear (void) { fill_n (m_Bits, s_nWords, 0); } - inline void set (void) { fill_n (m_Bits, s_nWords, -1); } - inline bitset operator~ (void) const { bitset rv (*this); rv.flip(); return (rv); } - inline size_type size (void) const { return (Size); } - inline size_type capacity (void) const { return (s_nBits); } - inline bool test (uoff_t n) const { return (BitRef(n) & Mask(n)); } - inline bool operator[] (uoff_t n) const { return (test(n)); } - inline const_iterator begin (void) const { return (m_Bits); } - inline iterator begin (void) { return (m_Bits); } - inline const_iterator end (void) const { return (m_Bits + s_nWords); } - inline iterator end (void) { return (m_Bits + s_nWords); } - /// Returns the value_type with the equivalent bits. If size() > 1, you'll get only the first BitsInType(value_type) bits. - inline value_type to_value (void) const { return (m_Bits[0]); } - /// Flips all the bits in the set. - inline void flip (void) { transform (begin(), end(), begin(), bitwise_not<value_type>()); } - /// Sets or clears bit \p n. - inline void set (uoff_t n, bool val = true) - { - value_type& br (BitRef (n)); - const value_type mask (Mask (n)); - const value_type bOn (br | mask), bOff (br & ~mask); - br = val ? bOn : bOff; - } - // Sets the value of the bitrange \p first through \p last to the equivalent number of bits from \p v. - inline void set (uoff_t first, uoff_t DebugArg(last), value_type v) - { - assert (size_t (distance (first, last)) <= s_WordBits && "Bit ranges must be 32 bits or smaller"); - assert (first / s_WordBits == last / s_WordBits && "Bit ranges can not cross dword (4 byte) boundary"); - assert ((v & BitMask(value_type,distance(first,last))) == v && "The value is too large to fit in the given bit range"); - BitRef(first) |= v << (first % s_WordBits); - } - /// Clears the bit \p n. - inline void reset (uoff_t n) { set (n, false); } - /// Returns a string with bits MSB "001101001..." LSB. - inline string to_string (void) const - { - string rv (Size, '0'); - convert_to_bitstring (m_Bits, s_nWords, rv); - return (rv); - } - inline value_type at (uoff_t n) const { return (test(n)); } - /// Returns the value in bits \p first through \p last. - inline value_type at (uoff_t first, uoff_t last) const - { - assert (size_t (distance (first, last)) <= s_WordBits && "Bit ranges must be 32 bits or smaller"); - assert (first / s_WordBits == last / s_WordBits && "Bit ranges can not cross dword (4 byte) boundary"); - return ((BitRef(first) >> (first % s_WordBits)) & BitMask(value_type,distance(first, last))); - } - inline bool any (void) const { value_type sum = 0; foreach (const_iterator, i, *this) sum |= *i; return (sum); } - inline bool none (void) const { return (!any()); } - inline size_t count (void) const { size_t sum = 0; foreach (const_iterator, i, *this) sum += popcount(*i); return (sum); } - inline bool operator== (const bitset<Size>& v) const - { return (s_nWords == 1 ? (m_Bits[0] == v.m_Bits[0]) : equal (begin(), end(), v.begin())); } - inline const bitset operator& (const bitset<Size>& v) - { bitset<Size> result; transform (begin(), end(), v.begin(), result.begin(), bitwise_and<value_type>()); return (result); } - inline const bitset operator| (const bitset<Size>& v) - { bitset<Size> result; transform (begin(), end(), v.begin(), result.begin(), bitwise_or<value_type>()); return (result); } - inline const bitset operator^ (const bitset<Size>& v) - { bitset<Size> result; transform (begin(), end(), v.begin(), result.begin(), bitwise_xor<value_type>()); return (result); } - inline const bitset& operator&= (const bitset<Size>& v) - { transform (begin(), end(), v.begin(), begin(), bitwise_and<value_type>()); return (*this); } - inline const bitset& operator|= (const bitset<Size>& v) - { transform (begin(), end(), v.begin(), begin(), bitwise_or<value_type>()); return (*this); } - inline const bitset& operator^= (const bitset<Size>& v) - { transform (begin(), end(), v.begin(), begin(), bitwise_xor<value_type>()); return (*this); } - inline void read (istream& is) { nr_container_read (is, *this); } - inline void write (ostream& os) const { nr_container_write (os, *this); } - inline void text_write (ostringstream& os) const { os << to_string(); } - inline size_t stream_size (void) const { return (sizeof(m_Bits)); } -private: - value_type m_Bits [s_nWords]; -}; - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/uctralgo.h +++ /dev/null @@ -1,470 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UCTRALGO_H_0D1AEDFA74B09791489FE25B1EC644B0 -#define UCTRALGO_H_0D1AEDFA74B09791489FE25B1EC644B0 - -namespace ustl { - -/// Copy copies elements from the range [first, last) to the range -/// [result, result + (last - first)). That is, it performs the assignments -/// *result = *first, *(result + 1) = *(first + 1), and so on. [1] Generally, -/// for every integer n from 0 to last - first, copy performs the assignment -/// *(result + n) = *(first + n). Assignments are performed in forward order, -/// i.e. in order of increasing n. -/// \ingroup MutatingAlgorithms -/// -template <typename Container, typename OutputIterator> -inline OutputIterator copy (const Container& ctr, OutputIterator result) -{ - return (copy (ctr.begin(), ctr.end(), result)); -} - -/// Copy_if copies elements from the range [first, last) to the range -/// [result, result + (last - first)) if pred(*i) returns true. -/// \ingroup MutatingAlgorithms -/// -template <typename Container, typename OutputIterator, typename Predicate> -inline OutputIterator copy_if (Container& ctr, OutputIterator result, Predicate pred) -{ - return (copy_if (ctr.begin(), ctr.end(), result, pred)); -} - -/// For_each applies the function object f to each element in the range -/// [first, last); f's return value, if any, is ignored. Applications are -/// performed in forward order, i.e. from first to last. For_each returns -/// the function object after it has been applied to each element. -/// \ingroup MutatingAlgorithms -/// -template <typename Container, typename UnaryFunction> -inline UnaryFunction for_each (Container& ctr, UnaryFunction f) -{ - return (for_each (ctr.begin(), ctr.end(), f)); -} - -/// For_each applies the function object f to each element in the range -/// [first, last); f's return value, if any, is ignored. Applications are -/// performed in forward order, i.e. from first to last. For_each returns -/// the function object after it has been applied to each element. -/// \ingroup MutatingAlgorithms -/// -template <typename Container, typename UnaryFunction> -inline UnaryFunction for_each (const Container& ctr, UnaryFunction f) -{ - return (for_each (ctr.begin(), ctr.end(), f)); -} - -/// Returns the first iterator i in the range [first, last) such that -/// *i == value. Returns last if no such iterator exists. -/// \ingroup SearchingAlgorithms -/// -template <typename Container, typename EqualityComparable> -inline typename Container::const_iterator find (const Container& ctr, const EqualityComparable& value) -{ - return (find (ctr.begin(), ctr.end(), value)); -} -template <typename Container, typename EqualityComparable> -inline typename Container::iterator find (Container& ctr, const EqualityComparable& value) -{ - return (find (ctr.begin(), ctr.end(), value)); -} - -/// Returns the first iterator i in the range [first, last) such that -/// pred(*i) is true. Returns last if no such iterator exists. -/// \ingroup SearchingAlgorithms -/// -template <typename Container, typename Predicate> -inline typename Container::const_iterator find_if (const Container& ctr, Predicate pred) -{ - return (find_if (ctr.begin(), ctr.end(), pred)); -} -template <typename Container, typename Predicate> -inline typename Container::iterator find_if (Container& ctr, Predicate pred) -{ - return (find_if (ctr.begin(), ctr.end(), pred)); -} - -/// Count finds the number of elements in [first, last) that are equal -/// to value. More precisely, the first version of count returns the -/// number of iterators i in [first, last) such that *i == value. -/// \ingroup ConditionAlgorithms -/// -template <typename Container, typename EqualityComparable> -inline size_t count (const Container& ctr, const EqualityComparable& value) -{ - return (count (ctr.begin(), ctr.end(), value)); -} - -/// Count_if finds the number of elements in [first, last) that satisfy the -/// predicate pred. More precisely, the first version of count_if returns the -/// number of iterators i in [first, last) such that pred(*i) is true. -/// \ingroup ConditionAlgorithms -/// -template <typename Container, typename Predicate> -inline size_t count_if (const Container& ctr, Predicate pred) -{ - return (count_if (ctr.begin(), ctr.end(), pred)); -} - -/// The first version of transform performs the operation op(*i) for each -/// iterator i in the range [first, last), and assigns the result of that -/// operation to *o, where o is the corresponding output iterator. That is, -/// for each n such that 0 <= n < last - first, it performs the assignment -/// *(result + n) = op(*(first + n)). -/// The return value is result + (last - first). -/// \ingroup MutatingAlgorithms -/// -template <typename Container, typename UnaryFunction> -inline void transform (Container& ctr, UnaryFunction op) -{ - transform (ctr.begin(), ctr.end(), ctr.begin(), op); -} - -/// The first version of transform performs the operation op(*i) for each -/// iterator i in the range [first, last), and assigns the result of that -/// operation to *o, where o is the corresponding output iterator. That is, -/// for each n such that 0 <= n < last - first, it performs the assignment -/// *(result + n) = op(*(first + n)). -/// The return value is result + (last - first). -/// \ingroup MutatingAlgorithms -/// -template <typename Container, typename OutputIterator, typename UnaryFunction> -inline OutputIterator transform (Container& ctr, OutputIterator result, UnaryFunction op) -{ - return (transform (ctr.begin(), ctr.end(), result, op)); -} - -/// The second version of transform is very similar, except that it uses a -/// Binary Function instead of a Unary Function: it performs the operation -/// op(*i1, *i2) for each iterator i1 in the range [first1, last1) and assigns -/// the result to *o, where i2 is the corresponding iterator in the second -/// input range and where o is the corresponding output iterator. That is, -/// for each n such that 0 <= n < last1 - first1, it performs the assignment -/// *(result + n) = op(*(first1 + n), *(first2 + n). -/// The return value is result + (last1 - first1). -/// \ingroup MutatingAlgorithms -/// -template <typename Container, typename InputIterator, typename OutputIterator, typename BinaryFunction> -inline OutputIterator transform (Container& ctr, InputIterator first, OutputIterator result, BinaryFunction op) -{ - return (transform (ctr.begin(), ctr.end(), first, result, op)); -} - -/// Replace replaces every element in the range [first, last) equal to -/// old_value with new_value. That is: for every iterator i, -/// if *i == old_value then it performs the assignment *i = new_value. -/// \ingroup MutatingAlgorithms -/// -template <typename Container, typename T> -inline void replace (Container& ctr, const T& old_value, const T& new_value) -{ - replace (ctr.begin(), ctr.end(), old_value, new_value); -} - -/// Replace_if replaces every element in the range [first, last) for which -/// pred returns true with new_value. That is: for every iterator i, if -/// pred(*i) is true then it performs the assignment *i = new_value. -/// \ingroup MutatingAlgorithms -/// -template <typename Container, typename Predicate, typename T> -inline void replace_if (Container& ctr, Predicate pred, const T& new_value) -{ - replace_if (ctr.begin(), ctr.end(), pred, new_value); -} - -/// Replace_copy copies elements from the range [first, last) to the range -/// [result, result + (last-first)), except that any element equal to old_value -/// is not copied; new_value is copied instead. More precisely, for every -/// integer n such that 0 <= n < last-first, replace_copy performs the -/// assignment *(result+n) = new_value if *(first+n) == old_value, and -/// *(result+n) = *(first+n) otherwise. -/// \ingroup MutatingAlgorithms -/// -template <typename Container, typename OutputIterator, typename T> -inline OutputIterator replace_copy (const Container& ctr, OutputIterator result, const T& old_value, const T& new_value) -{ - return (replace_copy (ctr.begin(), ctr.end(), result, old_value, new_value)); -} - -/// Replace_copy_if copies elements from the range [first, last) to the range -/// [result, result + (last-first)), except that any element for which pred is -/// true is not copied; new_value is copied instead. More precisely, for every -/// integer n such that 0 <= n < last-first, replace_copy_if performs the -/// assignment *(result+n) = new_value if pred(*(first+n)), -/// and *(result+n) = *(first+n) otherwise. -/// \ingroup MutatingAlgorithms -/// -template <typename Container, typename OutputIterator, typename Predicate, typename T> -inline OutputIterator replace_copy_if (const Container& ctr, OutputIterator result, Predicate pred, const T& new_value) -{ - return (replace_copy_if (ctr.begin(), ctr.end(), result, pred, new_value)); -} - -/// Fill assigns the value value to every element in the range [first, last). -/// That is, for every iterator i in [first, last), -/// it performs the assignment *i = value. -/// \ingroup GeneratorAlgorithms -/// -template <typename Container, typename T> -inline void fill (Container& ctr, const T& value) -{ - fill (ctr.begin(), ctr.end(), value); -} - -/// Generate assigns the result of invoking gen, a function object that -/// takes no arguments, to each element in the range [first, last). -/// \ingroup GeneratorAlgorithms -/// -template <typename Container, typename Generator> -inline void generate (Container& ctr, Generator gen) -{ - generate (ctr.begin(), ctr.end(), gen); -} - -/// Randomly permute the elements of the container. -/// \ingroup GeneratorAlgorithms -/// -template <typename Container> -inline void random_shuffle (Container& ctr) -{ - random_shuffle (ctr.begin(), ctr.end()); -} - -/// Remove_copy copies elements that are not equal to value from the range -/// [first, last) to a range beginning at result. The return value is the -/// end of the resulting range. This operation is stable, meaning that the -/// relative order of the elements that are copied is the same as in the -/// range [first, last). -/// \ingroup MutatingAlgorithms -/// -template <typename Container, typename OutputIterator, typename T> -inline OutputIterator remove_copy (const Container& ctr, OutputIterator result, const T& value) -{ - return (remove_copy (ctr.begin(), ctr.end(), result, value)); -} - -/// Remove_copy_if copies elements from the range [first, last) to a range -/// beginning at result, except that elements for which pred is true are not -/// copied. The return value is the end of the resulting range. This operation -/// is stable, meaning that the relative order of the elements that are copied -/// is the same as in the range [first, last). -/// \ingroup MutatingAlgorithms -/// -template <typename Container, typename OutputIterator, typename Predicate> -inline OutputIterator remove_copy_if (const Container& ctr, OutputIterator result, Predicate pred) -{ - return (remove_copy_if (ctr.begin(), ctr.end(), result, pred)); -} - -/// Remove removes from the range [first, last) all elements that are equal to -/// value. That is, remove returns an iterator new_last such that the range -/// [first, new_last) contains no elements equal to value. Remove is stable, -/// meaning that the relative order of elements that are not equal to value is -/// unchanged. -/// \ingroup MutatingAlgorithms -/// -template <typename Container, typename T> -inline void remove (Container& ctr, const T& value) -{ - ctr.erase (remove_copy (ctr.begin(), ctr.end(), ctr.begin(), value), ctr.end()); -} - -/// Remove removes from the range [first, last) all elements that have an iterator -/// in range [rfirst, rlast). The range is assumed to be sorted. That is, remove -/// returns an iterator new_last such that the range [first, new_last) contains -/// no elements whose iterators are in [rfirst, rlast). Remove is stable, -/// meaning that the relative order of elements that are not equal to value is -/// unchanged. This version of the algorithm is a uSTL extension. -/// \ingroup MutatingAlgorithms -/// -template <typename Container, typename ForwardIterator> -inline void remove (Container& ctr, ForwardIterator rfirst, ForwardIterator rlast) -{ - ctr.erase (remove_copy (ctr.begin(), ctr.end(), ctr.begin(), rfirst, rlast), ctr.end()); -} - -/// Remove_if removes from the range [first, last) every element x such that -/// pred(x) is true. That is, remove_if returns an iterator new_last such that -/// the range [first, new_last) contains no elements for which pred is true. -/// The iterators in the range [new_last, last) are all still dereferenceable, -/// but the elements that they point to are unspecified. Remove_if is stable, -/// meaning that the relative order of elements that are not removed is -/// unchanged. -/// \ingroup MutatingAlgorithms -/// -template <typename Container, typename Predicate> -inline void remove_if (Container& ctr, Predicate pred) -{ - ctr.erase (remove_copy_if (ctr.begin(), ctr.end(), ctr.begin(), pred), ctr.end()); -} - -/// Unique_copy copies elements from the range [first, last) to a range -/// beginning with result, except that in a consecutive group of duplicate -/// elements only the first one is copied. The return value is the end of -/// the range to which the elements are copied. This behavior is similar -/// to the Unix filter uniq. -/// \ingroup MutatingAlgorithms -/// -template <typename Container, typename OutputIterator> -inline OutputIterator unique_copy (const Container& ctr, OutputIterator result) -{ - return (unique_copy (ctr.begin(), ctr.end(), result)); -} - -/// Every time a consecutive group of duplicate elements appears in the range -/// [first, last), the algorithm unique removes all but the first element. -/// That is, unique returns an iterator new_last such that the range [first, -/// new_last) contains no two consecutive elements that are duplicates. -/// The iterators in the range [new_last, last) are all still dereferenceable, -/// but the elements that they point to are unspecified. Unique is stable, -/// meaning that the relative order of elements that are not removed is -/// unchanged. -/// \ingroup MutatingAlgorithms -/// -template <typename Container> -inline void unique (Container& ctr) -{ - ctr.erase (unique_copy (ctr.begin(), ctr.end(), ctr.begin()), ctr.end()); -} - -/// Every time a consecutive group of duplicate elements appears in the range -/// [first, last), the algorithm unique removes all but the first element. -/// That is, unique returns an iterator new_last such that the range [first, -/// new_last) contains no two consecutive elements that are duplicates. -/// The iterators in the range [new_last, last) are all still dereferenceable, -/// but the elements that they point to are unspecified. Unique is stable, -/// meaning that the relative order of elements that are not removed is -/// unchanged. -/// \ingroup MutatingAlgorithms -/// -template <typename Container, typename BinaryPredicate> -inline void unique (Container& ctr, BinaryPredicate binary_pred) -{ - ctr.erase (unique_copy (ctr.begin(), ctr.end(), ctr.begin(), binary_pred), ctr.end()); -} - -/// Reverse reverses a range. -/// That is: for every i such that 0 <= i <= (last - first) / 2), -/// it exchanges *(first + i) and *(last - (i + 1)). -/// \ingroup MutatingAlgorithms -/// -template <typename Container> -inline void reverse (Container& ctr) -{ - reverse (ctr.begin(), ctr.end()); -} - -/// Exchanges ranges [first, middle) and [middle, last) -/// \ingroup MutatingAlgorithms -/// -template <typename Container> -inline void rotate (Container& ctr, off_t offset) -{ - assert (size_t(offset > 0 ? offset : -offset) < ctr.size()); - if (offset > 0) - rotate (ctr.begin(), ctr.end() - offset, ctr.end()); - else - rotate (ctr.begin(), ctr.begin() - offset, ctr.end()); -} - -/// Returns the furthermost iterator i in [first, last) such that, -/// for every iterator j in [first, i), *j < value -/// Assumes the range is sorted. -/// \ingroup SearchingAlgorithms -/// -template <typename Container, typename LessThanComparable> -inline typename Container::const_iterator lower_bound (const Container& ctr, const LessThanComparable& value) -{ - return (lower_bound (ctr.begin(), ctr.end(), value)); -} -template <typename Container, typename LessThanComparable> -inline typename Container::iterator lower_bound (Container& ctr, const LessThanComparable& value) -{ - return (lower_bound (ctr.begin(), ctr.end(), value)); -} - -/// Returns the furthermost iterator i in [first,last) such that for -/// every iterator j in [first,i), value < *j is false. -/// \ingroup SearchingAlgorithms -/// -template <typename Container, typename LessThanComparable> -inline typename Container::const_iterator upper_bound (const Container& ctr, const LessThanComparable& value) -{ - return (upper_bound (ctr.begin(), ctr.end(), value)); -} -template <typename Container, typename LessThanComparable> -inline typename Container::iterator upper_bound (Container& ctr, const LessThanComparable& value) -{ - return (upper_bound (ctr.begin(), ctr.end(), value)); -} - -/// Performs a binary search for \p value. -/// Assumes the range is sorted. -/// \ingroup SearchingAlgorithms -/// -template <typename Container> -inline bool binary_search (const Container& ctr, const typename Container::value_type& value) -{ - return (binary_search (ctr.begin(), ctr.end(), value)); -} -template <typename Container> -inline bool binary_search (Container& ctr, const typename Container::value_type& value) -{ - return (binary_search (ctr.begin(), ctr.end(), value)); -} - -/// Returns pair<lower_bound,upper_bound> -/// \ingroup SearchingAlgorithms -/// -template <typename Container, typename LessThanComparable> -inline pair<typename Container::const_iterator,typename Container::const_iterator> equal_range (const Container& ctr, const LessThanComparable& value) -{ - return (equal_range (ctr.begin(), ctr.end(), value)); -} -template <typename Container, typename LessThanComparable> -inline pair<typename Container::iterator,typename Container::iterator> equal_range (Container& ctr, const LessThanComparable& value) -{ - return (equal_range (ctr.begin(), ctr.end(), value)); -} - -/// Sorts the container -/// \ingroup SortingAlgorithms -/// -template <typename Container> -inline void sort (Container& ctr) -{ - sort (ctr.begin(), ctr.end()); -} - -/// Sorts the container -/// \ingroup SortingAlgorithms -/// -template <typename Container, typename Compare> -inline void sort (Container& ctr, Compare comp) -{ - sort (ctr.begin(), ctr.end(), comp); -} - -/// Sorts the container -/// \ingroup SortingAlgorithms -/// -template <typename Container> -inline void stable_sort (Container& ctr) -{ - stable_sort (ctr.begin(), ctr.end()); -} - -/// Sorts the container -/// \ingroup SortingAlgorithms -/// -template <typename Container, typename Compare> -inline void stable_sort (Container& ctr, Compare comp) -{ - stable_sort (ctr.begin(), ctr.end(), comp); -} - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/uctrstrm.h +++ /dev/null @@ -1,181 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. -// -/// \file uctrstrm.h -/// -/// \brief Serialization templates for standard containers. -/// Because containers are templates, a single operator>> is impossible. -/// Making virtual read/write is also impossible because not all containers -/// contain serializable elements. Therefore, use the macros in this file. - -#ifndef UCTRSTRM_H_75B2C3EA4980DDDC6B6DFFF767A3B7AC -#define UCTRSTRM_H_75B2C3EA4980DDDC6B6DFFF767A3B7AC - -#include "mistream.h" -#include "sostream.h" -#include "uiosfunc.h" -#include <typeinfo> - -namespace ustl { - -//---------------------------------------------------------------------- -// Macros for easily declaring a container streamable. -//---------------------------------------------------------------------- - -/// \brief Declares container template \p type streamable. -/// -/// Use TEMPLATE_TYPE and TEMPLATE_DECL macros to pass in templated -/// type with commas and the template declaration. -/// -#define STD_TEMPLATE_CTR_STREAMABLE(type, template_decl) \ - template_decl \ - inline istream& operator>> (istream& is, type& v) \ - { return (container_read (is, v)); } \ - template_decl \ - inline ostream& operator<< (ostream& os, const type& v) \ - { return (container_write (os, v)); } \ - template_decl \ - inline ostringstream& operator<< (ostringstream& os, const type& v) \ - { return (container_text_write (os, v)); } \ - template_decl \ - struct object_stream_size<type > { \ - inline size_t operator()(const type& v) const \ - { return (container_stream_size (v)); } \ - }; - -/// \brief Declares non-resizable container template \p type streamable. -#define STD_TEMPLATE_NR_CTR_STREAMABLE(type, template_decl) \ - template_decl \ - inline istream& operator>> (istream& is, type& v) \ - { return (nr_container_read (is, v)); } \ - template_decl \ - inline ostream& operator<< (ostream& os, const type& v) \ - { return (nr_container_write (os, v)); } \ - template_decl \ - inline ostringstream& operator<< (ostringstream& os, const type& v) \ - { return (container_text_write (os, v)); } \ - template_decl \ - struct object_stream_size<type > { \ - inline size_t operator()(const type& v) const \ - { return (nr_container_stream_size (v)); } \ - }; - -//---------------------------------------------------------------------- -// Fixed size container serialization. -//---------------------------------------------------------------------- - -/// Reads fixed size container \p v from stream \p is. -template <typename Container> -inline istream& nr_container_read (istream& is, Container& v) -{ - foreach (typename Container::iterator, i, v) - is >> *i; - return (is); -} - -/// Writes fixed size container \p v into stream \p os. -template <typename Container> -inline ostream& nr_container_write (ostream& os, const Container& v) -{ - foreach (typename Container::const_iterator, i, v) - os << *i; - return (os); -} - -/// Computes the stream size of a fixed size standard container. -template <typename Container> -inline size_t nr_container_stream_size (const Container& v) -{ - typedef typename Container::const_iterator vciter_t; - typedef typename iterator_traits<vciter_t>::value_type value_type; - if (!v.size()) - return (0); - size_t s = 0, dvs; - vciter_t i = v.begin(); - do { - dvs = stream_size_of(*i); - s += dvs; - } while (++i != v.end() && !__builtin_constant_p(dvs)); - if (__builtin_constant_p(dvs)) - s *= v.size(); - return (s); -} - -//---------------------------------------------------------------------- -// Resizable container serialization. -//---------------------------------------------------------------------- - -/// Reads container \p v from stream \p is. -template <typename Container> -istream& container_read (istream& is, Container& v) -{ - typedef typename Container::value_type value_type; - typedef typename Container::iterator iterator; - typedef typename Container::written_size_type written_size_type; - written_size_type n = 0; - is >> n; - const size_t expectedSize = n * stream_size_of(value_type()); - if (!is.verify_remaining ("read", USTL_TYPENAME(v), expectedSize)) - return (is); - if (alignof(NullValue<value_type>()) > alignof(n)) - is >> ios::talign<value_type>(); - v.resize (n); - nr_container_read (is, v); - is >> ios::talign<written_size_type>(); - return (is); -} - -/// Writes the vector to stream \p os. -template <typename Container> -ostream& container_write (ostream& os, const Container& v) -{ - typedef typename Container::value_type value_type; - typedef typename Container::written_size_type written_size_type; - const written_size_type sz (v.size()); - os << sz; - if (alignof(NullValue<value_type>()) > alignof(sz)) - os << ios::talign<value_type>(); - nr_container_write (os, v); - os << ios::talign<written_size_type>(); - return (os); -} - -/// Computes the stream size of a standard container. -template <typename Container> -size_t container_stream_size (const Container& v) -{ - typedef typename Container::value_type value_type; - typedef typename Container::written_size_type written_size_type; - const written_size_type sz (v.size()); - size_t sizeSize = stream_size_of (sz); - if (alignof(NullValue<value_type>()) > alignof(sz)) - sizeSize = Align (sizeSize, alignof(NullValue<value_type>())); - return (Align (sizeSize + nr_container_stream_size (v), alignof(sz))); -} - -/// \brief Writes element \p v into stream \p os as text. -/// Specialize to custom print elements. -template <typename T> -inline ostringstream& container_element_text_write (ostringstream& os, const T& v) -{ return (os << v); } - -/// Writes container \p v into stream \p os as text. -template <typename Container> -ostringstream& container_text_write (ostringstream& os, const Container& v) -{ - typename Container::const_iterator i = v.begin(); - os << '('; - while (i < v.end()) { - container_element_text_write (os, *i); - os << ",)"[++i == v.end()]; - } - return (os); -} - -//---------------------------------------------------------------------- - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/uexception.h +++ /dev/null @@ -1,186 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UEXCEPTION_H_18DE3EF55C4F00673268F0D66546AF5D -#define UEXCEPTION_H_18DE3EF55C4F00673268F0D66546AF5D - -#include "utypes.h" -#ifndef WITHOUT_LIBSTDCPP - #include <exception> - #include <new> -#endif -#include "bktrace.h" - -#if WITHOUT_LIBSTDCPP -namespace std { -/// If you write a replacement terminate handler, it must be of this type. -typedef void (*terminate_handler) (void); -/// If you write a replacement unexpected handler, it must be of this type. -typedef void (*unexpected_handler) (void); -/// Takes a new handler function as an argument, returns the old function. -terminate_handler set_terminate (terminate_handler pHandler) throw(); -/// The runtime will call this function if exception handling must be -/// abandoned for any reason. It can also be called by the user. -void terminate (void) __attribute__ ((__noreturn__)); -/// Takes a new handler function as an argument, returns the old function. -unexpected_handler set_unexpected (unexpected_handler pHandler) throw(); -/// The runtime will call this function if an exception is thrown which -/// violates the function's exception specification. -void unexpected (void) __attribute__ ((__noreturn__)); -/// Returns true when the caught exception violates the throw specification. -bool uncaught_exception() throw(); -} // namespace std -#endif - -namespace ustl { - -class string; - -typedef uint32_t xfmt_t; - -enum { - xfmt_Exception, - xfmt_BadAlloc, - xfmt_LibcException = 12, - xfmt_FileException = 13, - xfmt_StreamBoundsException = 14 -}; - -/// \class exception uexception.h ustl.h -/// \ingroup Exceptions -/// -/// \brief Base class for exceptions, equivalent to std::exception. -/// -#if WITHOUT_LIBSTDCPP -class exception { -#else -class exception : public std::exception { -#endif -public: - typedef const CBacktrace& rcbktrace_t; -public: - inline exception (void) throw() : m_Format (xfmt_Exception) {} - inline virtual ~exception (void) throw() {} - inline virtual const char* what (void) const throw() { return ("error"); } - virtual void info (string& msgbuf, const char* fmt = NULL) const throw(); - virtual void read (istream& is); - virtual void write (ostream& os) const; - void text_write (ostringstream& os) const; - inline virtual size_t stream_size (void) const { return (sizeof(m_Format) + sizeof(uint32_t) + m_Backtrace.stream_size()); } - /// Format of the exception is used to lookup exception::info format string. - /// Another common use is the instantiation of serialized exceptions, used - /// by the error handler node chain to troubleshoot specific errors. - inline xfmt_t format (void) const { return (m_Format); } - inline rcbktrace_t backtrace (void) const { return (m_Backtrace); } -protected: - inline void set_format (xfmt_t fmt) { m_Format = fmt; } -private: - CBacktrace m_Backtrace; ///< Backtrace of the throw point. - xfmt_t m_Format; ///< Format of the exception's data. -}; - -/// \class bad_cast uexception.h ustl.h -/// \ingroup Exceptions -/// -/// \brief Thrown to indicate a bad dynamic_cast usage. -/// -class bad_cast : public exception { -public: - inline explicit bad_cast (void) throw() : exception() {} - inline virtual const char* what (void) const throw() { return ("bad cast"); } -}; - -//---------------------------------------------------------------------- - -/// \class bad_alloc uexception.h ustl.h -/// \ingroup Exceptions -/// -/// \brief Exception thrown on memory allocation failure by memblock::reserve. -/// -#if WITHOUT_LIBSTDCPP -class bad_alloc : public exception { -#else -class bad_alloc : public std::bad_alloc, public exception { -#endif -public: - explicit bad_alloc (size_t nBytes = 0) throw(); - inline virtual const char* what (void) const throw() { return ("memory allocation failed"); } - virtual void info (string& msgbuf, const char* fmt = NULL) const throw(); - virtual void read (istream& is); - virtual void write (ostream& os) const; - virtual size_t stream_size (void) const; -protected: - size_t m_nBytesRequested; ///< Number of bytes requested by the failed allocation. -}; - -/// \class libc_exception uexception.h ustl.h -/// \ingroup Exceptions -/// -/// \brief Thrown when a libc function returns an error. -/// -/// Contains an errno and description. This is a uSTL extension. -/// -class libc_exception : public exception { -public: - explicit libc_exception (const char* operation) throw(); - libc_exception (const libc_exception& v) throw(); - const libc_exception& operator= (const libc_exception& v); - inline virtual const char* what (void) const throw() { return ("libc function failed"); } - virtual void info (string& msgbuf, const char* fmt = NULL) const throw(); - virtual void read (istream& is); - virtual void write (ostream& os) const; - virtual size_t stream_size (void) const; -protected: - intptr_t m_Errno; ///< Error code returned by the failed operation. - const char* m_Operation; ///< Name of the failed operation. -}; - -/// \class file_exception uexception.h ustl.h -/// \ingroup Exceptions -/// -/// \brief File-related exceptions. -/// -/// Contains the file name. This is a uSTL extension. -/// -class file_exception : public libc_exception { -public: - file_exception (const char* operation, const char* filename) throw(); - inline virtual const char* what (void) const throw() { return ("file error"); } - virtual void info (string& msgbuf, const char* fmt = NULL) const throw(); - virtual void read (istream& is); - virtual void write (ostream& os) const; - virtual size_t stream_size (void) const; -protected: - char m_Filename [PATH_MAX]; ///< Name of the file causing the error. -}; - -/// \class stream_bounds_exception uexception.h ustl.h -/// \ingroup Exceptions -/// -/// \brief Stream bounds checking. -/// -/// Only thrown in debug builds unless you say otherwise in config.h -/// This is a uSTL extension. -/// -class stream_bounds_exception : public libc_exception { -public: - stream_bounds_exception (const char* operation, const char* type, uoff_t offset, size_t expected, size_t remaining) throw(); - inline virtual const char* what (void) const throw() { return ("stream bounds exception"); } - virtual void info (string& msgbuf, const char* fmt = NULL) const throw(); - virtual void read (istream& is); - virtual void write (ostream& os) const; - virtual size_t stream_size (void) const; -protected: - const char* m_TypeName; - uoff_t m_Offset; - size_t m_Expected; - size_t m_Remaining; -}; - -const char* demangle_type_name (char* buf, size_t bufSize, size_t* pdmSize = NULL); - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/ufunction.h +++ /dev/null @@ -1,465 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UFUNCTION_H_221ABA8551801799263C927234C085F3 -#define UFUNCTION_H_221ABA8551801799263C927234C085F3 - -namespace ustl { - -//---------------------------------------------------------------------- -// Standard functors -//---------------------------------------------------------------------- - -/// \brief void-returning function abstract interface. -/// \ingroup FunctorObjects -template <typename Result> -struct void_function { - typedef Result result_type; -}; - -/// \brief \p Result f (\p Arg) function abstract interface. -/// \ingroup FunctorObjects -template <typename Arg, typename Result> -struct unary_function { - typedef Arg argument_type; - typedef Result result_type; -}; - -/// \brief \p Result f (\p Arg1, \p Arg2) function abstract interface. -/// \ingroup FunctorObjects -template <typename Arg1, typename Arg2, typename Result> -struct binary_function { - typedef Arg1 first_argument_type; - typedef Arg2 second_argument_type; - typedef Result result_type; -}; - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -#define STD_BINARY_FUNCTOR(name, rv, func) \ -template <class T> struct name : public binary_function<T,T,rv> \ -{ inline rv operator()(const T& a, const T& b) const { return func; } }; -#define STD_UNARY_FUNCTOR(name, rv, func) \ -template <class T> struct name : public unary_function<T,rv> \ -{ inline rv operator()(const T& a) const { return func; } }; -#define STD_CONVERSION_FUNCTOR(name, func) \ -template <class S, class D> struct name : public unary_function<S,D> \ -{ inline D operator()(const S& a) const { return func; } }; - -STD_BINARY_FUNCTOR (plus, T, (a + b)) -STD_BINARY_FUNCTOR (minus, T, (a - b)) -STD_BINARY_FUNCTOR (divides, T, (a / b)) -STD_BINARY_FUNCTOR (modulus, T, (a % b)) -STD_BINARY_FUNCTOR (multiplies, T, (a * b)) -STD_BINARY_FUNCTOR (logical_and, T, (a && b)) -STD_BINARY_FUNCTOR (logical_or, T, (a || b)) -STD_UNARY_FUNCTOR (logical_not, T, (!a)) -STD_BINARY_FUNCTOR (bitwise_or, T, (a | b)) -STD_BINARY_FUNCTOR (bitwise_and, T, (a & b)) -STD_BINARY_FUNCTOR (bitwise_xor, T, (a ^ b)) -STD_UNARY_FUNCTOR (bitwise_not, T, (~a)) -STD_UNARY_FUNCTOR (negate, T, (-a)) -STD_BINARY_FUNCTOR (equal_to, bool, (a == b)) -STD_BINARY_FUNCTOR (not_equal_to, bool, (!(a == b))) -STD_BINARY_FUNCTOR (greater, bool, (b < a)) -STD_BINARY_FUNCTOR (less, bool, (a < b)) -STD_BINARY_FUNCTOR (greater_equal, bool, (!(a < b))) -STD_BINARY_FUNCTOR (less_equal, bool, (!(b < a))) -STD_BINARY_FUNCTOR (compare, int, (a < b ? -1 : (b < a))) -STD_UNARY_FUNCTOR (identity, T, (a)) - -#endif // DOXYGEN_SHOULD_SKIP_THIS - -/// \brief Selects and returns the first argument. -/// \ingroup FunctorObjects -template <class T1, class T2> struct project1st : public binary_function<T1,T2,T1> { inline const T1& operator()(const T1& a, const T2&) const { return (a); } }; -/// \brief Selects and returns the second argument. -/// \ingroup FunctorObjects -template <class T1, class T2> struct project2nd : public binary_function<T1,T2,T2> { inline const T2& operator()(const T1&, const T2& a) const { return (a); } }; - -//---------------------------------------------------------------------- -// Generic function to functor converters. -//---------------------------------------------------------------------- - -/// \brief Wrapper object for unary function pointers. -/// Use the ptr_fun accessor to create this object. -/// \ingroup FunctorObjects -template <typename Arg, typename Result> -class pointer_to_unary_function : public unary_function<Arg,Result> { -public: - typedef Arg argument_type; - typedef Result result_type; - typedef Result (*pfunc_t)(Arg); -public: - explicit inline pointer_to_unary_function (pfunc_t pfn) : m_pfn (pfn) {} - inline result_type operator() (argument_type v) const { return (m_pfn(v)); } -private: - pfunc_t m_pfn; ///< Pointer to the wrapped function. -}; - -/// \brief Wrapper object for binary function pointers. -/// Use the ptr_fun accessor to create this object. -/// \ingroup FunctorObjects -template <typename Arg1, typename Arg2, typename Result> -class pointer_to_binary_function : public binary_function<Arg1,Arg2,Result> { -public: - typedef Arg1 first_argument_type; - typedef Arg2 second_argument_type; - typedef Result result_type; - typedef Result (*pfunc_t)(Arg1, Arg2); -public: - explicit inline pointer_to_binary_function (pfunc_t pfn) : m_pfn (pfn) {} - inline result_type operator() (first_argument_type v1, second_argument_type v2) const { return (m_pfn(v1, v2)); } -private: - pfunc_t m_pfn; ///< Pointer to the wrapped function. -}; - -/// ptr_fun(pfn) wraps function pointer pfn into a functor class that calls it. -/// \ingroup FunctorAccessors -template <typename Arg, typename Result> -inline pointer_to_unary_function<Arg,Result> ptr_fun (Result (*pfn)(Arg)) -{ - return (pointer_to_unary_function<Arg,Result> (pfn)); -} - -/// ptr_fun(pfn) wraps function pointer pfn into a functor class that calls it. -/// \ingroup FunctorAccessors -template <typename Arg1, typename Arg2, typename Result> -inline pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun (Result (*pfn)(Arg1,Arg2)) -{ - return (pointer_to_binary_function<Arg1,Arg2,Result> (pfn)); -} - -//---------------------------------------------------------------------- -// Negators. -//---------------------------------------------------------------------- - -/// \brief Wraps a unary function to return its logical negative. -/// Use the unary_negator accessor to create this object. -/// \ingroup FunctorObjects -template <class UnaryFunction> -class unary_negate : public unary_function<typename UnaryFunction::argument_type, - typename UnaryFunction::result_type> { -public: - typedef typename UnaryFunction::argument_type argument_type; - typedef typename UnaryFunction::result_type result_type; -public: - explicit inline unary_negate (UnaryFunction pfn) : m_pfn (pfn) {} - inline result_type operator() (argument_type v) const { return (!m_pfn(v)); } -private: - UnaryFunction m_pfn; -}; - -/// Returns the functor that negates the result of *pfn(). -/// \ingroup FunctorAccessors -template <class UnaryFunction> -inline unary_negate<UnaryFunction> unary_negator (UnaryFunction pfn) -{ - return (unary_negate<UnaryFunction>(pfn)); -} - -//---------------------------------------------------------------------- -// Argument binders -//---------------------------------------------------------------------- - -/// \brief Converts a binary function to a unary function -/// by binding a constant value to the first argument. -/// Use the bind1st accessor to create this object. -/// \ingroup FunctorObjects -template <class BinaryFunction> -class binder1st : public unary_function<typename BinaryFunction::second_argument_type, - typename BinaryFunction::result_type> { -public: - typedef typename BinaryFunction::first_argument_type arg1_t; - typedef typename BinaryFunction::second_argument_type arg2_t; - typedef typename BinaryFunction::result_type result_t; -public: - inline binder1st (const BinaryFunction& pfn, const arg1_t& v) : m_pfn (pfn), m_Value(v) {} - inline result_t operator()(arg2_t v2) const { return (m_pfn (m_Value, v2)); } -protected: - BinaryFunction m_pfn; - arg1_t m_Value; -}; - -/// \brief Converts a binary function to a unary function -/// by binding a constant value to the second argument. -/// Use the bind2nd accessor to create this object. -/// \ingroup FunctorObjects -template <class BinaryFunction> -class binder2nd : public unary_function<typename BinaryFunction::first_argument_type, - typename BinaryFunction::result_type> { -public: - typedef typename BinaryFunction::first_argument_type arg1_t; - typedef typename BinaryFunction::second_argument_type arg2_t; - typedef typename BinaryFunction::result_type result_t; -public: - inline binder2nd (const BinaryFunction& pfn, const arg2_t& v) : m_pfn (pfn), m_Value(v) {} - inline result_t operator()(arg1_t v1) const { return (m_pfn (v1, m_Value)); } -protected: - BinaryFunction m_pfn; - arg2_t m_Value; -}; - -/// Converts \p pfn into a unary function by binding the first argument to \p v. -/// \ingroup FunctorAccessors -template <typename BinaryFunction> -inline binder1st<BinaryFunction> -bind1st (BinaryFunction pfn, typename BinaryFunction::first_argument_type v) -{ - return (binder1st<BinaryFunction> (pfn, v)); -} - -/// Converts \p pfn into a unary function by binding the second argument to \p v. -/// \ingroup FunctorAccessors -template <typename BinaryFunction> -inline binder2nd<BinaryFunction> -bind2nd (BinaryFunction pfn, typename BinaryFunction::second_argument_type v) -{ - return (binder2nd<BinaryFunction> (pfn, v)); -} - -//---------------------------------------------------------------------- -// Composition adapters -//---------------------------------------------------------------------- - -/// \brief Chains two unary functions together. -/// -/// When f(x) and g(x) are composed, the result is function c(x)=f(g(x)). -/// Use the \ref compose1 accessor to create this object. -/// This template is an extension, implemented by SGI STL and uSTL. -/// \ingroup FunctorObjects -/// -template <typename Operation1, typename Operation2> -class unary_compose : public unary_function<typename Operation2::argument_type, - typename Operation1::result_type> { -public: - typedef typename Operation2::argument_type arg_t; - typedef const arg_t& rcarg_t; - typedef typename Operation1::result_type result_t; -public: - inline unary_compose (const Operation1& f, const Operation2& g) : m_f(f), m_g(g) {} - inline result_t operator() (rcarg_t x) const { return m_f(m_g(x)); } -protected: - Operation1 m_f; ///< f(x), if c(x) = f(g(x)) - Operation2 m_g; ///< g(x), if c(x) = f(g(x)) -}; - -/// Creates a \ref unary_compose object whose function c(x)=f(g(x)) -/// \ingroup FunctorAccessors -template <typename Operation1, typename Operation2> -inline unary_compose<Operation1, Operation2> -compose1 (const Operation1& f, const Operation2& g) -{ return unary_compose<Operation1,Operation2>(f, g); } - -/// \brief Chains two unary functions through a binary function. -/// -/// When f(x,y), g(x), and h(x) are composed, the result is function -/// c(x)=f(g(x),h(x)). Use the \ref compose2 accessor to create this -/// object. This template is an extension, implemented by SGI STL and uSTL. -/// \ingroup FunctorObjects -/// -template <typename Operation1, typename Operation2, typename Operation3> -class binary_compose : public unary_function<typename Operation2::argument_type, - typename Operation1::result_type> { -public: - typedef typename Operation2::argument_type arg_t; - typedef const arg_t& rcarg_t; - typedef typename Operation1::result_type result_t; -public: - inline binary_compose (const Operation1& f, const Operation2& g, const Operation3& h) : m_f(f), m_g(g), m_h(h) {} - inline result_t operator() (rcarg_t x) const { return m_f(m_g(x), m_h(x)); } -protected: - Operation1 m_f; ///< f(x,y), if c(x) = f(g(x),h(x)) - Operation2 m_g; ///< g(x), if c(x) = f(g(x),h(x)) - Operation3 m_h; ///< h(x), if c(x) = f(g(x),h(x)) -}; - -/// Creates a \ref binary_compose object whose function c(x)=f(g(x),h(x)) -/// \ingroup FunctorAccessors -template <typename Operation1, typename Operation2, typename Operation3> -inline binary_compose<Operation1, Operation2, Operation3> -compose2 (const Operation1& f, const Operation2& g, const Operation3& h) -{ return binary_compose<Operation1, Operation2, Operation3> (f, g, h); } - -//---------------------------------------------------------------------- -// Member function adaptors -//---------------------------------------------------------------------- - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -#define MEM_FUN_T(WrapperName, ClassName, ArgType, FuncType, CallType) \ - template <typename Ret, class T> \ - class ClassName : public unary_function<ArgType,Ret> { \ - public: \ - typedef Ret (T::*func_t) FuncType; \ - public: \ - explicit inline ClassName (func_t pf) : m_pf (pf) {} \ - inline Ret operator() (ArgType p) const { return ((p CallType m_pf)()); } \ - private: \ - func_t m_pf; \ - }; \ - \ - template <class Ret, typename T> \ - inline ClassName<Ret,T> WrapperName (Ret (T::*pf) FuncType) \ - { \ - return (ClassName<Ret,T> (pf)); \ - } - -MEM_FUN_T(mem_fun, mem_fun_t, T*, (void), ->*) -MEM_FUN_T(mem_fun, const_mem_fun_t, const T*, (void) const, ->*) -MEM_FUN_T(mem_fun_ref, mem_fun_ref_t, T&, (void), .*) -MEM_FUN_T(mem_fun_ref, const_mem_fun_ref_t, const T&, (void) const, .*) - -#define EXT_MEM_FUN_T(ClassName, HostType, FuncType) \ - template <class T, typename Ret, typename V> \ - class ClassName : public unary_function<V,void> { \ - public: \ - typedef Ret (T::*func_t)(V) FuncType; \ - public: \ - inline ClassName (HostType t, func_t pf) : m_t (t), m_pf (pf) {} \ - inline Ret operator() (V v) const { return ((m_t->*m_pf)(v)); } \ - private: \ - HostType m_t; \ - func_t m_pf; \ - }; \ - \ - template <class T, typename Ret, typename V> \ - inline ClassName<T,Ret,V> mem_fun (HostType p, Ret (T::*pf)(V) FuncType) \ - { \ - return (ClassName<T,Ret,V> (p, pf)); \ - } - -EXT_MEM_FUN_T(ext_mem_fun_t, T*, ) -EXT_MEM_FUN_T(const_ext_mem_fun_t, const T*, const) - -#endif // DOXYGEN_SHOULD_SKIP_THIS - -//---------------------------------------------------------------------- -// Member variable adaptors (uSTL extension) -//---------------------------------------------------------------------- - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -#define MEM_VAR_T(FunctorName, ArgType, VarType, BaseClass, CallImpl) \ - template <typename Function, class T, typename VT> \ - class FunctorName##_t : public BaseClass { \ - public: \ - typedef ArgType argument_type; \ - typedef typename Function::result_type result_type; \ - typedef VarType mem_var_ptr_t; \ - public: \ - inline FunctorName##_t (mem_var_ptr_t pv, Function pfn) : m_pv(pv), m_pfn(pfn) {} \ - inline result_type operator() CallImpl \ - private: \ - mem_var_ptr_t m_pv; \ - Function m_pfn; \ - }; \ - \ - template <typename Function, class T, typename VT> \ - inline FunctorName##_t<Function, T, VT> \ - FunctorName (VT T::*mvp, Function pfn) \ - { \ - return (FunctorName##_t<Function,T,VT> (mvp, pfn)); \ - } - -#define FUNCTOR_UNARY_BASE(ArgType) unary_function<ArgType, typename Function::result_type> -#define FUNCTOR_BINARY_BASE(ArgType) binary_function<ArgType, ArgType, typename Function::result_type> - -#define MEM_VAR_UNARY_ARGS (argument_type p) const \ - { return (m_pfn(p.*m_pv)); } -#define MEM_VAR_BINARY_ARGS (argument_type p1, argument_type p2) const \ - { return (m_pfn(p1.*m_pv, p2.*m_pv)); } - -MEM_VAR_T(mem_var1, T&, VT T::*, FUNCTOR_UNARY_BASE(T&), MEM_VAR_UNARY_ARGS) -MEM_VAR_T(const_mem_var1, const T&, const VT T::*, FUNCTOR_UNARY_BASE(T&), MEM_VAR_UNARY_ARGS) -MEM_VAR_T(mem_var2, T&, VT T::*, FUNCTOR_BINARY_BASE(T&), MEM_VAR_BINARY_ARGS) -MEM_VAR_T(const_mem_var2, const T&, const VT T::*, FUNCTOR_BINARY_BASE(T&), MEM_VAR_BINARY_ARGS) - -#undef MEM_VAR_UNARY_ARGS -#undef MEM_VAR_BINARY_ARGS - -#endif // DOXYGEN_SHOULD_SKIP_THIS - -/// Returned functor passes member variable \p mvp reference of given object to equal\<VT\>. -/// \ingroup FunctorAccessors -template <class T, typename VT> -inline const_mem_var1_t<binder2nd<equal_to<VT> >, T, VT> -mem_var_equal_to (const VT T::*mvp, const VT& v) -{ - return (const_mem_var1_t<binder2nd<equal_to<VT> >,T,VT> (mvp, bind2nd(equal_to<VT>(), v))); -} - -/// Returned functor passes member variable \p mvp reference of given object to less\<VT\>. -/// \ingroup FunctorAccessors -template <class T, typename VT> -inline const_mem_var1_t<binder2nd<less<VT> >, T, VT> -mem_var_less (const VT T::*mvp, const VT& v) -{ - return (const_mem_var1_t<binder2nd<less<VT> >,T,VT> (mvp, bind2nd(less<VT>(), v))); -} - -/// Returned functor passes member variable \p mvp reference of given object to equal\<VT\>. -/// \ingroup FunctorAccessors -template <class T, typename VT> -inline const_mem_var2_t<equal_to<VT>, T, VT> -mem_var_equal_to (const VT T::*mvp) -{ - return (const_mem_var2_t<equal_to<VT>,T,VT> (mvp, equal_to<VT>())); -} - -/// Returned functor passes member variable \p mvp reference of given object to less\<VT\>. -/// \ingroup FunctorAccessors -template <class T, typename VT> -inline const_mem_var2_t<less<VT>, T, VT> -mem_var_less (const VT T::*mvp) -{ - return (const_mem_var2_t<less<VT>,T,VT> (mvp, less<VT>())); -} - -//---------------------------------------------------------------------- -// Dereference adaptors (uSTL extension) -//---------------------------------------------------------------------- - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -#define DEREFERENCER_T(ClassName, ArgType, BaseClass, CallImpl, FunctorKey) \ - template <typename T, typename Function> \ - class ClassName : public BaseClass { \ - public: \ - typedef ArgType* argument_type; \ - typedef typename Function::result_type result_type; \ - public: \ - inline ClassName (Function pfn) : m_pfn (pfn) {} \ - inline result_type operator() CallImpl \ - private: \ - Function m_pfn; \ - }; \ - \ - template <typename T, typename Function> \ - inline ClassName<T,Function> _dereference (Function pfn, FunctorKey) \ - { \ - return (ClassName<T,Function> (pfn)); \ - } - -#define DEREF_UNARY_ARGS (argument_type p) const \ - { return (m_pfn(*p)); } -#define DEREF_BINARY_ARGS (argument_type p1, argument_type p2) const \ - { return (m_pfn(*p1, *p2)); } - -DEREFERENCER_T(deref1_t, T, FUNCTOR_UNARY_BASE(T*), DEREF_UNARY_ARGS, FUNCTOR_UNARY_BASE(T)) -DEREFERENCER_T(const_deref1_t, const T, FUNCTOR_UNARY_BASE(const T*), DEREF_UNARY_ARGS, FUNCTOR_UNARY_BASE(const T)) -DEREFERENCER_T(deref2_t, T, FUNCTOR_BINARY_BASE(T*), DEREF_BINARY_ARGS, FUNCTOR_BINARY_BASE(T)) -DEREFERENCER_T(const_deref2_t, const T, FUNCTOR_BINARY_BASE(const T*), DEREF_BINARY_ARGS, FUNCTOR_BINARY_BASE(const T)) - -#define dereference(f) _dereference(f,f) - -#undef DEREF_UNARY_ARGS -#undef DEREF_BINARY_ARGS - -#endif - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/uheap.h +++ /dev/null @@ -1,142 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UHEAP_H_574B9EAF271A1C107190B4D575A356C5 -#define UHEAP_H_574B9EAF271A1C107190B4D575A356C5 - -#include "ualgobase.h" - -namespace ustl { - -/// \brief Returns true if the given range is a heap under \p comp. -/// A heap is a sequentially encoded binary tree where for every node -/// comp(node,child1) is false and comp(node,child2) is false. -/// \ingroup HeapAlgorithms -/// \ingroup ConditionAlgorithms -/// -template <typename RandomAccessIterator, typename Compare> -bool is_heap (RandomAccessIterator first, RandomAccessIterator last, Compare comp) -{ - RandomAccessIterator iChild (first); - for (; ++iChild < last; ++first) - if (comp (*first, *iChild) || (++iChild < last && comp (*first, *iChild))) - return (false); - return (true); -} - -/// \brief make_heap turns the range [first, last) into a heap -/// At completion, is_heap (first, last, comp) is true. -/// The algorithm is adapted from "Classic Data Structures in C++" by Timothy Budd. -/// \ingroup HeapAlgorithms -/// \ingroup SortingAlgorithms -/// -template <typename RandomAccessIterator, typename Compare> -void make_heap (RandomAccessIterator first, RandomAccessIterator last, Compare comp) -{ - typedef typename iterator_traits<RandomAccessIterator>::value_type value_type; - const value_type v (*first); - uoff_t iChild, iHole = 0, iEnd (distance (first, last)); - while ((iChild = 2 * iHole + 1) < iEnd) { - if (iChild + 1 < iEnd) // Pick the greater child - iChild += comp (first[iChild], first[iChild + 1]); - if (comp (first[iChild], v)) - break; // Done when parent is greater than both children. - first[iHole] = first[iChild]; - iHole = iChild; - } - if (iHole < iEnd) - first[iHole] = v; -} - -/// \brief Inserts the *--last into the preceeding range assumed to be a heap. -/// \ingroup HeapAlgorithms -/// \ingroup MutatingAlgorithms -template <typename RandomAccessIterator, typename Compare> -void push_heap (RandomAccessIterator first, RandomAccessIterator last, Compare comp) -{ - if (last <= first) - return; - typedef typename iterator_traits<RandomAccessIterator>::value_type value_type; - const value_type v (*--last); - while (first < last) { - RandomAccessIterator iParent = first + (distance(first, last) - 1) / 2; - if (comp (v, *iParent)) - break; - *last = *iParent; - last = iParent; - } - *last = v; -} - -/// Removes the largest element from the heap (*first) and places it at *(last-1) -/// [first, last-1) is a heap after this operation. -/// \ingroup HeapAlgorithms -/// \ingroup MutatingAlgorithms -template <typename RandomAccessIterator, typename Compare> -void pop_heap (RandomAccessIterator first, RandomAccessIterator last, Compare comp) -{ - if (--last <= first) - return; - iter_swap (first, last); - make_heap (first, last, comp); -} - -/// Sorts heap [first, last) in descending order according to comp. -/// \ingroup HeapAlgorithms -/// \ingroup SortingAlgorithms -template <typename RandomAccessIterator, typename Compare> -void sort_heap (RandomAccessIterator first, RandomAccessIterator last, Compare comp) -{ - for (; first < last; --last) - pop_heap (first, last, comp); -} - -#define HEAP_FN_WITH_LESS(rtype, name) \ -template <typename RandomAccessIterator>\ -inline rtype name (RandomAccessIterator first, RandomAccessIterator last) \ -{ \ - typedef typename iterator_traits<RandomAccessIterator>::value_type value_type; \ - return (name (first, last, less<value_type>())); \ -} -HEAP_FN_WITH_LESS (bool, is_heap) -HEAP_FN_WITH_LESS (void, make_heap) -HEAP_FN_WITH_LESS (void, push_heap) -HEAP_FN_WITH_LESS (void, pop_heap) -HEAP_FN_WITH_LESS (void, sort_heap) -#undef HEAP_FN_WITH_LESS - -/// \class priority_queue uheap.h ustl.h -/// \ingroup Sequences -/// -/// \brief Sorted queue adapter to uSTL containers. -/// -/// Acts just like the queue adapter, but keeps the elements sorted by priority -/// specified by the given comparison operator. -/// -template <typename T, typename Ctr = vector<T>, typename Comp = less<typename Ctr::value_type> > -class priority_queue { -public: - typedef Ctr base_ctr; - typedef typename base_ctr::value_type value_type; - typedef typename base_ctr::size_type size_type; - typedef typename base_ctr::const_pointer const_pointer; - typedef typename base_ctr::const_reference reference; -public: - priority_queue (const Comp& c = Comp()) : m_v(), m_c (c) {} - priority_queue (const_pointer f, const_pointer l, const Comp& c = Comp()) - : m_v (f, l), m_c (c) { make_heap (m_v.begin(), m_v.end(), m_c); } - inline size_type size (void) const { return (m_v.size()); } - inline bool empty (void) const { return (m_v.empty()); } - inline reference top (void) const { return (m_v.at(0)); } - inline void push (reference v) { m_v.push_back (v); make_heap (m_v.begin(), m_v.end(), m_c); } - inline void pop (void) { pop_heap (m_v.begin(), m_v.end()); m_v.pop_back(); } -private: - base_ctr m_v; ///< Element container. - Comp m_c; ///< Comparison functor by value. -}; - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/uios.h +++ /dev/null @@ -1,103 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UIOS_H_630C16E316F7650E3A02E1C6611B789A -#define UIOS_H_630C16E316F7650E3A02E1C6611B789A - -#include "utypes.h" - -namespace ustl { - -class file_exception; - -const char endl = '\n'; ///< End of line character. -const char ends = '\0'; ///< End of string character. - -/// Defines types and constants used by all stream classes. -class ios_base { -public: - /// Used to set parameters for stringstreams - enum fmtflags { - boolalpha = (1 << 0), ///< Boolean values printed as text. - dec = (1 << 1), ///< Decimal number output. - fixed = (1 << 2), ///< Fixed-point float output. - hex = (1 << 3), ///< Hexadecimal number output. - internal = (1 << 4), - left = (1 << 5), ///< Left alignment. - oct = (1 << 6), ///< Octal number output. - right = (1 << 7), ///< Right alignment. - scientific = (1 << 8), ///< Scientific float format. - showbase = (1 << 9), ///< Add 0x or 0 prefixes on hex and octal numbers. - showpoint = (1 << 10), ///< Print decimal point. - showpos = (1 << 11), - skipws = (1 << 12), ///< Skip whitespace when reading. - unitbuf = (1 << 13), - uppercase = (1 << 14), - adjustfield = (1 << 15), - basefield = (1 << 16), - floatfield = (1 << 17) - }; - /// For file-based streams, specifies fd mode. - enum openmode_bits { - in = (1 << 0), - out = (1 << 1), - app = (1 << 2), - ate = (1 << 3), - binary = (1 << 4), - trunc = (1 << 5), - #ifndef DOXYGEN_SHOULD_SKIP_THIS - nonblock= (1 << 6), - nocreate= (1 << 7), - noctty = (1 << 8), - nombits = 9 - #endif - }; - /// Seek directions, equivalent to SEEK_SET, SEEK_CUR, and SEEK_END. - enum seekdir { - beg, - cur, - end - }; - /// I/O state bitmasks. - enum iostate_bits { - goodbit = 0, - badbit = (1 << 0), - eofbit = (1 << 1), - failbit = (1 << 2), - #ifndef DOXYGEN_SHOULD_SKIP_THIS - nbadbits = 3, - allbadbits = 0x7 - #endif - }; - - typedef uint32_t openmode; ///< Holds openmode_bits. - typedef uint32_t iostate; ///< Holds iostate_bits for a file stream. - typedef file_exception failure; ///< Thrown by fstream on errors. - - static const char c_DefaultDelimiters [16]; ///< Default word delimiters for stringstreams. -public: - inline ios_base (void) : m_State (goodbit), m_Exceptions (allbadbits) {} - inline iostate rdstate (void) const { return (m_State); } - inline bool bad (void) const { return (rdstate() & badbit); } - inline bool good (void) const { return (rdstate() == goodbit); } - inline bool fail (void) const { return (rdstate() & (badbit | failbit)); } - inline bool eof (void) const { return (rdstate() & eofbit); } - inline bool operator! (void) const { return (fail()); } - inline operator void* (void) const { return (reinterpret_cast<void*>(!fail())); } - inline void clear (iostate v = goodbit) { m_State = v; } - inline void setstate (iostate v) { m_State |= v; } - inline iostate exceptions (void) const { return (m_Exceptions); } - inline iostate exceptions (iostate v) { return (m_Exceptions = v); } -protected: - inline bool set_and_throw (iostate v) { setstate(v); return (exceptions() & v); } - void overrun (const char* op, const char* type, uint32_t n, uint32_t p, uint32_t rem); -private: - uint16_t m_State; ///< Open state, using ios::iostate_bits. - uint16_t m_Exceptions; ///< Exception flags, using ios::iostate_bits. -}; - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/uiosfunc.h +++ /dev/null @@ -1,96 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UIOSFUNC_H_730C16E316F7650E3A02E1C6611B789A -#define UIOSFUNC_H_730C16E316F7650E3A02E1C6611B789A - -#include "sostream.h" - -namespace ustl { - -class ios : public ios_base { -public: - /// \class align uiosfunc.h ustl.h - /// \ingroup StreamFunctors - /// \brief Stream functor to allow inline align() calls. - /// - /// Example: os << ios::align(sizeof(uint16_t)); - /// - class align { - public: - inline explicit align (size_t grain = c_DefaultAlignment) : m_Grain(grain) {} - inline istream& apply (istream& is) const { is.align (m_Grain); return (is); } - inline ostream& apply (ostream& os) const { os.align (m_Grain); return (os); } - inline void read (istream& is) const { apply (is); } - inline void write (ostream& os) const { apply (os); } - inline size_t stream_size (void) const { return (m_Grain - 1); } - private: - const size_t m_Grain; - }; - - /// \class talign uiosfunc.h ustl.h - /// \ingroup StreamFunctors - /// \brief Stream functor to allow type-based alignment. - template <typename T> - class talign : public align { - public: - inline explicit talign (void) : align (alignof (NullValue<T>())) {} - }; - - /// \class skip uiosfunc.h ustl.h - /// \ingroup StreamFunctors - /// \brief Stream functor to allow inline skip() calls. - /// - /// Example: os << ios::skip(sizeof(uint16_t)); - /// - class skip { - public: - inline explicit skip (size_t nBytes) : m_nBytes(nBytes) {} - inline istream& apply (istream& is) const { is.skip (m_nBytes); return (is); } - inline ostream& apply (ostream& os) const { os.skip (m_nBytes); return (os); } - inline void read (istream& is) const { apply (is); } - inline void write (ostream& os) const { apply (os); } - inline size_t stream_size (void) const { return (m_nBytes); } - private: - const size_t m_nBytes; - }; - - /// \class width uiosfunc.h ustl.h - /// \ingroup StreamFunctors - /// \brief Stream functor to allow inline set_width() calls. - /// - /// Example: os << ios::width(15); - /// - class width { - public: - inline explicit width (size_t nBytes) : m_nBytes(nBytes) {} - inline ostringstream& apply (ostringstream& os) const { os.set_width (m_nBytes); return (os); } - inline void text_write (ostringstream& os) const { apply (os); } - private: - const size_t m_nBytes; - }; - - /// \class base uiosfunc.h ustl.h - /// \ingroup StreamFunctors - /// \brief Stream functor to allow inline set_base() calls. - /// - /// Example: os << ios::base(15); - /// - class base { - public: - inline explicit base (size_t n) : m_Base(n) {} - inline ostringstream& apply (ostringstream& os) const { os.set_base (m_Base); return (os); } - inline void text_write (ostringstream& os) const { apply (os); } - private: - const size_t m_Base; - }; -}; - -} // namespace ustl - -CAST_STREAMABLE(ustl::ios::fmtflags, uint32_t) -NUMERIC_LIMITS(ustl::ios::fmtflags, ustl::ios::boolalpha, ustl::ios::floatfield, false, true, true) - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/uiterator.h +++ /dev/null @@ -1,266 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. -// -/// \file uiterator.h -/// \brief Contains various iterator adapters. - -#ifndef UITERATOR_H_5BCA176C7214A30F2069E2614D2DC226 -#define UITERATOR_H_5BCA176C7214A30F2069E2614D2DC226 - -#include "utypes.h" - -namespace ustl { - -//---------------------------------------------------------------------- - -/// \struct iterator_traits uiterator.h ustl.h -/// \brief Contains the type traits of \p Iterator -/// -template <typename Iterator> -struct iterator_traits { - typedef typename Iterator::value_type value_type; - typedef typename Iterator::difference_type difference_type; - typedef typename Iterator::pointer pointer; - typedef typename Iterator::reference reference; -}; - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -template <typename T> -struct iterator_traits<T*> { - typedef T value_type; - typedef ptrdiff_t difference_type; - typedef const T* const_pointer; - typedef T* pointer; - typedef const T& const_reference; - typedef T& reference; -}; - -template <typename T> -struct iterator_traits<const T*> { - typedef T value_type; - typedef ptrdiff_t difference_type; - typedef const T* const_pointer; - typedef const T* pointer; - typedef const T& const_reference; - typedef const T& reference; -}; - -template <> -struct iterator_traits<void*> { - typedef uint8_t value_type; - typedef ptrdiff_t difference_type; - typedef const void* const_pointer; - typedef void* pointer; - typedef const value_type& const_reference; - typedef value_type& reference; -}; - -template <> -struct iterator_traits<const void*> { - typedef uint8_t value_type; - typedef ptrdiff_t difference_type; - typedef const void* const_pointer; - typedef const void* pointer; - typedef const value_type& const_reference; - typedef const value_type& reference; -}; - -#endif - -//---------------------------------------------------------------------- - -/// \class reverse_iterator uiterator.h ustl.h -/// \ingroup IteratorAdaptors -/// \brief Wraps \p Iterator to behave in an exactly opposite manner. -/// -template <class Iterator> -class reverse_iterator { -public: - typedef typename iterator_traits<Iterator>::value_type value_type; - typedef typename iterator_traits<Iterator>::difference_type difference_type; - typedef typename iterator_traits<Iterator>::pointer pointer; - typedef typename iterator_traits<Iterator>::reference reference; -public: - reverse_iterator (void) : m_i() {} - explicit reverse_iterator (Iterator iter) : m_i (iter) {} - inline bool operator== (const reverse_iterator& iter) const { return (m_i == iter.m_i); } - inline bool operator< (const reverse_iterator& iter) const { return (iter.m_i < m_i); } - inline Iterator base (void) const { return (m_i); } - inline reference operator* (void) const { Iterator prev (m_i); --prev; return (*prev); } - inline pointer operator-> (void) const { return (&(operator*())); } - inline reverse_iterator& operator++ (void) { -- m_i; return (*this); } - inline reverse_iterator& operator-- (void) { ++ m_i; return (*this); } - inline reverse_iterator operator++ (int) { reverse_iterator prev (*this); -- m_i; return (prev); } - inline reverse_iterator operator-- (int) { reverse_iterator prev (*this); ++ m_i; return (prev); } - inline reverse_iterator& operator+= (size_t n) { m_i -= n; return (*this); } - inline reverse_iterator& operator-= (size_t n) { m_i += n; return (*this); } - inline reverse_iterator operator+ (size_t n) const { return (reverse_iterator (m_i - n)); } - inline reverse_iterator operator- (size_t n) const { return (reverse_iterator (m_i + n)); } - inline reference operator[] (uoff_t n) const { return (*(*this + n)); } - inline difference_type operator- (const reverse_iterator& i) const { return (distance (m_i, i.m_i)); } -protected: - Iterator m_i; -}; - -//---------------------------------------------------------------------- - -/// \class insert_iterator uiterator.h ustl.h -/// \ingroup IteratorAdaptors -/// \brief Calls insert on bound container for each assignment. -/// -template <class Container> -class insert_iterator { -public: - typedef typename Container::value_type value_type; - typedef typename Container::difference_type difference_type; - typedef typename Container::pointer pointer; - typedef typename Container::reference reference; - typedef typename Container::iterator iterator; -public: - explicit insert_iterator (Container& ctr, iterator ip) : m_rCtr (ctr), m_ip (ip) {} - inline insert_iterator& operator= (typename Container::const_reference v) - { m_ip = m_rCtr.insert (m_ip, v); return (*this); } - inline insert_iterator& operator* (void) { return (*this); } - inline insert_iterator& operator++ (void) { ++ m_ip; return (*this); } - inline insert_iterator operator++ (int) { insert_iterator prev (*this); ++ m_ip; return (*this); } -protected: - Container& m_rCtr; - iterator m_ip; -}; - -/// Returns the insert_iterator for \p ctr. -template <class Container> -inline insert_iterator<Container> inserter (Container& ctr, typename Container::iterator ip) -{ - return (insert_iterator<Container> (ctr, ip)); -} - -//---------------------------------------------------------------------- - -/// \class back_insert_iterator uiterator.h ustl.h -/// \ingroup IteratorAdaptors -/// \brief Calls push_back on bound container for each assignment. -/// -template <class Container> -class back_insert_iterator { -public: - typedef typename Container::value_type value_type; - typedef typename Container::difference_type difference_type; - typedef typename Container::pointer pointer; - typedef typename Container::reference reference; -public: - explicit back_insert_iterator (Container& ctr) : m_rCtr (ctr) {} - inline back_insert_iterator& operator= (typename Container::const_reference v) - { m_rCtr.push_back (v); return (*this); } - inline back_insert_iterator& operator* (void) { return (*this); } - inline back_insert_iterator& operator++ (void) { return (*this); } - inline back_insert_iterator operator++ (int) { return (*this); } -protected: - Container& m_rCtr; -}; - -/// Returns the back_insert_iterator for \p ctr. -template <class Container> -inline back_insert_iterator<Container> back_inserter (Container& ctr) -{ - return (back_insert_iterator<Container> (ctr)); -} - -//---------------------------------------------------------------------- - -/// \class index_iterate uiterator.h ustl.h -/// \ingroup IteratorAdaptors -/// -/// \brief Allows iteration through an index container. -/// -/// Converts an iterator into a container of uoff_t indexes to an -/// iterator of iterators into another container. -/// -template <typename RandomAccessIterator, typename IndexIterator> -class index_iterate { -public: - typedef RandomAccessIterator value_type; - typedef ptrdiff_t difference_type; - typedef RandomAccessIterator* pointer; - typedef RandomAccessIterator reference; -public: - index_iterate (void) : m_Base(), m_i() {} - index_iterate (RandomAccessIterator ibase, IndexIterator iindex) : m_Base (ibase), m_i (iindex) {} - inline bool operator== (const index_iterate& i) const { return (m_i == i.m_i); } - inline bool operator< (const index_iterate& i) const { return (m_i < i.m_i); } - inline bool operator== (const RandomAccessIterator& i) const { return (m_Base == i); } - inline bool operator< (const RandomAccessIterator& i) const { return (m_Base < i); } - inline IndexIterator base (void) const { return (m_i); } - inline reference operator* (void) const { return (advance(m_Base, *m_i)); } - inline pointer operator-> (void) const { return (&(operator*())); } - inline index_iterate& operator++ (void) { ++ m_i; return (*this); } - inline index_iterate& operator-- (void) { -- m_i; return (*this); } - inline index_iterate operator++ (int) { index_iterate prev (*this); ++ m_i; return (prev); } - inline index_iterate operator-- (int) { index_iterate prev (*this); -- m_i; return (prev); } - inline index_iterate& operator+= (size_t n) { m_i += n; return (*this); } - inline index_iterate& operator-= (size_t n) { m_i -= n; return (*this); } - inline index_iterate operator+ (size_t n) const { return (index_iterate (m_Base, m_i + n)); } - inline index_iterate operator- (size_t n) const { return (index_iterate (m_Base, m_i - n)); } - inline reference operator[] (uoff_t n) const { return (*(*this + n)); } - inline difference_type operator- (const index_iterate& i) const { return (distance (m_i, i.m_i)); } -private: - RandomAccessIterator m_Base; - IndexIterator m_i; -}; - -/// Returns an index_iterate for \p ibase over \p iindex. -template <typename RandomAccessIterator, typename IndexIterator> -inline index_iterate<RandomAccessIterator, IndexIterator> index_iterator (RandomAccessIterator ibase, IndexIterator iindex) -{ - return (index_iterate<RandomAccessIterator, IndexIterator> (ibase, iindex)); -} - -/// Converts the indexes in \p xc to iterators in \p ic of base \p ibase. -template <typename IndexContainer, typename IteratorContainer> -inline void indexv_to_iteratorv (typename IteratorContainer::value_type ibase, const IndexContainer& xc, IteratorContainer& ic) -{ - ic.resize (xc.size()); - copy_n (index_iterator (ibase, xc.begin()), xc.size(), ic.begin()); -} - -//---------------------------------------------------------------------- - -/// Converts the given const_iterator into an iterator. -/// -template <typename Container> -inline typename Container::iterator unconst (typename Container::const_iterator i, Container&) - { return (const_cast<typename Container::iterator>(i)); } - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -#define IBYI(Iter1, Iter2, Ctr1, Ctr2) \ -template <typename Container1, typename Container2> \ -inline typename Container2::Iter2 ibyi (typename Container1::Iter1 idx, Ctr1& ctr1, Ctr2& ctr2) \ -{ \ - assert (ctr1.size() == ctr2.size()); \ - return (ctr2.begin() + (idx - ctr1.begin())); \ -} - -IBYI(const_iterator, const_iterator, const Container1, const Container2) -IBYI(iterator, iterator, Container1, Container2) -IBYI(const_iterator, iterator, const Container1, Container2) -IBYI(iterator, const_iterator, Container1, const Container2) - -#else // DOXYGEN - -#error This declaration is for doxygen only; it is not compiled. - -/// Converts a const_iterator in one container into a const_iterator in another container. -template <typename Container1, typename Container2> -inline typename Container2::iterator ibyi (typename Container1::iterator idx, Container1& ctr1, Container2& ctr2) {} - -#endif // DOXYGEN - -//---------------------------------------------------------------------- - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/ulaalgo.h +++ /dev/null @@ -1,221 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef ULAALGO_H_2E403D182E83FB596AFB800E68B255A1 -#define ULAALGO_H_2E403D182E83FB596AFB800E68B255A1 - -#include "umatrix.h" -#include "simd.h" - -namespace ustl { - -/// \brief Creates an identity matrix in \p m -/// \ingroup NumericAlgorithms -template <size_t NX, size_t NY, typename T> -void load_identity (matrix<NX,NY,T>& m) -{ - fill_n (m.begin(), NX * NY, 0); - for (typename matrix<NX,NY,T>::iterator i = m.begin(); i < m.end(); i += NX + 1) - *i = 1; -} - -/// \brief Multiplies two matrices -/// \ingroup NumericAlgorithms -template <size_t NX, size_t NY, typename T> -matrix<NY,NY,T> operator* (const matrix<NX,NY,T>& m1, const matrix<NY,NX,T>& m2) -{ - matrix<NY,NY,T> mr; - for (uoff_t ry = 0; ry < NY; ++ ry) { - for (uoff_t rx = 0; rx < NY; ++ rx) { - T dpv (0); - for (uoff_t x = 0; x < NX; ++ x) - dpv += m1[ry][x] * m2[x][rx]; - mr[ry][rx] = dpv; - } - } - return (mr); -} - -/// \brief Transforms vector \p t with matrix \p m -/// \ingroup NumericAlgorithms -template <size_t NX, size_t NY, typename T> -tuple<NX,T> operator* (const tuple<NY,T>& t, const matrix<NX,NY,T>& m) -{ - tuple<NX,T> tr; - for (uoff_t x = 0; x < NX; ++ x) { - T dpv (0); - for (uoff_t y = 0; y < NY; ++ y) - dpv += t[y] * m[y][x]; - tr[x] = dpv; - } - return (tr); -} - -/// \brief Transposes (exchanges rows and columns) matrix \p m. -/// \ingroup NumericAlgorithms -template <size_t N, typename T> -void transpose (matrix<N,N,T>& m) -{ - for (uoff_t x = 0; x < N; ++ x) - for (uoff_t y = x; y < N; ++ y) - swap (m[x][y], m[y][x]); -} - -#if WANT_UNROLLED_COPY - -#if CPU_HAS_SSE - -#if linux // Non-linux gcc versions (BSD, Solaris) can't handle "x" constraint and provide no alternative. -template <> -inline void load_identity (matrix<4,4,float>& m) -{ - asm ( - "movaps %4, %%xmm1 \n\t" // 1 0 0 0 - "movups %4, %0 \n\t" // 1 0 0 0 - "shufps $0xB1,%%xmm1,%%xmm1 \n\t" // 0 1 0 0 - "movups %%xmm1, %1 \n\t" // 0 1 0 0 - "shufps $0x4F,%4,%%xmm1 \n\t" // 0 0 1 0 - "shufps $0x1B,%4,%4 \n\t" // 0 0 0 1 - "movups %%xmm1, %2 \n\t" // 0 0 1 0 - "movups %4, %3" // 0 0 0 1 - : "=m"(m[0][0]), "=m"(m[1][0]), "=m"(m[2][0]), "=m"(m[3][0]) - : "x"(1.0f) - : "xmm1", "memory" - ); - asm ("":::"memory"); -} -#endif - -inline void _sse_load_matrix (const float* m) -{ - asm ( - "movups %0, %%xmm4 \n\t" // xmm4 = m[1 2 3 4] - "movups %1, %%xmm5 \n\t" // xmm5 = m[1 2 3 4] - "movups %2, %%xmm6 \n\t" // xmm6 = m[1 2 3 4] - "movups %3, %%xmm7" // xmm7 = m[1 2 3 4] - : : "m"(m[0]), "m"(m[4]), "m"(m[8]), "m"(m[12]) - : "xmm4", "xmm5", "xmm6", "xmm7", "memory" - ); -} - -inline void _sse_transform_to_vector (float* result) -{ - asm ( - "movaps %%xmm0, %%xmm1 \n\t" // xmm1 = t[0 1 2 3] - "movaps %%xmm0, %%xmm2 \n\t" // xmm1 = t[0 1 2 3] - "movaps %%xmm0, %%xmm3 \n\t" // xmm1 = t[0 1 2 3] - "shufps $0x00, %%xmm0, %%xmm0 \n\t" // xmm0 = t[0 0 0 0] - "shufps $0x66, %%xmm1, %%xmm1 \n\t" // xmm1 = t[1 1 1 1] - "shufps $0xAA, %%xmm2, %%xmm2 \n\t" // xmm2 = t[2 2 2 2] - "shufps $0xFF, %%xmm3, %%xmm3 \n\t" // xmm3 = t[3 3 3 3] - "mulps %%xmm4, %%xmm0 \n\t" // xmm0 = t[0 0 0 0] * m[0 1 2 3] - "mulps %%xmm5, %%xmm1 \n\t" // xmm1 = t[1 1 1 1] * m[0 1 2 3] - "addps %%xmm1, %%xmm0 \n\t" // xmm0 = xmm0 + xmm1 - "mulps %%xmm6, %%xmm2 \n\t" // xmm2 = t[2 2 2 2] * m[0 1 2 3] - "mulps %%xmm7, %%xmm3 \n\t" // xmm3 = t[3 3 3 3] * m[0 1 2 3] - "addps %%xmm3, %%xmm2 \n\t" // xmm2 = xmm2 + xmm3 - "addps %%xmm2, %%xmm0 \n\t" // xmm0 = result - "movups %%xmm0, %0" - : "=m"(result[0]), "=m"(result[1]), "=m"(result[2]), "=m"(result[3]) : - : "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "memory" - ); -} - -template <> -inline tuple<4,float> operator* (const tuple<4,float>& t, const matrix<4,4,float>& m) -{ - tuple<4,float> result; - _sse_load_matrix (m.begin()); - asm ("movups %0, %%xmm0" : : "m"(t[0]), "m"(t[1]), "m"(t[2]), "m"(t[3]) : "xmm0", "memory"); - _sse_transform_to_vector (result.begin()); - return (result); -} - -template <> -inline matrix<4,4,float> operator* (const matrix<4,4,float>& m1, const matrix<4,4,float>& m2) -{ - matrix<4,4,float> result; - _sse_load_matrix (m2.begin()); - for (uoff_t r = 0; r < 4; ++ r) { - asm ("movups %0, %%xmm0" : : "m"(m1[r][0]), "m"(m1[r][1]), "m"(m1[r][2]), "m"(m1[r][3]) : "xmm0", "memory"); - _sse_transform_to_vector (result[r]); - } - return (result); -} - -#elif CPU_HAS_3DNOW - -/// Specialization for 4-component vector transform, the slow part of 3D graphics. -template <> -static tuple<4,float> operator* (const tuple<4,float>& t, const matrix<4,4,float>& m) -{ - tuple<4,float> result; - // This is taken from "AMD Athlon Code Optimization Guide" from AMD. 18 cycles! - // If you are writing a 3D engine, you may want to copy it instead of calling it - // because of the femms instruction at the end, which takes 2 cycles. - asm ( - "movq %2, %%mm0 \n\t" // y | x - "movq %3, %%mm1 \n\t" // w | z - "movq %%mm0, %%mm2 \n\t" // y | x - "movq %4, %%mm3 \n\t" // m[0][1] | m[0][0] - "punpckldq %%mm0, %%mm0 \n\t" // x | x - "movq %6, %%mm4 \n\t" // m[1][1] | m[1][0] - "pfmul %%mm0, %%mm3 \n\t" // x*m[0][1] | x*m[0][0] - "punpckhdq %%mm2, %%mm2 \n\t" // y | y - "pfmul %%mm2, %%mm4 \n\t" // y*m[1][1] | y*m[1][0] - "movq %5, %%mm5 \n\t" // m[0][3] | m[0][2] - "movq %7, %%mm7 \n\t" // m[1][3] | m[1][2] - "movq %%mm1, %%mm6 \n\t" // w | z - "pfmul %%mm0, %%mm5 \n\t" // x*m[0][3] | v0>x*m[0][2] - "movq %8, %%mm0 \n\t" // m[2][1] | m[2][0] - "punpckldq %%mm1, %%mm1 \n\t" // z | z - "pfmul %%mm2, %%mm7 \n\t" // y*m[1][3] | y*m[1][2] - "movq %9, %%mm2 \n\t" // m[2][3] | m[2][2] - "pfmul %%mm1, %%mm0 \n\t" // z*m[2][1] | z*m[2][0] - "pfadd %%mm4, %%mm3 \n\t" // x*m[0][1]+y*m[1][1] | x*m[0][0]+y*m[1][0] - "movq %10, %%mm4 \n\t" // m[3][1] | m[3][0] - "pfmul %%mm1, %%mm2 \n\t" // z*m[2][3] | z*m[2][2] - "pfadd %%mm7, %%mm5 \n\t" // x*m[0][3]+y*m[1][3] | x*m[0][2]+y*m[1][2] - "movq %11, %%mm1 \n\t" // m[3][3] | m[3][2] - "punpckhdq %%mm6, %%mm6 \n\t" // w | w - "pfadd %%mm0, %%mm3 \n\t" // x*m[0][1]+y*m[1][1]+z*m[2][1] | x*m[0][0]+y*m[1][0]+z*m[2][0] - "pfmul %%mm6, %%mm4 \n\t" // w*m[3][1] | w*m[3][0] - "pfmul %%mm6, %%mm1 \n\t" // w*m[3][3] | w*m[3][2] - "pfadd %%mm2, %%mm5 \n\t" // x*m[0][3]+y*m[1][3]+z*m[2][3] | x*m[0][2]+y*m[1][2]+z*m[2][2] - "pfadd %%mm4, %%mm3 \n\t" // x*m[0][1]+y*m[1][1]+z*m[2][1]+w*m[3][1] | x*m[0][0]+y*m[1][0]+z*m[2][0]+w*m[3][0] - "movq %%mm3, %0 \n\t" // store result->y | result->x - "pfadd %%mm1, %%mm5 \n\t" // x*m[0][3]+y*m[1][3]+z*m[2][3]+w*m[3][3] | x*m[0][2]+y*m[1][2]+z*m[2][2]+w*m[3][2] - "movq %%mm5, %1" // store result->w | result->z - : "=m"(result[0]), "=m"(result[2]) - : "m"(t[0]), "m"(t[2]), - "m"(m[0][0]), "m"(m[0][2]), - "m"(m[1][0]), "m"(m[1][2]), - "m"(m[2][0]), "m"(m[2][2]), - "m"(m[3][0]), "m"(m[3][2]) - : ALL_MMX_REGS_CHANGELIST, "memory" - ); - asm ("":::"memory"); - simd::reset_mmx(); - return (result); -} - -#else // If no processor extensions, just unroll the multiplication - -/// Specialization for 4-component vector transform, the slow part of 3D graphics. -template <> -static tuple<4,float> operator* (const tuple<4,float>& t, const matrix<4,4,float>& m) -{ - tuple<4,float> tr; - for (uoff_t i = 0; i < 4; ++ i) - tr[i] = t[0] * m[0][i] + t[1] * m[1][i] + t[2] * m[2][i] + t[3] * m[3][i]; - return (tr); -} - -#endif // CPU_HAS_3DNOW -#endif // WANT_UNROLLED_COPY - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/ulimits.h +++ /dev/null @@ -1,104 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef ULIMITS_H_1C2192EA3821E0811BBAF86B0F048364 -#define ULIMITS_H_1C2192EA3821E0811BBAF86B0F048364 - -#include "utypes.h" - -namespace ustl { - -#define __limits_digits(T) (sizeof(T)*8) -#define __limits_digits10(T) (sizeof(T)*8*643/2136+1) - -/// \class numeric_limits ulimits.h ustl.h -/// \brief Defines numeric limits for a type. -/// -template <typename T> -struct numeric_limits { - /// Returns the minimum value for type T. - static inline T min (void) { return (T(0)); } - /// Returns the minimum value for type T. - static inline T max (void) { return (T(0)); } - static const bool is_signed = false; ///< True if the type is signed. - static const bool is_integer = false; ///< True if stores an exact value. - static const bool is_integral = false; ///< True if fixed size and cast-copyable. - static const unsigned digits = __limits_digits(T); ///< Number of bits in T - static const unsigned digits10 = __limits_digits10(T); ///< Maximum number of decimal digits in printed version of T -}; - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -template <typename T> -struct numeric_limits<T*> { - static inline T* min (void) { return (NULL); } - static inline T* max (void) { return (reinterpret_cast<T*>(UINTPTR_MAX)); } - static const bool is_signed = false; - static const bool is_integer = true; - static const bool is_integral = true; - static const unsigned digits = __limits_digits(T*); - static const unsigned digits10 = __limits_digits10(T*); -}; - -#define _NUMERIC_LIMITS(type, minVal, maxVal, bSigned, bInteger, bIntegral) \ -template <> \ -struct numeric_limits<type> { \ - static inline type min (void) { return (minVal); } \ - static inline type max (void) { return (maxVal); } \ - static const bool is_signed = bSigned; \ - static const bool is_integer = bInteger; \ - static const bool is_integral = bIntegral; \ - static const unsigned digits = __limits_digits(type); \ - static const unsigned digits10 = __limits_digits10(type); \ -} - -//-------------------------------------------------------------------------------------- -// type min max signed integer integral -//-------------------------------------------------------------------------------------- -_NUMERIC_LIMITS (bool, false, true, false, true, true); -_NUMERIC_LIMITS (char, CHAR_MIN, CHAR_MAX, true, true, true); -_NUMERIC_LIMITS (int, INT_MIN, INT_MAX, true, true, true); -_NUMERIC_LIMITS (short, SHRT_MIN, SHRT_MAX, true, true, true); -_NUMERIC_LIMITS (long, LONG_MIN, LONG_MAX, true, true, true); -#if HAVE_THREE_CHAR_TYPES -_NUMERIC_LIMITS (signed char, SCHAR_MIN, SCHAR_MAX, true, true, true); -#endif -_NUMERIC_LIMITS (unsigned char, 0, UCHAR_MAX, false, true, true); -_NUMERIC_LIMITS (unsigned int, 0, UINT_MAX, false, true, true); -_NUMERIC_LIMITS (unsigned short,0, USHRT_MAX, false, true, true); -_NUMERIC_LIMITS (unsigned long, 0, ULONG_MAX, false, true, true); -_NUMERIC_LIMITS (wchar_t, 0, WCHAR_MAX, false, true, true); -_NUMERIC_LIMITS (float, FLT_MIN, FLT_MAX, true, false, true); -_NUMERIC_LIMITS (double, DBL_MIN, DBL_MAX, true, false, true); -_NUMERIC_LIMITS (long double, LDBL_MIN, LDBL_MAX, true, false, true); -#if HAVE_LONG_LONG -_NUMERIC_LIMITS (long long, LLONG_MIN, LLONG_MAX, true, true, true); -_NUMERIC_LIMITS (unsigned long long, 0, ULLONG_MAX, false, true, true); -#endif -//-------------------------------------------------------------------------------------- - -#endif // DOXYGEN_SHOULD_SKIP_THIS - -/// Macro for defining numeric_limits specializations -#define NUMERIC_LIMITS(type, minVal, maxVal, bSigned, bInteger, bIntegral) \ -namespace ustl { _NUMERIC_LIMITS (type, minVal, maxVal, bSigned, bInteger, bIntegral); } - -/// \brief Returns the recommended stream alignment for type \p T. Override with ALIGNOF. -/// Because this is occasionally called with a null value, do not access the argument! -template <typename T> -inline size_t alignof (const T&) -{ - if (numeric_limits<T>::is_integral) - return (__alignof__(T)); - return (4); -} - -#define ALIGNOF(type,grain) \ -namespace ustl { \ - template <> inline size_t alignof (const type&) { return (grain); } } - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/ulist.h +++ /dev/null @@ -1,74 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef ULIST_H_54E3B510498982C87A0A1E1932E6729D -#define ULIST_H_54E3B510498982C87A0A1E1932E6729D - -#include "uvector.h" -#include "uctralgo.h" - -namespace ustl { - -/// \class list ulist.h ustl.h -/// \ingroup Sequences -/// -/// \brief Linked list, defined as an alias to vector. -/// -template <typename T> -class list : public vector<T> { -public: - typedef typename vector<T>::size_type size_type; - typedef typename vector<T>::iterator iterator; - typedef typename vector<T>::const_iterator const_iterator; - typedef typename vector<T>::reference reference; - typedef typename vector<T>::const_reference const_reference; -public: - inline list (void) : vector<T> () {} - inline explicit list (size_type n) : vector<T> (n) {} - inline list (size_type n, const T& v) : vector<T> (n, v) {} - inline list (const list<T>& v) : vector<T> (v) {} - inline list (const_iterator i1, const_iterator i2) : vector<T> (i1, i2) {} - inline size_type size (void) const { return (vector<T>::size()); } - inline iterator begin (void) { return (vector<T>::begin()); } - inline const_iterator begin (void) const { return (vector<T>::begin()); } - inline iterator end (void) { return (vector<T>::end()); } - inline const_iterator end (void) const { return (vector<T>::end()); } - inline void push_front (const T& v) { insert (begin(), v); } - inline void pop_front (void) { erase (begin()); } - inline const_reference front (void) const { return (*begin()); } - inline reference front (void) { return (*begin()); } - inline void remove (const T& v) { ::ustl::remove (*this, v); } - inline void unique (void) { ::ustl::unique (*this); } - inline void sort (void) { ::ustl::sort (*this); } - void merge (list<T>& l); - void splice (iterator ip, list<T>& l, iterator first = NULL, iterator last = NULL); -}; - -/// Merges the contents with \p l. Assumes both lists are sorted. -template <typename T> -void list<T>::merge (list& l) -{ - list<T>::resize (size() + l.size()); - iterator me = merge (begin(), end(), l.begin(), l.end(), begin()); - list<T>::resize (distance (begin(), me)); -} - -/// Moves the range [first, last) from \p l to this list at \p ip. -template <typename T> -void list<T>::splice (iterator ip, list<T>& l, iterator first, iterator last) -{ - if (!first) - first = l.begin(); - if (!last) - last = l.end(); - insert (ip, first, last); - l.erase (first, last); -} - -#define deque list ///< list has all the functionality provided by deque - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/umap.h +++ /dev/null @@ -1,160 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UMAP_H_45643F516E02A87A3DCEA5024052A6F5 -#define UMAP_H_45643F516E02A87A3DCEA5024052A6F5 - -#include "uvector.h" -#include "ufunction.h" - -namespace ustl { - -/// \class map umap.h ustl.h -/// \ingroup AssociativeContainers -/// -/// \brief A sorted associative container of pair<K,V> -/// -template <typename K, typename V> -class map : public vector<pair<K,V> > { -public: - typedef K key_type; - typedef V data_type; - typedef const K& const_key_ref; - typedef const V& const_data_ref; - typedef const map<K,V>& rcself_t; - typedef vector<pair<K,V> > base_class; - typedef typename base_class::value_type value_type; - typedef typename base_class::size_type size_type; - typedef typename base_class::pointer pointer; - typedef typename base_class::const_pointer const_pointer; - typedef typename base_class::reference reference; - typedef typename base_class::const_reference const_reference; - typedef typename base_class::const_iterator const_iterator; - typedef typename base_class::iterator iterator; - typedef typename base_class::reverse_iterator reverse_iterator; - typedef typename base_class::const_reverse_iterator const_reverse_iterator; - typedef pair<const_iterator,const_iterator> const_range_t; - typedef pair<iterator,iterator> range_t; - typedef pair<iterator,bool> insertrv_t; -public: - inline map (void) : vector<pair<K,V> > () {} - explicit inline map (size_type n) : vector<pair<K,V> > (n) {} - inline map (rcself_t v) : vector<pair<K,V> > (v) {} - inline map (const_iterator i1, const_iterator i2) : vector<pair<K,V> >() { insert (i1, i2); } - inline rcself_t operator= (rcself_t v) { base_class::operator= (v); return (*this); } - inline const_data_ref operator[] (const_key_ref i) const; - data_type& operator[] (const_key_ref i); - inline size_type size (void) const { return (base_class::size()); } - inline iterator begin (void) { return (base_class::begin()); } - inline const_iterator begin (void) const { return (base_class::begin()); } - inline iterator end (void) { return (base_class::end()); } - inline const_iterator end (void) const { return (base_class::end()); } - inline void assign (const_iterator i1, const_iterator i2) { clear(); insert (i1, i2); } - inline void push_back (const_reference v) { insert (v); } - inline const_iterator find (const_key_ref k) const; - inline iterator find (const_key_ref k) { return (const_cast<iterator> (const_cast<rcself_t>(*this).find (k))); } - inline const_iterator find_data (const_data_ref v, const_iterator first = NULL, const_iterator last = NULL) const; - inline iterator find_data (const_data_ref v, iterator first = NULL, iterator last = NULL); - insertrv_t insert (const_reference v); - void insert (const_iterator i1, const_iterator i2); - inline void erase (const_key_ref k); - inline iterator erase (iterator ep) { return (base_class::erase (ep)); } - inline iterator erase (iterator ep1, iterator ep2) { return (base_class::erase (ep1, ep2)); } - inline void clear (void) { base_class::clear(); } -private: - const_iterator lower_bound (const_key_ref k) const; - inline iterator lower_bound (const_key_ref k) { return (const_cast<iterator>(const_cast<rcself_t>(*this).lower_bound (k))); } -}; - -template <typename K, typename V> -typename map<K,V>::const_iterator map<K,V>::lower_bound (const_key_ref k) const -{ - const_iterator first (begin()), last (end()); - while (first != last) { - const_iterator mid = advance (first, distance (first,last) / 2); - if (mid->first < k) - first = advance (mid, 1); - else - last = mid; - } - return (first); -} - -/// Returns the pair<K,V> where K = \p k. -template <typename K, typename V> -inline typename map<K,V>::const_iterator map<K,V>::find (const_key_ref k) const -{ - const_iterator i = lower_bound (k); - return ((i < end() && k < i->first) ? end() : i); -} - -/// Returns the pair<K,V> where V = \p v, occuring in range [first,last). -template <typename K, typename V> -inline typename map<K,V>::const_iterator map<K,V>::find_data (const_data_ref v, const_iterator first, const_iterator last) const -{ - if (!first) first = begin(); - if (!last) last = end(); - for (; first != last && first->second != v; ++first) ; - return (first); -} - -/// Returns the pair<K,V> where V = \p v, occuring in range [first,last). -template <typename K, typename V> -inline typename map<K,V>::iterator map<K,V>::find_data (const_data_ref v, iterator first, iterator last) -{ - return (const_cast<iterator> (find_data (v, const_cast<const_iterator>(first), const_cast<const_iterator>(last)))); -} - -/// Returns data associated with key \p k. -template <typename K, typename V> -inline const typename map<K,V>::data_type& map<K,V>::operator[] (const_key_ref k) const -{ - assert (find(k) != end() && "operator[] const can not insert non-existent keys"); - return (find(k)->second); -} - -/// Returns data associated with key \p k. -template <typename K, typename V> -typename map<K,V>::data_type& map<K,V>::operator[] (const_key_ref k) -{ - iterator ip = lower_bound (k); - if (ip == end() || k < ip->first) - ip = base_class::insert (ip, make_pair (k, V())); - return (ip->second); -} - -/// Inserts the pair into the container. -template <typename K, typename V> -typename map<K,V>::insertrv_t map<K,V>::insert (const_reference v) -{ - iterator ip = lower_bound (v.first); - bool bInserted = ip == end() || v.first < ip->first; - if (bInserted) - ip = base_class::insert (ip, v); - return (make_pair (ip, bInserted)); -} - -/// Inserts elements from range [i1,i2) into the container. -template <typename K, typename V> -void map<K,V>::insert (const_iterator i1, const_iterator i2) -{ - assert (i1 <= i2); - reserve (size() + distance (i1, i2)); - for (; i1 != i2; ++i1) - insert (*i1); -} - -/// Erases the element with key value \p k. -template <typename K, typename V> -inline void map<K,V>::erase (const_key_ref k) -{ - iterator ip = find (k); - if (ip != end()) - erase (ip); -} - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/umatrix.h +++ /dev/null @@ -1,121 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UMATRIX_H_740EBFEF554E833645E0FD72419A8185 -#define UMATRIX_H_740EBFEF554E833645E0FD72419A8185 - -#include "utuple.h" - -namespace ustl { - -/// \class matrix umatrix.h ustl.h -/// \ingroup Sequences -/// -/// \brief A two-dimensional array of NX*NY elements of type T. -/// -template <size_t NX, size_t NY, typename T> -class matrix : public tuple<NX*NY,T> { -public: - typedef tuple<NX,T> row_type; - typedef tuple<NY,T> column_type; - typedef tuple<NX*NY,T> tuple_type; - typedef typename tuple_type::value_type value_type; - typedef typename tuple_type::size_type size_type; - typedef typename tuple_type::pointer pointer; - typedef typename tuple_type::const_pointer const_pointer; - typedef typename tuple_type::reference reference; - typedef typename tuple_type::const_reference const_reference; - typedef typename tuple_type::iterator iterator; - typedef typename tuple_type::const_iterator const_iterator; - typedef typename tuple_type::range_t range_t; - typedef typename tuple_type::const_range_t const_range_t; - typedef typename tuple_type::reverse_iterator reverse_iterator; - typedef typename tuple_type::const_reverse_iterator const_reverse_iterator; -public: - inline matrix (void) { } - inline size_type columns (void) const { return (NX); } - inline size_type rows (void) const { return (NY); } - inline const_iterator at (size_type i) const { return (matrix::begin() + i * NX); } - inline iterator at (size_type i) { return (matrix::begin() + i * NX); } - inline const_iterator operator[] (size_type i) const { return (at (i)); } - inline iterator operator[] (size_type i) { return (at (i)); } - inline row_type row (size_type r) const { return (row_type (at (r))); } - inline column_type column (size_type c) const; - template <typename T2> - inline const matrix& operator= (const matrix<NX,NY,T2>& src) { tuple_type::operator= (src); return (*this); } - inline const matrix& operator= (const matrix<NX,NY,T>& src) { tuple_type::operator= (src); return (*this); } - inline const matrix& operator+= (const_reference v) { tuple_type::operator+= (v); return (*this); } - inline const matrix& operator-= (const_reference v) { tuple_type::operator-= (v); return (*this); } - inline const matrix& operator*= (const_reference v) { tuple_type::operator*= (v); return (*this); } - inline const matrix& operator/= (const_reference v) { tuple_type::operator/= (v); return (*this); } - inline const matrix operator+ (const_reference v) const - { matrix result (*this); result += v; return (result); } - inline const matrix operator- (const_reference v) const - { matrix result (*this); result -= v; return (result); } - inline const matrix operator* (const_reference v) const - { matrix result (*this); result *= v; return (result); } - inline const matrix operator/ (const_reference v) const - { matrix result (*this); result /= v; return (result); } -}; - -template <size_t NX, size_t NY, typename T> -inline typename matrix<NX,NY,T>::column_type matrix<NX,NY,T>::column (size_type c) const -{ - column_type result; - const_iterator src (matrix::begin() + c); - iterator dest (result.begin()); - for (uoff_t i = 0; i < NY; ++ i, ++ dest, src += NX) - *dest = *src; - return (result); -} - -//---------------------------------------------------------------------- -// Define SIMD specializations for member functions. - -#if CPU_HAS_SSE -#define MATRIX_R(v) "m"(v[0]),"m"(v[4]),"m"(v[8]),"m"(v[12]) -#define MATRIX_W(v) "=m"(v[0]),"=m"(v[4]),"=m"(v[8]),"=m"(v[12]) -#define SSE_TUPLE_SPECS(n,type) \ -template <> inline tuple<n,type>::tuple (void) \ -{ asm volatile ("xorps %%xmm0, %%xmm0\n\t" \ - "movups %%xmm0, %0\n\t" \ - "movups %%xmm0, %1\n\t" \ - "movups %%xmm0, %2\n\t" \ - "movups %%xmm0, %3" \ - : "=m"(m_v[0]),"=m"(m_v[4]),"=m"(m_v[8]),"=m"(m_v[12]) \ - ::"xmm0","memory"); \ -} \ -namespace simd { \ -SIMD_PASSIGN_SPEC(n,type) \ -{ \ - asm volatile ("movups %2, %%xmm0\n\t" \ - "movups %3, %%xmm1\n\t" \ - "movups %%xmm0, %0\n\t" \ - "movups %%xmm1, %1" \ - : "=m"(oout[0]),"=m"(oout[4]) \ - : "m"(oin[0]),"m"(oin[4]) \ - : "xmm0", "xmm1", "memory"); \ - asm volatile ("movups %2, %%xmm0\n\t" \ - "movups %3, %%xmm1\n\t" \ - "movups %%xmm0, %0\n\t" \ - "movups %%xmm1, %1" \ - : "=m"(oout[8]),"=m"(oout[12]) \ - : "m"(oin[8]),"m"(oin[12]) \ - : "xmm0", "xmm1", "memory"); \ -} \ -} -SSE_TUPLE_SPECS(16,float) -SSE_TUPLE_SPECS(16,int32_t) -SSE_TUPLE_SPECS(16,uint32_t) -#undef SSE_TUPLE_SPECS -#undef TOUCH_MATRIX_R -#undef TOUCH_MATRIX_W -#undef MATRIX_R -#undef MATRIX_W -#endif - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/umemory.h +++ /dev/null @@ -1,193 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UMEMORY_H_4AB5B0DB5BF09140541409CC47BCD17A -#define UMEMORY_H_4AB5B0DB5BF09140541409CC47BCD17A - -#include "unew.h" -#if HAVE_ALLOCA_H - #include <alloca.h> -#else - #include <stdlib.h> -#endif -#include "upair.h" -#include "uiterator.h" -#include "ulimits.h" - -namespace ustl { - -/// \class auto_ptr umemory.h ustl.h -/// \ingroup MemoryManagement -/// -/// \brief A smart pointer. -/// -/// Calls delete in the destructor; assignment transfers ownership. -/// This class does not work with void pointers due to the absence -/// of the required dereference operator. -/// -template <typename T> -class auto_ptr { -public: - typedef T value_type; - typedef T* pointer; - typedef T& reference; -public: - /// Takes ownership of \p p. - inline explicit auto_ptr (pointer p = NULL) : m_p (p) {} - /// Takes ownership of pointer in \p p. \p p relinquishes ownership. - inline auto_ptr (auto_ptr<T>& p) : m_p (p.release()) {} - /// Deletes the owned pointer. - inline ~auto_ptr (void) { delete m_p; } - /// Returns the pointer without relinquishing ownership. - inline pointer get (void) const { return (m_p); } - /// Returns the pointer and gives up ownership. - inline pointer release (void) { pointer rv (m_p); m_p = NULL; return (rv); } - /// Deletes the pointer and sets it equal to \p p. - inline void reset (pointer p) { if (p != m_p) { delete m_p; m_p = p; } } - /// Takes ownership of \p p. - inline auto_ptr<T>& operator= (pointer p) { reset (p); return (*this); } - /// Takes ownership of pointer in \p p. \p p relinquishes ownership. - inline auto_ptr<T>& operator= (auto_ptr<T>& p) { reset (p.release()); return (*this); } - inline reference operator* (void) const { return (*m_p); } - inline pointer operator-> (void) const { return (m_p); } - inline bool operator== (const pointer p) const { return (m_p == p); } - inline bool operator== (const auto_ptr<T>& p) const { return (m_p == p.m_p); } - inline bool operator< (const auto_ptr<T>& p) const { return (p.m_p < m_p); } -private: - pointer m_p; -}; - -/// Calls the placement new on \p p. -/// \ingroup RawStorageAlgorithms -/// -template <typename T> -inline void construct (T* p) -{ - new (p) T; -} - -/// Calls the placement new on \p p. -/// \ingroup RawStorageAlgorithms -/// -template <typename ForwardIterator> -inline void construct (ForwardIterator first, ForwardIterator last) -{ - typedef typename iterator_traits<ForwardIterator>::value_type value_type; - if (!numeric_limits<value_type>::is_integral && first) - for (--last; first <= last; ++first) - construct (&*first); -} - -/// Calls the placement new on \p p. -/// \ingroup RawStorageAlgorithms -/// -template <typename T> -inline void construct (T* p, const T& value) -{ - new (p) T (value); -} - -/// Calls the destructor of \p p without calling delete. -/// \ingroup RawStorageAlgorithms -/// -template <typename T> -inline void destroy (T* p) throw() -{ - p->~T(); -} - -// Helper templates to not instantiate anything for integral types. -template <typename T> -void dtors (T first, T last) throw() - { for (--last; first <= last; ++first) destroy (&*first); } -template <typename T, bool bIntegral> -struct Sdtorsr { - inline void operator()(T first, T last) throw() { dtors (first, last); } -}; -template <typename T> -struct Sdtorsr<T,true> { - inline void operator()(T, T) throw() {} -}; - -/// Calls the destructor on elements in range [first, last) without calling delete. -/// \ingroup RawStorageAlgorithms -/// -template <typename ForwardIterator> -inline void destroy (ForwardIterator first, ForwardIterator last) throw() -{ - typedef typename iterator_traits<ForwardIterator>::value_type value_type; - Sdtorsr<ForwardIterator,numeric_limits<value_type>::is_integral>()(first, last); -} - -/// Casts \p p to the type of the second pointer argument. -template <typename T> inline T* cast_to_type (void* p, const T*) { return ((T*) p); } - -/// \brief Creates a temporary buffer pair from \p p and \p n -/// This is intended to be used with alloca to create temporary buffers. -/// The size in the returned pair is set to 0 if the allocation is unsuccessful. -/// \ingroup RawStorageAlgorithms -/// -template <typename T> -inline pair<T*, ptrdiff_t> make_temporary_buffer (void* p, size_t n, const T* ptype) -{ - return (make_pair (cast_to_type(p,ptype), ptrdiff_t(p ? n : 0))); -} - -#if HAVE_ALLOCA_H - /// \brief Allocates a temporary buffer, if possible. - /// \ingroup RawStorageAlgorithms - #define get_temporary_buffer(size, ptype) make_temporary_buffer (alloca(size_of_elements(size, ptype)), size, ptype) - #define return_temporary_buffer(p) -#else - #define get_temporary_buffer(size, ptype) make_temporary_buffer (malloc(size_of_elements(size, ptype)), size, ptype) - #define return_temporary_buffer(p) if (p) free (p), p = NULL -#endif - -/// Copies [first, last) into result by calling copy constructors in result. -/// \ingroup RawStorageAlgorithms -/// -template <typename InputIterator, typename ForwardIterator> -ForwardIterator uninitialized_copy (InputIterator first, InputIterator last, ForwardIterator result) -{ - for (; first < last; ++result, ++first) - construct (&*result, *first); - return (result); -} - -/// Copies [first, first + n) into result by calling copy constructors in result. -/// \ingroup RawStorageAlgorithms -/// -template <typename InputIterator, typename ForwardIterator> -ForwardIterator uninitialized_copy_n (InputIterator first, size_t n, ForwardIterator result) -{ - for (++n; --n; ++result, ++first) - construct (&*result, *first); - return (result); -} - -/// Calls construct on all elements in [first, last) with value \p v. -/// \ingroup RawStorageAlgorithms -/// -template <typename ForwardIterator, typename T> -void uninitialized_fill (ForwardIterator first, ForwardIterator last, const T& v) -{ - for (; first < last; ++first) - construct (&*first, v); -} - -/// Calls construct on all elements in [first, first + n) with value \p v. -/// \ingroup RawStorageAlgorithms -/// -template <typename ForwardIterator, typename T> -ForwardIterator uninitialized_fill_n (ForwardIterator first, size_t n, const T& v) -{ - for (++n; --n; ++first) - construct (&*first, v); - return (first); -} - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/umultimap.h +++ /dev/null @@ -1,116 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UMULTIMAP_H_45743F516E02A87A3FCEA5024052A6F5 -#define UMULTIMAP_H_45743F516E02A87A3FCEA5024052A6F5 - -#include "uvector.h" -#include "ufunction.h" - -namespace ustl { - -/// \class multimap umultimap.h ustl.h -/// \ingroup AssociativeContainers -/// -/// \brief A sorted associative container that may container multiple entries for each key. -/// -template <typename K, typename V> -class multimap : public vector<pair<K,V> > { -public: - typedef K key_type; - typedef V data_type; - typedef const K& const_key_ref; - typedef const V& const_data_ref; - typedef const multimap<K,V>& rcself_t; - typedef vector<pair<K,V> > base_class; - typedef typename base_class::value_type value_type; - typedef typename base_class::size_type size_type; - typedef typename base_class::pointer pointer; - typedef typename base_class::const_pointer const_pointer; - typedef typename base_class::reference reference; - typedef typename base_class::const_reference const_reference; - typedef typename base_class::const_iterator const_iterator; - typedef typename base_class::iterator iterator; - typedef typename base_class::reverse_iterator reverse_iterator; - typedef typename base_class::const_reverse_iterator const_reverse_iterator; - typedef pair<const_iterator,const_iterator> const_range_t; - typedef pair<iterator,iterator> range_t; -public: - inline multimap (void) : vector<pair<K,V> > () {} - explicit inline multimap (size_type n) : vector<pair<K,V> > (n) {} - inline multimap (rcself_t v) : vector<pair<K,V> > (v) {} - inline multimap (const_iterator i1, const_iterator i2) : vector<pair<K,V> > () { insert (i1, i2); } - inline rcself_t operator= (rcself_t v) { base_class::operator= (v); return (*this); } - inline size_type size (void) const { return (base_class::size()); } - inline iterator begin (void) { return (base_class::begin()); } - inline const_iterator begin (void) const { return (base_class::begin()); } - inline iterator end (void) { return (base_class::end()); } - inline const_iterator end (void) const { return (base_class::end()); } - inline void assign (const_iterator i1, const_iterator i2) { clear(); insert (i1, i2); } - inline size_type count (const_key_ref k) const { return (upper_bound(k) - lower_bound(k)); } - inline void push_back (const_reference v) { insert (v); } - inline const_range_t equal_range (const_key_ref k) const { return (make_pair (lower_bound(k), upper_bound(k))); } - inline range_t equal_range (const_key_ref k) { return (make_pair (const_cast<iterator>(lower_bound(k)), const_cast<iterator>(upper_bound(k)))); } - const_iterator lower_bound (const_key_ref k) const; - const_iterator upper_bound (const_key_ref k) const; - inline iterator insert (const_reference v); - void insert (const_iterator i1, const_iterator i2); - inline void erase (const_key_ref k) { erase (const_cast<iterator>(lower_bound(k)), const_cast<iterator>(upper_bound(k))); } - inline iterator erase (iterator ep) { return (base_class::erase (ep)); } - inline iterator erase (iterator ep1, iterator ep2) { return (base_class::erase (ep1, ep2)); } - inline void clear (void) { base_class::clear(); } -}; - -/// Returns an iterator to the first element with key value \p k. -template <typename K, typename V> -typename multimap<K,V>::const_iterator multimap<K,V>::lower_bound (const_key_ref k) const -{ - const_iterator first (begin()), last (end()); - while (first != last) { - const_iterator mid = advance (first, distance (first,last) / 2); - if (mid->first < k) - first = advance (mid, 1); - else - last = mid; - } - return (first); -} - -/// Returns an iterator to the first element with key value \p k. -template <typename K, typename V> -typename multimap<K,V>::const_iterator multimap<K,V>::upper_bound (const_key_ref k) const -{ - const_iterator first (begin()), last (end()); - while (first != last) { - const_iterator mid = advance (first, distance (first,last) / 2); - if (k < mid->first) - last = mid; - else - first = advance (mid, 1); - } - return (last); -} - -/// Inserts the pair into the container. -template <typename K, typename V> -inline typename multimap<K,V>::iterator multimap<K,V>::insert (const_reference v) -{ - iterator ip = const_cast<iterator> (upper_bound (v.first)); - return (base_class::insert (ip, v)); -} - -/// Inserts elements from range [i1,i2) into the container. -template <typename K, typename V> -void multimap<K,V>::insert (const_iterator i1, const_iterator i2) -{ - assert (i1 <= i2); - reserve (size() + distance (i1, i2)); - for (; i1 != i2; ++i1) - insert (*i1); -} - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/umultiset.h +++ /dev/null @@ -1,101 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UMULTISET_H_446AEDBB7F61C6994DC228C25D5FA3A1 -#define UMULTISET_H_446AEDBB7F61C6994DC228C25D5FA3A1 - -#include "uvector.h" -#include "ualgo.h" - -namespace ustl { - -/// \class multiset umultiset.h ustl.h -/// \ingroup AssociativeContainers -/// -/// \brief Multiple sorted container. -/// Unlike set, it may contain multiple copies of each element. -/// -template <typename T> -class multiset : public vector<T> { -public: - typedef const multiset<T>& rcself_t; - typedef vector<T> base_class; - typedef typename base_class::value_type value_type; - typedef typename base_class::size_type size_type; - typedef typename base_class::pointer pointer; - typedef typename base_class::const_pointer const_pointer; - typedef typename base_class::reference reference; - typedef typename base_class::const_reference const_reference; - typedef typename base_class::const_iterator const_iterator; - typedef typename base_class::iterator iterator; - typedef typename base_class::reverse_iterator reverse_iterator; - typedef typename base_class::const_reverse_iterator const_reverse_iterator; -public: - inline multiset (void) : vector<T> () {} - explicit inline multiset (size_type n) : vector<T> (n) {} - inline multiset (rcself_t v) : vector<T> (v) {} - inline multiset (const_iterator i1, const_iterator i2) : vector<T> () { insert (i1, i2); } - inline rcself_t operator= (rcself_t v) { base_class::operator= (v); return (*this); } - inline size_type size (void) const { return (base_class::size()); } - inline iterator begin (void) { return (base_class::begin()); } - inline const_iterator begin (void) const { return (base_class::begin()); } - inline iterator end (void) { return (base_class::end()); } - inline const_iterator end (void) const { return (base_class::end()); } - inline void assign (const_iterator i1, const_iterator i2); - size_type count (const_reference v) const; - inline void push_back (const_reference v) { insert (v); } - inline iterator insert (const_reference v); - void insert (const_iterator i1, const_iterator i2); - void erase (const_reference v); - inline iterator erase (iterator ep) { return (base_class::erase (ep)); } - inline iterator erase (iterator ep1, iterator ep2) { return (base_class::erase (ep1, ep2)); } - inline void clear (void) { base_class::clear(); } -}; - -/// Copies contents of range [i1,i2) -template <typename T> -inline void multiset<T>::assign (const_iterator i1, const_iterator i2) -{ - base_class::clear(); - insert (i1, i2); -} - -/// Returns the number of elements of value \p v. -template <typename T> -typename multiset<T>::size_type multiset<T>::count (const_reference v) const -{ - const pair<const_iterator,const_iterator> fr = equal_range (begin(), end(), v); - return (distance (fr.first, fr.second)); -} - -/// Inserts \p v. -template <typename T> -inline typename multiset<T>::iterator multiset<T>::insert (const_reference v) -{ - iterator ip = upper_bound (begin(), end(), v); - return (base_class::insert (ip, v)); -} - -/// Inserts all elements from range [i1,i2). -template <typename T> -void multiset<T>::insert (const_iterator i1, const_iterator i2) -{ - assert (i1 <= i2); - reserve (size() + distance (i1, i2)); - for (; i1 < i2; ++i1) - push_back (*i1); -} - -/// Erases all elements with value \p v. -template <typename T> -void multiset<T>::erase (const_reference v) -{ - pair<iterator,iterator> epr = equal_range (begin(), end(), v); - erase (epr.first, epr.second); -} - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/unew.h +++ /dev/null @@ -1,47 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UNEW_H_11D237512B324C9C05A55DAF1BF086F1 -#define UNEW_H_11D237512B324C9C05A55DAF1BF086F1 - -#include "uexception.h" -#include <stdlib.h> - -/// Just like malloc, but throws on failure. -void* tmalloc (size_t n) throw (ustl::bad_alloc) __attribute__((malloc)); -/// Just like free, but doesn't crash when given a NULL. -inline void nfree (void* p) throw() { if (p) free (p); } - -#if WITHOUT_LIBSTDCPP - -// -// These are replaceable signatures: -// - normal single new and delete (no arguments, throw @c bad_alloc on error) -// - normal array new and delete (same) -// - @c nothrow single new and delete (take a @c nothrow argument, return -// @c NULL on error) -// - @c nothrow array new and delete (same) -// -// Placement new and delete signatures (take a memory address argument, -// does nothing) may not be replaced by a user's program. -// -inline void* operator new (size_t n) throw (ustl::bad_alloc) { return (tmalloc (n)); } -inline void* operator new[] (size_t n) throw (ustl::bad_alloc) { return (tmalloc (n)); } -inline void operator delete (void* p) throw() { nfree (p); } -inline void operator delete[] (void* p) throw() { nfree (p); } - -// Default placement versions of operator new. -inline void* operator new (size_t, void* p) throw() { return (p); } -inline void* operator new[] (size_t, void* p) throw() { return (p); } - -// Default placement versions of operator delete. -inline void operator delete (void*, void*) throw() { } -inline void operator delete[](void*, void*) throw() { } - -#else -#include <new> -#endif // WITHOUT_LIBSTDCPP - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/unumeric.h +++ /dev/null @@ -1,154 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UNUMERIC_H_6C99D6F6363832C644A6FFF336E84E18 -#define UNUMERIC_H_6C99D6F6363832C644A6FFF336E84E18 - -namespace ustl { - -/// Returns the sum of all elements in [first, last) added to \p init. -/// \ingroup NumericAlgorithms -/// -template <typename InputIterator, typename T> -inline T accumulate (InputIterator first, InputIterator last, T init) -{ - while (first < last) - init += *first++; - return (init); -} - -/// Returns the sum of all elements in [first, last) via \p op, added to \p init. -/// \ingroup NumericAlgorithms -/// -template <typename InputIterator, typename T, typename BinaryFunction> -inline T accumulate (InputIterator first, InputIterator last, T init, BinaryFunction binary_op) -{ - while (first < last) - init = binary_op (init, *first++); - return (init); -} - -/// Assigns range [value, value + (last - first)) to [first, last) -/// \ingroup NumericAlgorithms -/// -template <typename ForwardIterator, typename T> -inline void iota (ForwardIterator first, ForwardIterator last, T value) -{ - while (first < last) - *first++ = value++; -} - -/// Returns the sum of products of respective elements in the given ranges. -/// \ingroup NumericAlgorithms -/// -template <typename InputIterator1, typename InputIterator2, typename T> -inline T inner_product (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init) -{ - while (first1 < last1) - init += *first1++ * *first2++; - return (init); -} - -/// Returns the sum of products of respective elements in the given ranges. -/// \ingroup NumericAlgorithms -/// -template <typename InputIterator1, typename InputIterator2, typename T, - typename BinaryOperation1, typename BinaryOperation2> -inline T inner_product -(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init, - BinaryOperation1 sumOp, BinaryOperation2 productOp) -{ - while (first1 < last1) - init = sumOp (init, productOp (*first1++, *first2++)); - return (init); -} - -/// Writes result such that result[i] = sum (first...first+i) -/// \ingroup NumericAlgorithms -/// -template <typename InputIterator, typename OutputIterator> -inline OutputIterator partial_sum (InputIterator first, InputIterator last, OutputIterator result) -{ - if (first < last) - *result = *first++; - while (first < last) - *++result = *first++ + *result; - return (result); -} - -/// Writes result such that result[i] = sumOp (first...first+i) -/// \ingroup NumericAlgorithms -/// -template <typename InputIterator, typename OutputIterator, typename BinaryOperation> -inline OutputIterator partial_sum (InputIterator first, InputIterator last, OutputIterator result, BinaryOperation sumOp) -{ - if (first < last) - *result = *first++; - while (first < last) - *++result = sumOp (*first++, *result); - return (result); -} - -/// Writes result such that result[i] = first[i] - first[i - 1] -/// \ingroup NumericAlgorithms -/// -template <typename InputIterator, typename OutputIterator> -inline OutputIterator adjacent_difference (InputIterator first, InputIterator last, OutputIterator result) -{ - if (first < last) - *result++ = *first++; - while (first < last) - *result++ = *first - *(first - 1); - return (result); -} - -/// Writes result such that result[i] = differenceOp (first[i], first[i - 1]) -/// \ingroup NumericAlgorithms -/// -template <typename InputIterator, typename OutputIterator, typename BinaryOperation> -inline OutputIterator adjacent_difference (InputIterator first, InputIterator last, OutputIterator result, BinaryOperation differenceOp) -{ - if (first < last) - *result++ = *first++; - while (first < last) - *result++ = differenceOp (*first, *(first - 1)); - return (result); -} - -/// \brief Returns x^n. -/// Donald Knuth's Russian Peasant algorithm. -/// \ingroup NumericAlgorithms -/// -template <typename T> -inline T power (T x, unsigned n) -{ - T result (n % 2 ? x : 1); - while (n /= 2) { - x *= x; - if (n % 2) - result *= x; - } - return (result); -} - -/// \brief Returns x^n, using \p op instead of multiplication. -/// Donald Knuth's Russian Peasant algorithm. -/// \ingroup NumericAlgorithms -/// -template <typename T, typename BinaryOperation> -inline T power (T x, unsigned n, BinaryOperation op) -{ - T result (n % 2 ? x : 1); - while (n /= 2) { - x = op (x, x); - if (n % 2) - result = op (result, x); - } - return (result); -} - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/upair.h +++ /dev/null @@ -1,59 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UPAIR_H_7DC08F1B7FECF8AE6856D84C3B617A75 -#define UPAIR_H_7DC08F1B7FECF8AE6856D84C3B617A75 - -#include "utypes.h" - -namespace ustl { - -/// \class pair upair.h ustl.h -/// \ingroup AssociativeContainers -/// -/// \brief Container for two values. -/// -template <typename T1, typename T2> -class pair { -public: - typedef T1 first_type; - typedef T2 second_type; -public: - /// Default constructor. - inline pair (void) : first (T1()), second (T2()) {} - /// Initializes members with \p a, and \p b. - inline pair (const T1& a, const T2& b) : first (a), second (b) {} - inline pair& operator= (const pair<T1, T2>& p2) { first = p2.first; second = p2.second; return (*this); } - template <typename T3, typename T4> - inline pair& operator= (const pair<T3, T4>& p2) { first = p2.first; second = p2.second; return (*this); } -public: - first_type first; - second_type second; -}; - -/// Compares both values of \p p1 to those of \p p2. -template <typename T1, typename T2> -inline bool operator== (const pair<T1,T2>& p1, const pair<T1,T2>& p2) -{ - return (p1.first == p2.first && p1.second == p2.second); -} - -/// Compares both values of \p p1 to those of \p p2. -template <typename T1, typename T2> -bool operator< (const pair<T1,T2>& p1, const pair<T1,T2>& p2) -{ - return (p1.first < p2.first || (p1.first == p2.first && p1.second < p2.second)); -} - -/// Returns a pair object with (a,b) -template <typename T1, typename T2> -inline pair<T1,T2> make_pair (const T1& a, const T2& b) -{ - return (pair<T1,T2> (a, b)); -} - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/upredalgo.h +++ /dev/null @@ -1,587 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UPREDALGO_H_2CB058AE0807A01A2F6A51BA5D5820A5 -#define UPREDALGO_H_2CB058AE0807A01A2F6A51BA5D5820A5 - -namespace ustl { - -/// Copy_if copies elements from the range [first, last) to the range -/// [result, result + (last - first)) if pred(*i) returns true. -/// \ingroup MutatingAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename InputIterator, typename OutputIterator, typename Predicate> -inline OutputIterator copy_if (InputIterator first, InputIterator last, OutputIterator result, Predicate pred) -{ - for (; first != last; ++first) { - if (pred(*first)) { - *result = *first; - ++ result; - } - } - return (result); -} - -/// Returns the first iterator i in the range [first, last) such that -/// pred(*i) is true. Returns last if no such iterator exists. -/// \ingroup SearchingAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename InputIterator, typename Predicate> -inline InputIterator find_if (InputIterator first, InputIterator last, Predicate pred) -{ - while (first != last && !pred (*first)) - ++ first; - return (first); -} - -/// Returns the first iterator such that p(*i, *(i + 1)) == true. -/// \ingroup SearchingAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename ForwardIterator, typename BinaryPredicate> -inline ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last, BinaryPredicate p) -{ - if (first != last) - for (ForwardIterator prev = first; ++first != last; ++ prev) - if (p (*prev, *first)) - return (prev); - return (last); -} - -/// Returns the pointer to the first pair of unequal elements. -/// \ingroup SearchingAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename InputIterator, typename BinaryPredicate> -inline pair<InputIterator,InputIterator> -mismatch (InputIterator first1, InputIterator last1, InputIterator first2, BinaryPredicate comp) -{ - while (first1 != last1 && comp(*first1, *first2)) - ++ first1, ++ first2; - return (make_pair (first1, first2)); -} - -/// Returns true if two ranges are equal. -/// This is an extension, present in uSTL and SGI STL. -/// \ingroup ConditionAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename InputIterator, typename BinaryPredicate> -inline bool equal (InputIterator first1, InputIterator last1, InputIterator first2, BinaryPredicate comp) -{ - return (mismatch (first1, last1, first2, comp).first == last1); -} - -/// Count_if finds the number of elements in [first, last) that satisfy the -/// predicate pred. More precisely, the first version of count_if returns the -/// number of iterators i in [first, last) such that pred(*i) is true. -/// \ingroup ConditionAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename InputIterator, typename Predicate> -inline size_t count_if (InputIterator first, InputIterator last, Predicate pred) -{ - size_t total = 0; - for (; first != last; ++first) - if (pred (*first)) - ++ total; - return (total); -} - -/// Replace_if replaces every element in the range [first, last) for which -/// pred returns true with new_value. That is: for every iterator i, if -/// pred(*i) is true then it performs the assignment *i = new_value. -/// \ingroup MutatingAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename ForwardIterator, typename Predicate, typename T> -inline void replace_if (ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value) -{ - for (; first != last; ++first) - if (pred (*first)) - *first = new_value; -} - -/// Replace_copy_if copies elements from the range [first, last) to the range -/// [result, result + (last-first)), except that any element for which pred is -/// true is not copied; new_value is copied instead. More precisely, for every -/// integer n such that 0 <= n < last-first, replace_copy_if performs the -/// assignment *(result+n) = new_value if pred(*(first+n)), -/// and *(result+n) = *(first+n) otherwise. -/// \ingroup MutatingAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename InputIterator, typename OutputIterator, typename Predicate, typename T> -inline OutputIterator replace_copy_if (InputIterator first, InputIterator last, OutputIterator result, Predicate pred, const T& new_value) -{ - for (; first != last; ++result, ++first) - *result = pred(*first) ? new_value : *first; -} - -/// Remove_copy_if copies elements from the range [first, last) to a range -/// beginning at result, except that elements for which pred is true are not -/// copied. The return value is the end of the resulting range. This operation -/// is stable, meaning that the relative order of the elements that are copied -/// is the same as in the range [first, last). -/// \ingroup MutatingAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename InputIterator, typename OutputIterator, typename Predicate> -inline OutputIterator remove_copy_if (InputIterator first, InputIterator last, OutputIterator result, Predicate pred) -{ - for (; first != last; ++first) - if (pred (*first)) - *result++ = *first; - return (result); -} - -/// Remove_if removes from the range [first, last) every element x such that -/// pred(x) is true. That is, remove_if returns an iterator new_last such that -/// the range [first, new_last) contains no elements for which pred is true. -/// The iterators in the range [new_last, last) are all still dereferenceable, -/// but the elements that they point to are unspecified. Remove_if is stable, -/// meaning that the relative order of elements that are not removed is -/// unchanged. -/// \ingroup MutatingAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename ForwardIterator, typename Predicate> -inline ForwardIterator remove_if (ForwardIterator first, ForwardIterator last, Predicate pred) -{ - return (remove_copy_if (first, last, first, pred)); -} - -/// The reason there are two different versions of unique_copy is that there -/// are two different definitions of what it means for a consecutive group of -/// elements to be duplicates. In the first version, the test is simple -/// equality: the elements in a range [f, l) are duplicates if, for every -/// iterator i in the range, either i == f or else *i == *(i-1). In the second, -/// the test is an arbitrary Binary Predicate binary_pred: the elements in -/// [f, l) are duplicates if, for every iterator i in the range, either -/// i == f or else binary_pred(*i, *(i-1)) is true. -/// \ingroup MutatingAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename InputIterator, typename OutputIterator, typename BinaryPredicate> -OutputIterator unique_copy (InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate binary_pred) -{ - if (first != last) { - *result = *first; - while (++first != last) - if (!binary_pred (*first, *result)) - *++result = *first; - ++ result; - } - return (result); -} - -/// Every time a consecutive group of duplicate elements appears in the range -/// [first, last), the algorithm unique removes all but the first element. -/// That is, unique returns an iterator new_last such that the range [first, -/// new_last) contains no two consecutive elements that are duplicates. -/// The iterators in the range [new_last, last) are all still dereferenceable, -/// but the elements that they point to are unspecified. Unique is stable, -/// meaning that the relative order of elements that are not removed is -/// unchanged. -/// \ingroup MutatingAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename ForwardIterator, typename BinaryPredicate> -inline ForwardIterator unique (ForwardIterator first, ForwardIterator last, BinaryPredicate binary_pred) -{ - return (unique_copy (first, last, first, binary_pred)); -} - -/// Returns the furthermost iterator i in [first, last) such that, -/// for every iterator j in [first, i), comp(*j, value) is true. -/// Assumes the range is sorted. -/// \ingroup SearchingAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename ForwardIterator, typename T, typename StrictWeakOrdering> -ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& value, StrictWeakOrdering comp) -{ - ForwardIterator mid; - while (first != last) { - mid = advance (first, distance (first,last) / 2); - if (comp (*mid, value)) - first = mid + 1; - else - last = mid; - } - return (first); -} - -/// Performs a binary search inside the sorted range. -/// \ingroup SearchingAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename ForwardIterator, typename T, typename StrictWeakOrdering> -inline bool binary_search (ForwardIterator first, ForwardIterator last, const T& value, StrictWeakOrdering comp) -{ - ForwardIterator found = lower_bound (first, last, value, comp); - return (found != last && !comp(*found, value)); -} - -/// Returns the furthermost iterator i in [first,last) such that for -/// every iterator j in [first,i), comp(value,*j) is false. -/// \ingroup SearchingAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename ForwardIterator, typename T, typename StrictWeakOrdering> -ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& value, StrictWeakOrdering comp) -{ - ForwardIterator mid; - while (first != last) { - mid = advance (first, distance (first,last) / 2); - if (comp (value, *mid)) - last = mid; - else - first = mid + 1; - } - return (last); -} - -/// Returns pair<lower_bound,upper_bound> -/// \ingroup SearchingAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename ForwardIterator, typename T, typename StrictWeakOrdering> -inline pair<ForwardIterator,ForwardIterator> equal_range (ForwardIterator first, ForwardIterator last, const T& value, StrictWeakOrdering comp) -{ - pair<ForwardIterator,ForwardIterator> rv; - rv.second = rv.first = lower_bound (first, last, value, comp); - while (rv.second != last && !comp(value, *(rv.second))) - ++ rv.second; - return (rv); -} - -/// \brief Puts \p nth element into its sorted position. -/// In this implementation, the entire array is sorted. The performance difference is -/// so small and the function use is so rare, there is no need to have code for it. -/// \ingroup SortingAlgorithms -/// \ingroup SearchingAlgorithms -/// \ingroup PredicateAlgorithms -/// -template <typename RandomAccessIterator, typename Compare> -inline void nth_element (RandomAccessIterator first, RandomAccessIterator, RandomAccessIterator last, Compare comp) -{ - sort (first, last, comp); -} - -/// \brief Searches for the first subsequence [first2,last2) in [first1,last1) -/// \ingroup SearchingAlgorithms -/// \ingroup PredicateAlgorithms -template <typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate> -ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate comp) -{ - const ForwardIterator1 slast = last1 - distance(first2, last2) + 1; - for (; first1 < slast; ++first1) { - ForwardIterator2 i = first2; - ForwardIterator1 j = first1; - for (; i != last2 && comp(*j, *i); ++i, ++j) ; - if (i == last2) - return (first1); - } - return (last1); -} - -/// \brief Searches for the last subsequence [first2,last2) in [first1,last1) -/// \ingroup SearchingAlgorithms -/// \ingroup PredicateAlgorithms -template <typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate> -ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate comp) -{ - ForwardIterator1 s = last1 - distance(first2, last2); - for (; first1 < s; --s) { - ForwardIterator2 i = first2, j = s; - for (; i != last2 && comp(*j, *i); ++i, ++j) ; - if (i == last2) - return (s); - } - return (last1); -} - -/// \brief Searches for the first occurence of \p count \p values in [first, last) -/// \ingroup SearchingAlgorithms -/// \ingroup PredicateAlgorithms -template <typename Iterator, typename T, typename BinaryPredicate> -Iterator search_n (Iterator first, Iterator last, size_t count, const T& value, BinaryPredicate comp) -{ - size_t n = 0; - for (; first != last; ++first) { - if (!comp (*first, value)) - n = 0; - else if (++n == count) - return (first - --n); - } - return (last); -} - -/// \brief Searches [first1,last1) for the first occurrence of an element from [first2,last2) -/// \ingroup SearchingAlgorithms -/// \ingroup PredicateAlgorithms -template <typename InputIterator, typename ForwardIterator, typename BinaryPredicate> -InputIterator find_first_of (InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2, BinaryPredicate comp) -{ - for (; first1 != last1; ++first1) - for (ForwardIterator i = first2; i != last2; ++i) - if (comp (*first1, *i)) - return (first1); - return (first1); -} - -/// \brief Returns true if [first2,last2) is a subset of [first1,last1) -/// \ingroup ConditionAlgorithms -/// \ingroup SetAlgorithms -/// \ingroup PredicateAlgorithms -template <typename InputIterator1, typename InputIterator2, typename StrictWeakOrdering> -bool includes (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, StrictWeakOrdering comp) -{ - for (; (first1 != last1) & (first2 != last2); ++first1) { - if (comp (*first2, *first1)) - return (false); - first2 += !comp (*first1, *first2); - } - return (first2 == last2); -} - -/// \brief Merges [first1,last1) with [first2,last2) -/// -/// Result will contain every element that is in either set. If duplicate -/// elements are present, max(n,m) is placed in the result. -/// -/// \ingroup SetAlgorithms -/// \ingroup PredicateAlgorithms -template <typename InputIterator1, typename InputIterator2, typename OutputIterator, typename StrictWeakOrdering> -OutputIterator set_union (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, StrictWeakOrdering comp) -{ - for (; (first1 != last1) & (first2 != last2); ++result) { - if (comp (*first2, *first1)) - *result = *first2++; - else { - first2 += !comp (*first1, *first2); - *result = *first1++; - } - } - return (copy (first2, last2, copy (first1, last1, result))); -} - -/// \brief Creates a set containing elements shared by the given ranges. -/// \ingroup SetAlgorithms -/// \ingroup PredicateAlgorithms -template <typename InputIterator1, typename InputIterator2, typename OutputIterator, typename StrictWeakOrdering> -OutputIterator set_intersection (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, StrictWeakOrdering comp) -{ - while ((first1 != last1) & (first2 != last2)) { - bool b1ge2 = !comp (*first1, *first2), b2ge1 = !comp (*first2, *first1); - if (b1ge2 & b2ge1) - *result++ = *first1; - first1 += b2ge1; - first2 += b1ge2; - } - return (result); -} - -/// \brief Removes from [first1,last1) elements present in [first2,last2) -/// \ingroup SetAlgorithms -/// \ingroup PredicateAlgorithms -template <typename InputIterator1, typename InputIterator2, typename OutputIterator, typename StrictWeakOrdering> -OutputIterator set_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, StrictWeakOrdering comp) -{ - while ((first1 != last1) & (first2 != last2)) { - bool b1ge2 = !comp (*first1, *first2), b2ge1 = !comp (*first2, *first1); - if (!b1ge2) - *result++ = *first1; - first1 += b2ge1; - first2 += b1ge2; - } - return (copy (first1, last1, result)); -} - -/// \brief Performs union of sets A-B and B-A. -/// \ingroup SetAlgorithms -/// \ingroup PredicateAlgorithms -template <typename InputIterator1, typename InputIterator2, typename OutputIterator, typename StrictWeakOrdering> -OutputIterator set_symmetric_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, StrictWeakOrdering comp) -{ - while ((first1 != last1) & (first2 != last2)) { - bool b1l2 = comp (*first1, *first2), b2l1 = comp (*first2, *first1); - if (b1l2) - *result++ = *first1; - else if (b2l1) - *result++ = *first2; - first1 += !b2l1; - first2 += !b1l2; - } - return (copy (first2, last2, copy (first1, last1, result))); -} - -/// \brief Returns true if the given range is sorted. -/// \ingroup ConditionAlgorithms -/// \ingroup PredicateAlgorithms -template <typename ForwardIterator, typename StrictWeakOrdering> -bool is_sorted (ForwardIterator first, ForwardIterator last, StrictWeakOrdering comp) -{ - for (ForwardIterator i = first; ++i < last; ++first) - if (comp (*i, *first)) - return (false); - return (true); -} - -/// \brief Compares two given containers like strcmp compares strings. -/// \ingroup ConditionAlgorithms -/// \ingroup PredicateAlgorithms -template <typename InputIterator1, typename InputIterator2, typename BinaryPredicate> -bool lexicographical_compare (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate comp) -{ - for (; (first1 != last1) & (first2 != last2); ++first1, ++first2) { - if (comp (*first1, *first2)) - return (true); - if (comp (*first2, *first1)) - return (false); - } - return ((first1 == last1) & (first2 != last2)); -} - -/// \brief Creates the next lexicographical permutation of [first,last). -/// Returns false if no further permutations can be created. -/// \ingroup GeneratorAlgorithms -/// \ingroup PredicateAlgorithms -template <typename BidirectionalIterator, typename StrictWeakOrdering> -bool next_permutation (BidirectionalIterator first, BidirectionalIterator last, StrictWeakOrdering comp) -{ - if (distance (first, last) < 2) - return (false); - BidirectionalIterator i = last; - for (--i; i != first; ) { - --i; - if (comp (i[0], i[1])) { - BidirectionalIterator j = last; - while (!comp (*i, *--j)) ; - iter_swap (i, j); - reverse (i + 1, last); - return (true); - } - } - reverse (first, last); - return (false); -} - -/// \brief Creates the previous lexicographical permutation of [first,last). -/// Returns false if no further permutations can be created. -/// \ingroup GeneratorAlgorithms -/// \ingroup PredicateAlgorithms -template <typename BidirectionalIterator, typename StrictWeakOrdering> -bool prev_permutation (BidirectionalIterator first, BidirectionalIterator last, StrictWeakOrdering comp) -{ - if (distance (first, last) < 2) - return (false); - BidirectionalIterator i = last; - for (--i; i != first; ) { - --i; - if (comp(i[1], i[0])) { - BidirectionalIterator j = last; - while (!comp (*--j, *i)) ; - iter_swap (i, j); - reverse (i + 1, last); - return (true); - } - } - reverse (first, last); - return (false); -} - -/// \brief Returns iterator to the max element in [first,last) -/// \ingroup SearchingAlgorithms -/// \ingroup PredicateAlgorithms -template <typename ForwardIterator, typename BinaryPredicate> -inline ForwardIterator max_element (ForwardIterator first, ForwardIterator last, BinaryPredicate comp) -{ - ForwardIterator result = first; - for (; first != last; ++first) - if (comp (*result, *first)) - result = first; - return (result); -} - -/// \brief Returns iterator to the min element in [first,last) -/// \ingroup SearchingAlgorithms -/// \ingroup PredicateAlgorithms -template <typename ForwardIterator, typename BinaryPredicate> -inline ForwardIterator min_element (ForwardIterator first, ForwardIterator last, BinaryPredicate comp) -{ - ForwardIterator result = first; - for (; first != last; ++first) - if (comp (*first, *result)) - result = first; - return (result); -} - -/// \brief Makes [first,middle) a part of the sorted array. -/// Contents of [middle,last) is undefined. This implementation just calls stable_sort. -/// \ingroup SortingAlgorithms -/// \ingroup PredicateAlgorithms -template <typename RandomAccessIterator, typename StrictWeakOrdering> -inline void partial_sort (RandomAccessIterator first, RandomAccessIterator, RandomAccessIterator last, StrictWeakOrdering comp) -{ - stable_sort (first, last, comp); -} - -/// \brief Like partial_sort, but outputs to [result_first,result_last) -/// \ingroup SortingAlgorithms -/// \ingroup PredicateAlgorithms -template <typename InputIterator, typename RandomAccessIterator, typename StrictWeakOrdering> -RandomAccessIterator partial_sort_copy (InputIterator first, InputIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last, StrictWeakOrdering comp) -{ - RandomAccessIterator rend = result_first; - for (; first != last; ++first) { - RandomAccessIterator i = result_first; - for (; i != rend && comp (*i, *first); ++i) ; - if (i == result_last) - continue; - rend += (rend < result_last); - copy_backward (i, rend - 1, rend); - *i = *first; - } - return (rend); -} - -/// \brief Like partition, but preserves equal element order. -/// \ingroup SortingAlgorithms -/// \ingroup PredicateAlgorithms -template <typename ForwardIterator, typename Predicate> -ForwardIterator stable_partition (ForwardIterator first, ForwardIterator last, Predicate pred) -{ - if (first == last) - return (first); - ForwardIterator l, r, m = advance (first, distance (first, last) / 2); - if (first == m) - return (pred(*first) ? last : first); - l = stable_partition (first, m, pred); - r = stable_partition (m, last, pred); - rotate (l, m, r); - return (advance (l, distance (m, r))); -} - -/// \brief Splits [first,last) in two by \p pred. -/// -/// Creates two ranges [first,middle) and [middle,last), where every element -/// in the former is less than every element in the latter. -/// The return value is middle. -/// -/// \ingroup SortingAlgorithms -/// \ingroup PredicateAlgorithms -template <typename ForwardIterator, typename Predicate> -inline ForwardIterator partition (ForwardIterator first, ForwardIterator last, Predicate pred) -{ - return (stable_partition (first, last, pred)); -} - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/uqueue.h +++ /dev/null @@ -1,69 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UQUEUE_H_27F01FDB0D59B75277E0E5C41ABC6B5B -#define UQUEUE_H_27F01FDB0D59B75277E0E5C41ABC6B5B - -namespace ustl { - -/// \class queue uqueue.h ustl.h -/// \ingroup Sequences -/// -/// \brief Queue adapter to uSTL containers. -/// -/// The most efficient way to use this implementation is to fill the queue -/// and the completely empty it before filling again. -/// -template <typename T> -class queue { -public: - typedef T value_type; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T& reference; - typedef const T& const_reference; - typedef T* pointer; - typedef const T* const_pointer; -public: - inline queue (void) : m_Storage (), m_Front (0) { } - explicit inline queue (const vector<T>& s) : m_Storage (s), m_Front (0) { } - explicit inline queue (const queue& s) : m_Storage (s.m_Storage), m_Front (0) { } - inline size_type size (void) const { return (m_Storage.size() - m_Front); } - inline bool empty (void) const { return (!size()); } - inline reference front (void) { return (m_Storage [m_Front]); } - inline const_reference front (void) const { return (m_Storage [m_Front]); } - inline reference back (void) { return (m_Storage.back()); } - inline const_reference back (void) const { return (m_Storage.back()); } - inline void push (const value_type& v); - inline void pop (void); - inline bool operator== (const queue& s) const { return (m_Storage == s.m_Storage && m_Front == s.m_Front); } - inline bool operator< (const queue& s) const { return (size() < s.size()); } -private: - vector<T> m_Storage; ///< Where the data actually is. - size_type m_Front; ///< Index of the element returned by next pop. -}; - -/// Pushes \p v on the queue. -template <typename T> -inline void queue<T>::push (const value_type& v) -{ - if (m_Front) { - m_Storage.erase (m_Storage.begin(), m_Front); - m_Front = 0; - } - m_Storage.push_back (v); -} - -/// Pops the topmost element from the queue. -template <typename T> -inline void queue<T>::pop (void) -{ - if (++m_Front >= m_Storage.size()) - m_Storage.resize (m_Front = 0); -} - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/uset.h +++ /dev/null @@ -1,91 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef USET_H_45543F516E02A87A3FCEA5024052A6F5 -#define USET_H_45543F516E02A87A3FCEA5024052A6F5 - -#include "uvector.h" - -namespace ustl { - -/// \class set uset.h ustl.h -/// \ingroup Sequences -/// -/// \brief Unique sorted container. Sorted vector with all values unique. -/// -template <typename T> -class set : public vector<T> { -public: - typedef const set<T>& rcself_t; - typedef vector<T> base_class; - typedef typename base_class::value_type key_type; - typedef typename base_class::value_type data_type; - typedef typename base_class::value_type value_type; - typedef typename base_class::size_type size_type; - typedef typename base_class::pointer pointer; - typedef typename base_class::const_pointer const_pointer; - typedef typename base_class::reference reference; - typedef typename base_class::const_reference const_reference; - typedef typename base_class::const_iterator const_iterator; - typedef typename base_class::iterator iterator; - typedef typename base_class::reverse_iterator reverse_iterator; - typedef typename base_class::const_reverse_iterator const_reverse_iterator; - typedef pair<iterator,bool> insertrv_t; -public: - inline set (void) : vector<T> () { } - explicit inline set (size_type n) : vector<T> (n) { } - inline set (rcself_t v) : vector<T> (v) { } - inline set (const_iterator i1, const_iterator i2) : vector<T> () { insert (i1, i2); } - inline rcself_t operator= (rcself_t v) { base_class::operator= (v); return (*this); } - inline size_type size (void) const { return (base_class::size()); } - inline iterator begin (void) { return (base_class::begin()); } - inline const_iterator begin (void) const { return (base_class::begin()); } - inline iterator end (void) { return (base_class::end()); } - inline const_iterator end (void) const { return (base_class::end()); } - inline void assign (const_iterator i1, const_iterator i2) { clear(); insert (i1, i2); } - inline void push_back (const_reference v) { insert (v); } - inline const_iterator find (const_reference v) const { const_iterator i = lower_bound (begin(), end(), v); return ((i != end() && *i == v) ? i : end()); } - inline iterator find (const_reference v) { return (const_cast<iterator>(const_cast<rcself_t>(*this).find (v))); } - insertrv_t insert (const_reference v); - inline void insert (const_iterator i1, const_iterator i2); - inline void erase (const_reference v); - inline iterator erase (iterator ep) { return (base_class::erase (ep)); } - inline iterator erase (iterator ep1, iterator ep2) { return (base_class::erase (ep1, ep2)); } - inline void clear (void) { base_class::clear(); } -}; - -/// Inserts \p v into the container, maintaining the sort order. -template <typename T> -typename set<T>::insertrv_t set<T>::insert (const_reference v) -{ - iterator ip = lower_bound (begin(), end(), v); - bool bInserted = (ip == end() || v < *ip); - if (bInserted) - ip = base_class::insert (ip, v); - return (make_pair (ip, bInserted)); -} - -/// Inserts the contents of range [i1,i2) -template <typename T> -void set<T>::insert (const_iterator i1, const_iterator i2) -{ - assert (i1 <= i2); - reserve (size() + distance (i1, i2)); - for (; i1 < i2; ++i1) - push_back (*i1); -} - -/// Erases the element with value \p v. -template <typename T> -inline void set<T>::erase (const_reference v) -{ - iterator ip = find (v); - if (ip != end()) - erase (ip); -} - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/uspecial.h +++ /dev/null @@ -1,260 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef USPECIAL_H_947ADYOU0ARE3YOU2REALLY8ARE44CE0 -#define USPECIAL_H_947ADYOU0ARE3YOU2REALLY8ARE44CE0 - -#include "uvector.h" -#include "ustring.h" -#include "uset.h" -#include "umultiset.h" -#include "ubitset.h" -#include "ulaalgo.h" -#include "uctralgo.h" -#include "ufunction.h" -#include "uctrstrm.h" -#include "sistream.h" -#include <ctype.h> - -namespace ustl { - -//---------------------------------------------------------------------- -// Alogrithm specializations not in use by the library code. -//---------------------------------------------------------------------- - -template <> inline void swap (cmemlink& a, cmemlink& b) { a.swap (b); } -template <> inline void swap (memlink& a, memlink& b) { a.swap (b); } -template <> inline void swap (memblock& a, memblock& b) { a.swap (b); } -template <> inline void swap (string& a, string& b) { a.swap (b); } -#define TEMPLATE_SWAP_PSPEC(type, template_decl) \ -template_decl inline void swap (type& a, type& b) { a.swap (b); } -TEMPLATE_SWAP_PSPEC (TEMPLATE_TYPE1 (vector,T), TEMPLATE_DECL1 (T)) -TEMPLATE_SWAP_PSPEC (TEMPLATE_TYPE1 (set,T), TEMPLATE_DECL1 (T)) -TEMPLATE_SWAP_PSPEC (TEMPLATE_TYPE1 (multiset,T), TEMPLATE_DECL1 (T)) -TEMPLATE_SWAP_PSPEC (TEMPLATE_TYPE2 (tuple,N,T), TEMPLATE_FULL_DECL2 (size_t,N,typename,T)) - -//---------------------------------------------------------------------- -// Streamable definitions. Not used in the library and require streams. -//---------------------------------------------------------------------- - -//----{ pair }---------------------------------------------------------- - -/// \brief Reads pair \p p from stream \p is. -template <typename T1, typename T2> -istream& operator>> (istream& is, pair<T1,T2>& p) -{ - is >> p.first; - is.align (alignof(p.second)); - is >> p.second; - is.align (alignof(p.first)); - return (is); -} - -/// Writes pair \p p to stream \p os. -template <typename T1, typename T2> -ostream& operator<< (ostream& os, const pair<T1,T2>& p) -{ - os << p.first; - os.align (alignof(p.second)); - os << p.second; - os.align (alignof(p.first)); - return (os); -} - -/// Writes pair \p p to stream \p os. -template <typename T1, typename T2> -ostringstream& operator<< (ostringstream& os, const pair<T1,T2>& p) -{ - os << '(' << p.first << ',' << p.second << ')'; - return (os); -} - -/// Returns the written size of the object. -template <typename T1, typename T2> -struct object_stream_size<pair<T1,T2> > { - inline size_t operator()(const pair<T1,T2>& v) const - { - return (Align (stream_size_of(v.first), alignof(v.second)) + - Align (stream_size_of(v.second), alignof(v.first))); - } -}; - -/// \brief Takes a pair and returns pair.first -/// This is an extension, available in uSTL and the SGI STL. -template <typename Pair> struct select1st : public unary_function<Pair,typename Pair::first_type> { - typedef typename Pair::first_type result_type; - inline const result_type& operator()(const Pair& a) const { return (a.first); } - inline result_type& operator()(Pair& a) const { return (a.first); } -}; - -/// \brief Takes a pair and returns pair.second -/// This is an extension, available in uSTL and the SGI STL. -template <typename Pair> struct select2nd : public unary_function<Pair,typename Pair::second_type> { - typedef typename Pair::second_type result_type; - inline const result_type& operator()(const Pair& a) const { return (a.second); } - inline result_type& operator()(Pair& a) const { return (a.second); } -}; - -/// \brief Converts a const_iterator pair into an iterator pair -/// Useful for converting pair ranges returned by equal_range, for instance. -/// This is an extension, available in uSTL. -template <typename Container> -inline pair<typename Container::iterator, typename Container::iterator> -unconst (const pair<typename Container::const_iterator, typename Container::const_iterator>& i, Container&) -{ - typedef pair<typename Container::iterator, typename Container::iterator> unconst_pair_t; - return (*noalias_cast<unconst_pair_t*>(&i)); -} - -//----{ vector }-------------------------------------------------------- - -template <typename T> -inline size_t alignof (const vector<T>&) -{ - typedef typename vector<T>::written_size_type written_size_type; - return (alignof (written_size_type())); -} - -//----{ bitset }-------------------------------------------------------- - -/// Writes bitset \p v into stream \p os. -template <size_t Size> -istringstream& operator>> (istringstream& is, bitset<Size>& v) -{ - char c; - for (int i = Size; --i >= 0 && (is >> c).good();) - v.set (i, c == '1'); - return (is); -} - -//----{ tuple }--------------------------------------------------------- - -template <size_t N, typename T> -inline istream& operator>> (istream& is, tuple<N,T>& v) - { v.read (is); return (is); } -template <size_t N, typename T> -inline ostream& operator<< (ostream& os, const tuple<N,T>& v) - { v.write (os); return (os); } -template <size_t N, typename T> -inline ostringstream& operator<< (ostringstream& os, const tuple<N,T>& v) - { v.text_write (os); return (os); } - -template <size_t N, typename T> -struct numeric_limits<tuple<N,T> > { - typedef numeric_limits<T> value_limits; - static inline tuple<N,T> min (void) { tuple<N,T> v; fill (v, value_limits::min()); return (v); } - static inline tuple<N,T> max (void) { tuple<N,T> v; fill (v, value_limits::max()); return (v); } - static const bool is_signed = value_limits::is_signed; - static const bool is_integer = value_limits::is_integer; - static const bool is_integral = value_limits::is_integral; -}; - -template <size_t N, typename T> -inline size_t alignof (const tuple<N,T>&) { return (alignof (NullValue<T>())); } - -template <typename T, typename IntT> -inline ostringstream& chartype_text_write (ostringstream& os, const T& v) -{ - os.format (_FmtPrtChr[!isprint(v)], v); - return (os); -} - -template <> -inline ostringstream& container_element_text_write (ostringstream& os, const uint8_t& v) -{ return (chartype_text_write<uint8_t, unsigned int> (os, v)); } -template <> -inline ostringstream& container_element_text_write (ostringstream& os, const int8_t& v) -{ return (chartype_text_write<int8_t, int> (os, v)); } - -//----{ matrix }-------------------------------------------------------- - -/// Writes tuple \p v into stream \p os. -template <size_t NX, size_t NY, typename T> -ostringstream& operator<< (ostringstream& os, const matrix<NX,NY,T>& v) -{ - os << '('; - for (uoff_t row = 0; row < NY; ++ row) { - os << '('; - for (uoff_t column = 0; column < NX; ++column) - os << v[row][column] << ",)"[column == NX-1]; - } - os << ')'; - return (os); -} - -//----{ long4grain }---------------------------------------------------- - -#if SIZE_OF_LONG == 8 && HAVE_INT64_T -// Helper class for long4grain and ptr4grain wrappers. -class _long4grain { -public: - inline _long4grain (uint64_t v) : m_v (v) {} -#if __x86_64__ - inline void read (istream& is) - { - assert (is.aligned(4)); - #if WANT_STREAM_BOUNDS_CHECKING - if (!is.verify_remaining ("read", "long4grain", sizeof(m_v))) return; - #else - assert (is.remaining() >= sizeof(m_v)); - #endif - m_v = *reinterpret_cast<const uint64_t*>(is.ipos()); - is.skip (sizeof(m_v)); - } - inline void write (ostream& os) const - { - assert (os.aligned(4)); - #if WANT_STREAM_BOUNDS_CHECKING - if (!os.verify_remaining ("write", "long4grain", sizeof(m_v))) return; - #else - assert (os.remaining() >= sizeof(m_v)); - #endif - *reinterpret_cast<uint64_t*>(os.ipos()) = m_v; - os.skip (sizeof(m_v)); - } -#elif USTL_BYTE_ORDER == USTL_BIG_ENDIAN - inline void read (istream& is) { uint32_t vl, vh; is >> vh >> vl; m_v = (uint64_t(vh) << 32) | uint64_t(vl); } - inline void write (ostream& os) const { os << uint32_t(m_v >> 32) << uint32_t(m_v); } -#else - inline void read (istream& is) { uint32_t vl, vh; is >> vl >> vh; m_v = (uint64_t(vh) << 32) | uint64_t(vl); } - inline void write (ostream& os) const { os << uint32_t(m_v) << uint32_t(m_v >> 32); } -#endif - inline size_t stream_size (void) const { return (stream_size_of(m_v)); } -private: - uint64_t m_v; -}; - -/// Wrap long values to allow writing them on 4-grain even on 64bit platforms. -inline _long4grain& long4grain (unsigned long& v) { asm("":"+m"(v)); return (*noalias_cast<_long4grain*>(&v)); } -/// Wrap long values to allow writing them on 4-grain even on 64bit platforms. -inline const _long4grain long4grain (const unsigned long& v) { return (_long4grain(v)); } -/// Wrap pointer values to allow writing them on 4-grain even on 64bit platforms. -template <typename T> -inline _long4grain& ptr4grain (T*& p) { asm("":"+m"(p)); return (*noalias_cast<_long4grain*>(&p)); } -/// Wrap pointer values to allow writing them on 4-grain even on 64bit platforms. -template <typename T> -inline const _long4grain ptr4grain (const T* const& p) { return (_long4grain(uintptr_t(p))); } -#else // if not SIZE_OF_LONG == 8 && HAVE_INT64_T -inline unsigned long& long4grain (unsigned long& v) { return (v); } -inline const unsigned long& long4grain (const unsigned long& v) { return (v); } -template <typename T> inline T*& ptr4grain (T*& p) { return (p); } -template <typename T> inline const T* const& ptr4grain (const T* const& p) { return (p); } -#endif // SIZE_OF_LONG == 8 - -//---------------------------------------------------------------------- - -} // namespace ustl - -// This is here because there really is no other place to put it. -#if SIZE_OF_BOOL != SIZE_OF_CHAR -// bool is a big type on some machines (like DEC Alpha), so it's written as a byte. -ALIGNOF(bool, sizeof(uint8_t)) -CAST_STREAMABLE(bool, uint8_t) -#endif -#if SIZE_OF_LONG == 8 && HAVE_INT64_T -ALIGNOF (_long4grain, 4) -#endif - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/ustack.h +++ /dev/null @@ -1,44 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef USTACK_H_5242F5635322B2EC44A9AEE73022C6E9 -#define USTACK_H_5242F5635322B2EC44A9AEE73022C6E9 - -namespace ustl { - -/// \class stack ustack.h ustl.h -/// \ingroup Sequences -/// -/// \brief Stack adapter to uSTL containers. -/// -template <typename T> -class stack { -public: - typedef T value_type; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T& reference; - typedef const T& const_reference; - typedef T* pointer; - typedef const T* const_pointer; -public: - inline stack (void) : m_Storage () { } - explicit inline stack (const vector<T>& s) : m_Storage (s) { } - explicit inline stack (const stack& s) : m_Storage (s.m_Storage) { } - inline bool empty (void) const { return (m_Storage.empty()); } - inline size_type size (void) const { return (m_Storage.size()); } - inline reference top (void) { return (m_Storage.back()); } - inline const_reference top (void) const { return (m_Storage.back()); } - inline void push (const value_type& v) { m_Storage.push_back (v); } - inline void pop (void) { m_Storage.pop_back(); } - inline bool operator== (const stack& s) const { return (m_Storage == s.m_Storage); } - inline bool operator< (const stack& s) const { return (m_Storage.size() < s.m_Storage.size()); } -private: - vector<T> m_Storage; ///< Where the data actually is. -}; - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/ustdxept.h +++ /dev/null @@ -1,140 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef USTDXEPT_H_46F7AE967738B588038F95E41158D7FF -#define USTDXEPT_H_46F7AE967738B588038F95E41158D7FF - -#include "uexception.h" -#include "ustring.h" - -namespace ustl { - -enum { - xfmt_ErrorMessage = 2, - xfmt_LogicError = xfmt_ErrorMessage, - xfmt_RuntimeError = xfmt_ErrorMessage -}; - -/// \class logic_error ustdxept.h ustl.h -/// \ingroup Exceptions -/// -/// \brief Logic errors represent problems in the internal logic of the program. -/// -class error_message : public exception { -public: - explicit error_message (const char* arg) throw(); - virtual ~error_message (void) throw(); - inline virtual const char* what (void) const throw() { return (m_Arg.c_str()); } - inline virtual const char* name (void) const throw() { return ("error"); } - virtual void info (string& msgbuf, const char* fmt = NULL) const throw(); - virtual void read (istream& is); - virtual void write (ostream& os) const; - virtual size_t stream_size (void) const; -protected: - string m_Arg; -}; - -/// \class logic_error ustdxept.h ustl.h -/// \ingroup Exceptions -/// -/// \brief Logic errors represent problems in the internal logic of the program. -/// -class logic_error : public error_message { -public: - inline explicit logic_error (const char* arg) throw() : error_message (arg) {} - inline virtual const char* name (void) const throw() { return ("logic error"); } -}; - -/// \class domain_error ustdxept.h ustl.h -/// \ingroup Exceptions -/// -/// \brief Reports domain errors ("domain" is in the mathematical sense) -/// -class domain_error : public logic_error { -public: - inline explicit domain_error (const char* arg) throw() : logic_error (arg) {} - inline virtual const char* name (void) const throw() { return ("domain error"); } -}; - -/// \class invalid_argument ustdxept.h ustl.h -/// \ingroup Exceptions -/// -/// \brief Reports an invalid argument to a function. -/// -class invalid_argument : public logic_error { -public: - inline explicit invalid_argument (const char* arg) throw() : logic_error (arg) {} - inline virtual const char* name (void) const throw() { return ("invalid argument"); } -}; - -/// \class length_error ustdxept.h ustl.h -/// \ingroup Exceptions -/// -/// \brief Reports when an object exceeds its allowed size. -/// -class length_error : public logic_error { -public: - inline explicit length_error (const char* arg) throw() : logic_error (arg) {} - inline virtual const char* name (void) const throw() { return ("length error"); } -}; - -/// \class out_of_range ustdxept.h ustl.h -/// \ingroup Exceptions -/// -/// \brief Reports arguments with values out of allowed range. -/// -class out_of_range : public logic_error { -public: - inline explicit out_of_range (const char* arg) throw() : logic_error (arg) {} - inline virtual const char* name (void) const throw() { return ("out of range"); } -}; - -/// \class runtime_error ustdxept.h ustl.h -/// \ingroup Exceptions -/// -/// \brief Reports errors that are dependent on the data being processed. -/// -class runtime_error : public error_message { -public: - inline explicit runtime_error (const char* arg) throw() : error_message (arg) {} - inline virtual const char* name (void) const throw() { return ("runtime error"); } -}; - -/// \class range_error ustdxept.h ustl.h -/// \ingroup Exceptions -/// -/// \brief Reports data that does not fall within the permitted range. -/// -class range_error : public runtime_error { -public: - inline explicit range_error (const char* arg) throw() : runtime_error (arg) {} - inline virtual const char* name (void) const throw() { return ("range error"); } -}; - -/// \class overflow_error ustdxept.h ustl.h -/// \ingroup Exceptions -/// -/// \brief Reports arithmetic overflow. -/// -class overflow_error : public runtime_error { -public: - inline explicit overflow_error (const char* arg) throw() : runtime_error (arg) {} - inline virtual const char* name (void) const throw() { return ("overflow error"); } -}; - -/// \class underflow_error ustdxept.h ustl.h -/// \ingroup Exceptions -/// -/// \brief Reports arithmetic underflow. -/// -class underflow_error : public runtime_error { -public: - inline explicit underflow_error (const char* arg) throw() : runtime_error (arg) {} - inline virtual const char* name (void) const throw() { return ("underflow error"); } -}; - -} // namespace ustl - -#endif
--- a/packages/language/cxx/ustl/current/include/ustl.h +++ b/packages/language/cxx/ustl/current/include/ustl.h @@ -6,19 +6,19 @@ #ifndef USTL_H_6A5A10410D2CD7FC2D78FE470F045EB7 #define USTL_H_6A5A10410D2CD7FC2D78FE470F045EB7 -#include "uspecial.h" -#include "umap.h" -#include "umultimap.h" -#include "ustack.h" -#include "uqueue.h" +#include "ustl/uspecial.h" +#include "ustl/umap.h" +#include "ustl/umultimap.h" +#include "ustl/ustack.h" +#include "ustl/uqueue.h" #ifdef CYGCLS_USTL_FSTREAMS -#include "ofstream.h" +#include "ustl/ofstream.h" #endif -#include "unumeric.h" -#include "ulist.h" -#include "uheap.h" -#include "ustdxept.h" -#include "ustlecos.h" +#include "ustl/unumeric.h" +#include "ustl/ulist.h" +#include "ustl/uheap.h" +#include "ustl/ustdxept.h" +#include "ustl/ustlecos.h" #endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/bktrace.h @@ -0,0 +1,52 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2006-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef BKTRACE_H_63ABB1E4388CEDD975DBE58B57DE474F +#define BKTRACE_H_63ABB1E4388CEDD975DBE58B57DE474F + +#include "ulimits.h" +#include <stdlib.h> + +namespace ustl { + +class ostringstream; +class istream; +class ostream; + +/// \class CBacktrace bktrace.h ustl.h +/// +/// \brief Stores the backtrace from the point of construction. +/// +/// The backtrace, or callstack, is the listing of functions called to +/// reach the construction of this object. This is useful for debugging, +/// to print the location of an error. To get meaningful output you'll +/// need to use a debug build with symbols and with frame pointers. For +/// GNU ld you will also need to link with the -rdynamic option to see +/// actual function names instead of __gxx_personality0+0xF4800. +/// +class CBacktrace { +public: + CBacktrace (void) throw(); + CBacktrace (const CBacktrace& v) throw(); + inline ~CBacktrace (void) throw() { if (m_Symbols) free (m_Symbols); } + const CBacktrace& operator= (const CBacktrace& v) throw(); + void text_write (ostringstream& os) const; + void read (istream& is); + void write (ostream& os) const; + size_t stream_size (void) const; +private: + void GetSymbols (void) throw() DLL_LOCAL; +private: + void* m_Addresses [64]; ///< Addresses of each function on the stack. + char* m_Symbols; ///< Symbols corresponding to each address. + uint32_t m_nFrames; ///< Number of addresses in m_Addresses. + uint32_t m_SymbolsSize; ///< Size of m_Symbols. +}; + +} // namespace ustl + +ALIGNOF(ustl::CBacktrace, sizeof(void*)) + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/cmemlink.h @@ -0,0 +1,103 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef CMEMLINK_H_7CFAB32C5C6732ED29B34EF00EA40A12 +#define CMEMLINK_H_7CFAB32C5C6732ED29B34EF00EA40A12 + +#include "ualgobase.h" +#include "config.h" + +/// The ustl namespace contains all ustl classes and algorithms. +namespace ustl { + +class istream; +class ostream; +class ostringstream; + +/// \class cmemlink cmemlink.h ustl.h +/// \ingroup MemoryManagement +/// +/// \brief A read-only pointer to a sized block of memory. +/// +/// Use this class the way you would a const pointer to an allocated unstructured block. +/// The pointer and block size are available through member functions and cast operator. +/// +/// Example usage: +/// +/// \code +/// void* p = malloc (46721); +/// cmemlink a, b; +/// a.link (p, 46721); +/// assert (a.size() == 46721)); +/// b = a; +/// assert (b.size() == 46721)); +/// assert (b.DataAt(34) == a.DataAt(34)); +/// assert (0 == memcmp (a, b, 12)); +/// \endcode +/// +class cmemlink { +public: + typedef char value_type; + typedef const value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type reference; + typedef value_type const_reference; + typedef size_t size_type; + typedef uint32_t written_size_type; + typedef ptrdiff_t difference_type; + typedef const_pointer const_iterator; + typedef const_iterator iterator; + typedef const cmemlink& rcself_t; +public: + inline cmemlink (void) : m_Data (NULL), m_Size (0) { } + inline cmemlink (const void* p, size_type n) : m_Data (const_pointer(p)), m_Size (n) { assert (p || !n); } + inline cmemlink (const cmemlink& l) : m_Data (l.m_Data), m_Size (l.m_Size) {} + inline virtual ~cmemlink (void) throw() {} + void link (const void* p, size_type n); + inline void link (const cmemlink& l) { link (l.begin(), l.size()); } + inline void link (const void* first, const void* last) { link (first, distance (first, last)); } + inline void relink (const void* p, size_type n); + virtual void unlink (void) throw(); + inline rcself_t operator= (const cmemlink& l) { link (l); return (*this); } + bool operator== (const cmemlink& l) const; + inline void swap (cmemlink& l) { ::ustl::swap (m_Data, l.m_Data); ::ustl::swap (m_Size, l.m_Size); } + inline size_type size (void) const { return (m_Size); } + inline size_type max_size (void) const { return (size()); } + inline size_type readable_size (void) const { return (size()); } + inline bool empty (void) const { return (!size()); } + inline const_pointer cdata (void) const { return (m_Data); } + inline iterator begin (void) const { return (iterator (cdata())); } + inline iterator iat (size_type i) const { assert (i <= size()); return (begin() + i); } + inline iterator end (void) const { return (iat (size())); } + inline void resize (size_type n) { m_Size = n; } + inline void read (istream&) { assert (!"ustl::cmemlink is a read-only object."); } + void write (ostream& os) const; + size_type stream_size (void) const; + void text_write (ostringstream& os) const; +#ifdef CYGCLS_USTL_FSTREAMS + void write_file (const char* filename, int mode = 0644) const; +#endif +private: + const_pointer m_Data; ///< Pointer to the data block (const) + size_type m_Size; ///< size of the data block +}; + +//---------------------------------------------------------------------- + +/// A fast alternative to link which can be used when relinking to the same block (i.e. when it is resized) +inline void cmemlink::relink (const void* p, size_type n) +{ + m_Data = reinterpret_cast<const_pointer>(p); + m_Size = n; +} + +//---------------------------------------------------------------------- + +/// Use with cmemlink-derived classes to link to a static array +#define static_link(v) link (VectorBlock(v)) + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/config.h @@ -0,0 +1,389 @@ +#ifndef CYGONCE_CONFIG_H +#define CYGONCE_CONFIG_H +// ========================================================================== +// +// config.h +// +// Manually constructed uSTL configuration file for eCos RTOS +// +// =========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2009 Free Software Foundation, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later +// version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License +// along with eCos; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// As a special exception, if other files instantiate templates or use +// macros or inline functions from this file, or you compile this file +// and link it with other works to produce a work based on this file, +// this file does not by itself cause the resulting work to be covered by +// the GNU General Public License. However the source code for this file +// must still be made available in accordance with section (3) of the GNU +// General Public License v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +// =========================================================================== +// =========================================================================== +// #####DESCRIPTIONBEGIN#### +// +// Author(s): Uwe Kindler +// Contributors: +// Date: 2009-07-28 +// Purpose: eCos specific uSTL configuration +// Description: +// +// ####DESCRIPTIONEND#### +// +// ========================================================================*/ +#include <stdint.h> +#include <pkgconf/ustl.h> // ustl package configuration + + +// +// If there is no RTTI support (normally this is the default eCos setting) +// C++ typeid keyword is not supported. We hide this by using a macro instead +// of using typeid keyword directly. +// +#ifdef __GXX_RTTI + #define USTL_TYPENAME(_t_) typeid(_t_).name() +#else + #define USTL_TYPENAME(_t_) "unknown type (RTTI disabled)" +#endif + +// +// If there is no exception support (normally this is the default eCos setting) +// C++ keywords try, catch and throw are not supported. To compile uSTL without +// exception support we use macros USLT_TRY, USLT_CATCH_ALL and USLT_THROW +// instead of the real keywords. To handle exceptions in debug builds we define +// a "lightwight" exception handler. This handler is simply a function that +// prints exception information do diagnostic channel. +// +#ifdef __EXCEPTIONS + #define USTL_TRY try + #define USTL_CATCH_ALL catch (...) {} + #define USTL_THROW(_exception_) throw (_exception_) +#else + namespace ustl + { + class exception; + extern void exception_handler(const exception& ex); + } + #define USTL_TRY + #define USTL_CATCH_ALL + #define USTL_THROW(_exception_) ustl::exception_handler(_exception_) +#endif + +// +// There is no eCos header that exports this function so we do it here +// +#ifdef CYGCLS_USTL_FSTREAMS +__externC int ioctl( int fd, CYG_ADDRWORD com, ... ); +#endif + + +/// Define to 1 if you want stream operations to throw exceptions on +/// insufficient data or insufficient space. All these errors should +/// be preventable in output code; the input code should verify the +/// data in a separate step. It slows down stream operations a lot, +/// but it's your call. By default only debug builds throw. +/// +#ifdef CYGSEM_USTL_STREAM_BOUNDS_CHECK +#define WANT_STREAM_BOUNDS_CHECKING 1 +#else +#undef WANT_STREAM_BOUNDS_CHECKING +#endif + +#if !defined(WANT_STREAM_BOUNDS_CHECKING) && !defined(NDEBUG) + #define WANT_STREAM_BOUNDS_CHECKING 1 +#endif + +/// Define to 1 if you want backtrace symbols demangled. +/// This adds some 15k to the library size, and requires that you link it and +/// any executables you make with the -rdynamic flag (increasing library size +/// even more). By default this option is disable. Enabling this option also +/// pulls in __cxa_demangle from libsupc++ +#undef WANT_NAME_DEMANGLING + +/// Define to 1 if you want to build without libstdc++ +#define WITHOUT_LIBSTDCPP 1 + +/// Define GNU extensions if unavailable. +#ifndef __GNUC__ + /// GCC (and some other compilers) define '__attribute__'; ustl is using this + /// macro to alert the compiler to flag inconsistencies in printf/scanf-like + /// function calls. Just in case '__attribute__' is undefined, make a dummy. + /// + #ifndef __attribute__ + #define __attribute__(p) + #endif +#endif +#if defined(__GNUC__) && __GNUC__ >= 4 + #define INLINE __attribute__((always_inline)) +#else + #define INLINE +#endif +#define DLL_EXPORT +#define DLL_LOCAL +#if defined(__GNUC__) && __GNUC__ >= 3 && (__i386__ || __x86_64__) + /// GCC 3+ supports the prefetch directive, which some CPUs use to improve caching + #define prefetch(p,rw,loc) __builtin_prefetch(p,rw,loc) +#else + #define prefetch(p,rw,loc) +#endif +#if !defined(__GNUC__) || __GNUC__ < 3 + /// __alignof__ returns the recommended alignment for the type + #define __alignof__(v) min(sizeof(v), sizeof(void*)) + /// This macro returns 1 if the value of x is known at compile time. + #ifndef __builtin_constant_p + #define __builtin_constant_p(x) 0 + #endif +#endif + +// Define to 1 if you have the `atexit' function. +#define HAVE_ATEXIT 1 + +// Define to 1 if you have the <assert.h> header file. +#define HAVE_ASSERT_H 1 + +// Define to 1 if you have the <ctype.h> header file. +#define HAVE_CTYPE_H 1 + +// Define to 1 if you have the <errno.h> header file. +#define HAVE_ERRNO_H 1 + +// Define to 1 if you have the <fcntl.h> header file. +#define HAVE_FCNTL_H 1 + +// Define to 1 if you have the <float.h> header file. +#define HAVE_FLOAT_H 1 + +// Define to 1 if you have the <limits.h> header file. +#define HAVE_LIMITS_H 1 + +// Define to 1 if you have the <locale.h> header file. +#define HAVE_LOCALE_H 1 + +// Define to 1 if your system has a working `malloc' function. +#define HAVE_MALLOC 1 + +// Define to 1 if you have the `memchr' function. +#define HAVE_MEMCHR 1 + +// Define to 1 if you have the `memmove' function. +#define HAVE_MEMMOVE 1 + +// Define to 1 if you have the `memset' function. +#define HAVE_MEMSET 1 + +// Define to 1 if the system has the type `ptrdiff_t'. +#define HAVE_PTRDIFF_T 1 + +// Define to 1 if you have the <signal.h> header file. +#define HAVE_SIGNAL_H 1 + +// Define to 1 if you have the <stdarg.h> header file. +#define HAVE_STDARG_H 1 + +// Define to 1 if you have the <stddef.h> header file. +#define HAVE_STDDEF_H 1 + +// Define to 1 if you have the <stdint.h> header file. +#define HAVE_STDINT_H 1 + +// Define to 1 if you have the <stdio.h> header file. +#define HAVE_STDIO_H 1 + +// Define to 1 if you have the <stdlib.h> header file. +#define HAVE_STDLIB_H 1 + +// Define to 1 if you have the `strerror' function. +#define HAVE_STRERROR 1 + +// Define to 1 if you have the <string.h> header file. +#define HAVE_STRING_H 1 + +// Define to 1 if you have the `strrchr' function. +#define HAVE_STRRCHR 1 + +// Define to 1 if you have the `strtol' function. +#define HAVE_STRTOL 1 + +// Define to 1 if you have the <sys/stat.h> header file. +#define HAVE_SYS_STAT_H 1 + +// Define to 1 if you have the <sys/types.h> header file. +#define HAVE_SYS_TYPES_H 1 + +// Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. +#define HAVE_SYS_WAIT_H 1 + +// Define to 1 if you have the <time.h> header file. +#define HAVE_TIME_H 1 + +// Define to 1 if you have the <unistd.h> header file. +#define HAVE_UNISTD_H 1 + +// Define to 1 if you have the <math.h> header file. +#define HAVE_MATH_H 1 + +// Define to 1 if you have the long long type +#define HAVE_LONG_LONG 1 + +// Define to 1 if you have 64 bit types available +#define HAVE_INT64_T 1 + +// Define to 1 if your compiler treats char as a separate type along with +// signed char and unsigned char. This will create overloads for char. +#define HAVE_THREE_CHAR_TYPES 1 + +// Define to 1 if you have the <cxxabi.h> header file. +#if __GNUC__ >= 3 + #define HAVE_CXXABI_H 1 +#endif + +// Define to 1 if you have the rintf function. Will use rint otherwise. +#undef HAVE_RINTF + +// Define to 1 if you have the <strings.h> header file. +#undef HAVE_STRINGS_H + +// Define to 1 if you have the `strsignal' function. +#undef HAVE_STRSIGNAL + +// Define to 1 if you have the __va_copy function +#undef HAVE_VA_COPY + +// Define to 1 if you have the <inttypes.h> header file. +#undef HAVE_INTTYPES_H + +// Define to 1 if you have the <malloc.h> header file. +#undef HAVE_MALLOC_H + +// Define to 1 if you have the <memory.h> header file. +#undef HAVE_MEMORY_H + +// Define to 1 if you have the <alloca.h> header file. +#undef HAVE_ALLOCA_H + +// Define to 1 if `stat' has the bug that it succeeds when given the +// zero-length file name argument. +#undef HAVE_STAT_EMPTY_STRING_BUG + +// STDC_HEADERS is defined to 1 on sane systems. +#if defined(HAVE_ASSERT_H) && defined(HAVE_CTYPE_H) &&\ + defined(HAVE_ERRNO_H) && defined(HAVE_FLOAT_H) &&\ + defined(HAVE_LIMITS_H) && defined(HAVE_LOCALE_H) &&\ + defined(HAVE_MATH_H) && defined(HAVE_SIGNAL_H) &&\ + defined(HAVE_STDARG_H) && defined(HAVE_STDDEF_H) &&\ + defined(HAVE_STDIO_H) && defined(HAVE_STDLIB_H) &&\ + defined(HAVE_STRING_H) && defined(HAVE_TIME_H) +#define STDC_HEADERS 1 +#endif + +// STDC_HEADERS is defined to 1 on unix systems. +#if defined(HAVE_FCNTL_H) && defined(HAVE_SYS_STAT_H) && defined(HAVE_UNISTD_H) +#define STDUNIX_HEADERS 1 +#endif + +// Define to 1 if you have the <byteswap.h> header file. +#if (__GNUC__ >= 3) // gcc 2.95 somehow doesn't recognize 'asm volatile' in libc byteswap.h +#undef HAVE_BYTESWAP_H +#endif + +// Define to 1 if `lstat' dereferences a symlink specified with a trailing slash. +#undef LSTAT_FOLLOWS_SLASHED_SYMLINK + +// Define as the return type of signal handlers (`int' or `void'). +#undef RETSIGTYPE + +// Define to 1 if you want unrolled specializations for fill and copy +#undef WANT_UNROLLED_COPY + +// Define to 1 if you want to use MMX/SSE/3dNow! processor instructions +#undef WANT_MMX + +// Define to byte sizes of types +#define SIZE_OF_CHAR 1 +#define SIZE_OF_SHORT 2 +#define SIZE_OF_INT 4 +#define SIZE_OF_LONG 4 +#define SIZE_OF_LONG_LONG 8 +#define SIZE_OF_POINTER 4 +#define SIZE_OF_SIZE_T 4 +#define SIZE_OF_BOOL 1 + + +// Byte order macros, converted in utypes.h +#define USTL_LITTLE_ENDIAN 4321 +#define USTL_BIG_ENDIAN 1234 +#if (CYG_BYTEORDER == CYG_LSBFIRST) +#define USTL_BYTE_ORDER USTL_BIG_ENDIAN +#else +#define USTL_BYTE_ORDER USTL_LITTLE_ENDIAN +#endif + +// Extended CPU capabilities +#undef CPU_HAS_FPU +#undef CPU_HAS_EXT_DEBUG +#undef CPU_HAS_TIMESTAMPC +#undef CPU_HAS_MSR +#undef CPU_HAS_CMPXCHG8 +#undef CPU_HAS_APIC +#undef CPU_HAS_SYSCALL +#undef CPU_HAS_MTRR +#undef CPU_HAS_CMOV +#undef CPU_HAS_FCMOV +#if defined WANT_MMX +#undef CPU_HAS_MMX +#undef CPU_HAS_FXSAVE +#undef CPU_HAS_SSE +#undef CPU_HAS_SSE2 +#undef CPU_HAS_SSE3 +#undef CPU_HAS_EXT_3DNOW +#undef CPU_HAS_3DNOW +#endif + +// GCC vector extensions +#if defined(CPU_HAS_MMX) || defined(CPU_HAS_SSE) + #undef HAVE_VECTOR_EXTENSIONS +#endif + +#if defined(CPU_HAS_SSE) && defined(__GNUC__) + #define __sse_align __attribute__((aligned(16))) +#else + #define __sse_align +#endif + + +// Define to empty if `const' does not conform to ANSI C. +//#undef const + +// Define as `__inline' if that's what the C compiler calls it, or to nothing +// if it is not supported. +//#undef inline + +// Define to `long' if <sys/types.h> does not define. +//#undef off_t + +// Define to `unsigned' if <sys/types.h> does not define. +//#undef size_t + +// --------------------------------------------------------------------------- +#endif // CYGONCE_CONFIG_H +
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/fstream.h @@ -0,0 +1,77 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef FSTREAM_H_056E10F70EAD416443E3B36A2D6B5FA3 +#define FSTREAM_H_056E10F70EAD416443E3B36A2D6B5FA3 + +#include "uios.h" +#include "ustring.h" + +struct stat; + +namespace ustl { + +/// \class fstream fstream.h ustl.h +/// \ingroup DeviceStreams +/// +/// \brief Implements file operations. +/// +/// This is not implemented as a stream, but rather as a base for one. You +/// should use ifstream or ofstream if you want flow operators. Otherwise +/// this only implements functions for binary i/o. +/// +class fstream : public ios_base { +public: + fstream (void); + explicit fstream (const char* filename, openmode mode = in | out); + explicit fstream (int nfd, const char* filename = ""); + ~fstream (void) throw(); + void open (const char* filename, openmode mode, mode_t perms = 0644); + void attach (int nfd, const char* filename = ""); + void detach (void); + void close (void); + void sync (void); + off_t read (void* p, off_t n); + off_t readsome (void* p, off_t n); + off_t write (const void* p, off_t n); + off_t size (void) const; + off_t seek (off_t n, seekdir whence = beg); + off_t pos (void) const; + void stat (struct stat& rs) const; + int ioctl (const char* rname, int request, long argument = 0); + inline int ioctl (const char* rname, int request, int argument) { return (fstream::ioctl (rname, request, long(argument))); } + inline int ioctl (const char* rname, int request, void* argument) { return (fstream::ioctl (rname, request, intptr_t(argument))); } + int fcntl (const char* rname, int request, long argument = 0); + inline int fcntl (const char* rname, int request, int argument) { return (fstream::fcntl (rname, request, long(argument))); } + inline int fcntl (const char* rname, int request, void* argument) { return (fstream::fcntl (rname, request, intptr_t(argument))); } +#if 0 // memory mapped files are not supported in eCos + memlink mmap (off_t n, off_t offset = 0); + void munmap (memlink& l); + void msync (memlink& l); +#endif // #if 0 + void set_nonblock (bool v = true); + inline int fd (void) const { return (m_fd); } + inline bool is_open (void) const { return (fd() >= 0); } + inline off_t tellg (void) const { return (pos()); } + inline off_t tellp (void) const { return (pos()); } + inline void seekg (off_t n, seekdir whence = beg) { seek (n, whence); } + inline void seekp (off_t n, seekdir whence = beg) { seek (n, whence); } + inline void flush (void) { sync(); } + inline const string& name (void) const { return (m_Filename); } +private: + DLL_LOCAL static int om_to_flags (openmode m); + DLL_LOCAL void set_and_throw (iostate s, const char* op); +private: + int m_fd; ///< Currently open file descriptor. + string m_Filename; ///< Currently open filename. +}; + +/// Argument macro for fstream::ioctl. Use like fs.ioctl (IOCTLID (TCGETS), &ts). +#define IOCTLID(r) "ioctl("#r")", r +#define FCNTLID(r) "fcntl("#r")", r + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/memblock.h @@ -0,0 +1,64 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef MEMBLOCK_H_7ED63A891164CC43578E63664D52A196 +#define MEMBLOCK_H_7ED63A891164CC43578E63664D52A196 + +#include "memlink.h" +#include "config.h" + +namespace ustl { + +/// \class memblock memblock.h ustl.h +/// \ingroup MemoryManagement +/// +/// \brief Allocated memory block. +/// +/// Adds memory management capabilities to memlink. Uses malloc and realloc to +/// maintain the internal pointer, but only if allocated using members of this class, +/// or if linked to using the Manage() member function. Managed memory is automatically +/// freed in the destructor. +/// +class memblock : public memlink { +public: + memblock (void); + memblock (const void* p, size_type n); + explicit memblock (size_type n); + explicit memblock (const cmemlink& b); + explicit memblock (const memlink& b); + memblock (const memblock& b); + virtual ~memblock (void) throw(); + virtual void unlink (void) throw(); + inline void assign (const cmemlink& l) { assign (l.cdata(), l.readable_size()); } + inline const memblock& operator= (const cmemlink& l) { assign (l); return (*this); } + inline const memblock& operator= (const memlink& l) { assign (l); return (*this); } + inline const memblock& operator= (const memblock& l) { assign (l); return (*this); } + inline void swap (memblock& l) { memlink::swap (l); ::ustl::swap (m_Capacity, l.m_Capacity); } + void assign (const void* p, size_type n); + void reserve (size_type newSize, bool bExact = true); + void resize (size_type newSize, bool bExact = true); + iterator insert (iterator start, size_type size); + iterator erase (iterator start, size_type size); + inline void clear (void) { resize (0); } + inline size_type capacity (void) const { return (m_Capacity); } + inline bool is_linked (void) const { return (!capacity()); } + inline size_type max_size (void) const { return (is_linked() ? memlink::max_size() : SIZE_MAX); } + inline void manage (memlink& l) { manage (l.begin(), l.size()); } + void deallocate (void) throw(); + void manage (void* p, size_type n); + void copy_link (void); + void read (istream& is); +#ifdef CYGCLS_USTL_FSTREAMS + void read_file (const char* filename); +#endif +protected: + virtual size_type minimumFreeCapacity (void) const throw() __attribute__((const)); +private: + size_type m_Capacity; ///< Number of bytes allocated by Resize. +}; + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/memlink.h @@ -0,0 +1,102 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef MEMLINK_H_798D25827C8E322D2D7E734B169FF5FC +#define MEMLINK_H_798D25827C8E322D2D7E734B169FF5FC + +#include "cmemlink.h" +#include "ualgo.h" + +namespace ustl { + +/// \class memlink memlink.h ustl.h +/// \ingroup MemoryManagement +/// +/// \brief Wrapper for pointer to block with size. +/// +/// Use this class the way you would a pointer to an allocated unstructured block. +/// The pointer and block size are available through member functions and cast operator. +/// +/// Example usage: +/// \code +/// void* p = malloc (46721); +/// memlink a, b; +/// a.link (p, 46721); +/// assert (a.size() == 46721)); +/// b = a; +/// assert (b.size() == 46721)); +/// assert (b.begin() + 34 == a.begin + 34); +/// assert (0 == memcmp (a, b, 12)); +/// a.fill (673, b, 42, 67); +/// b.erase (87, 12); +/// \endcode +/// +class memlink : public cmemlink { +public: + typedef value_type* pointer; + typedef cmemlink::pointer const_pointer; + typedef cmemlink::const_iterator const_iterator; + typedef pointer iterator; + typedef const memlink& rcself_t; +public: + inline memlink (void) : cmemlink() {} + inline memlink (void* p, size_type n) : cmemlink (p, n) {} + inline memlink (const void* p, size_type n) : cmemlink (p, n) {} + inline memlink (rcself_t l) : cmemlink (l) {} + inline explicit memlink (const cmemlink& l) : cmemlink (l) {} + inline pointer data (void) { return (const_cast<pointer>(cdata())); } + inline iterator begin (void) { return (iterator (data())); } + inline iterator iat (size_type i) { assert (i <= size()); return (begin() + i); } + inline iterator end (void) { return (iat (size())); } + inline const_iterator begin (void) const { return (cmemlink::begin()); } + inline const_iterator end (void) const { return (cmemlink::end()); } + inline const_iterator iat (size_type i) const { return (cmemlink::iat (i)); } + size_type writable_size (void) const { return (size()); } + inline rcself_t operator= (const cmemlink& l) { cmemlink::operator= (l); return (*this); } + inline rcself_t operator= (rcself_t l) { cmemlink::operator= (l); return (*this); } + inline void link (const void* p, size_type n) { cmemlink::link (p, n); } + inline void link (void* p, size_type n) { cmemlink::link (p, n); } + inline void link (const cmemlink& l) { cmemlink::link (l); } + inline void link (memlink& l) { cmemlink::link (l); } + inline void link (const void* first, const void* last) { link (first, distance (first, last)); } + inline void link (void* first, void* last) { link (first, distance (first, last)); } + inline void relink (const void* p, size_type n) { cmemlink::relink (p, n); } + inline void relink (void* p, size_type n) { cmemlink::relink (p, n); } + inline void copy (const cmemlink& l) { copy (begin(), l.cdata(), l.size()); } + inline void copy (const void* p, size_type n) { copy (begin(), p, n); } + void copy (iterator offset, const void* p, size_type n); + inline void swap (memlink& l) { cmemlink::swap (l); } + void fill (iterator start, const void* p, size_type elsize, size_type elCount = 1); + inline void insert (iterator start, size_type size); + inline void erase (iterator start, size_type size); + void read (istream& is); +}; + +/// Shifts the data in the linked block from \p start to \p start + \p n. +/// The contents of the uncovered bytes is undefined. +inline void memlink::insert (iterator start, size_type n) +{ + assert (data() || !n); + assert (cmemlink::begin() || !n); + assert (start >= begin() && start + n <= end()); + rotate (start, end() - n, end()); +} + +/// Shifts the data in the linked block from \p start + \p n to \p start. +/// The contents of the uncovered bytes is undefined. +inline void memlink::erase (iterator start, size_type n) +{ + assert (data() || !n); + assert (cmemlink::begin() || !n); + assert (start >= begin() && start + n <= end()); + rotate (start, start + n, end()); +} + +/// Use with memlink-derived classes to allocate and link to stack space. +#define alloca_link(m,n) (m).link (alloca (n), (n)) + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/metamac.h @@ -0,0 +1,92 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. +// +/// \file metamac.h +/// \brief Macros for complex metaprogramming involving pseudoiteration. + +#ifndef METAMAC_H_7235D14A209C29332F2330EF553B81AF +#define METAMAC_H_7235D14A209C29332F2330EF553B81AF + +//---------------------------------------------------------------------- +// Functors and general utilities. +//---------------------------------------------------------------------- + +/// Evaluates to itself +#define ITSELF(x) x + +/// Concatenates \p a and \p b +#define PASTE(a,b) a##b + +//---------------------------------------------------------------------- +// Lists and other iterators +//---------------------------------------------------------------------- + +/// The maximum number of elements in REPEAT, LIST, and COMMA_LIST +#define METAMAC_MAXN 9 + +/// Simple list with no separators. Repeats x N times. +/// @{ +#define REPEAT_1(x) x(1) +#define REPEAT_2(x) REPEAT_1(x) x(2) +#define REPEAT_3(x) REPEAT_2(x) x(3) +#define REPEAT_4(x) REPEAT_3(x) x(4) +#define REPEAT_5(x) REPEAT_4(x) x(5) +#define REPEAT_6(x) REPEAT_5(x) x(6) +#define REPEAT_7(x) REPEAT_6(x) x(7) +#define REPEAT_8(x) REPEAT_7(x) x(8) +#define REPEAT_9(x) REPEAT_8(x) x(9) +#define REPEAT(N,x) PASTE(REPEAT_,N)(x) +/// @} + +/// Simple separated list. Repeats x N times with sep in between. +/// @{ +#define LIST_1(x,sep) x(1) +#define LIST_2(x,sep) LIST_1(x,sep) sep x(2) +#define LIST_3(x,sep) LIST_2(x,sep) sep x(3) +#define LIST_4(x,sep) LIST_3(x,sep) sep x(4) +#define LIST_5(x,sep) LIST_4(x,sep) sep x(5) +#define LIST_6(x,sep) LIST_5(x,sep) sep x(6) +#define LIST_7(x,sep) LIST_6(x,sep) sep x(7) +#define LIST_8(x,sep) LIST_7(x,sep) sep x(8) +#define LIST_9(x,sep) LIST_8(x,sep) sep x(9) +#define LIST(N,x,sep) PASTE(LIST_,N)(x,sep) +/// @} + +/// Comma separated list. A special case of LIST needed because the preprocessor can't substitute commas. +/// @{ +#define COMMA_LIST_1(x) x(1) +#define COMMA_LIST_2(x) COMMA_LIST_1(x), x(2) +#define COMMA_LIST_3(x) COMMA_LIST_2(x), x(3) +#define COMMA_LIST_4(x) COMMA_LIST_3(x), x(4) +#define COMMA_LIST_5(x) COMMA_LIST_4(x), x(5) +#define COMMA_LIST_6(x) COMMA_LIST_5(x), x(6) +#define COMMA_LIST_7(x) COMMA_LIST_6(x), x(7) +#define COMMA_LIST_8(x) COMMA_LIST_7(x), x(8) +#define COMMA_LIST_9(x) COMMA_LIST_8(x), x(9) +#define COMMA_LIST(N,x) PASTE(COMMA_LIST_,N)(x) +/// @} + +//---------------------------------------------------------------------- +// Macros for defining LIST arguments. +//---------------------------------------------------------------------- + +/// Ignores N, producing lists of identically named arguments. +#define LARG_NONE(name,N) name + +/// Appends N to name. +#define LARG_NUMBER(name,N) name##N + +/// name is a reference type. +#define LARG_REF(name,N) name##N& + +/// Sequential parameter passed by value with sequential types. +#define LARG_MT_PARAM_BY_VALUE(type,name,N) type##N name##N + +/// Sequential parameter passed by reference with sequential types. +#define LARG_MT_PARAM_BY_REF(type,name,N) type##N& name##N + +//---------------------------------------------------------------------- + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/mistream.h @@ -0,0 +1,325 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef MISTREAM_H_103AEF1F266C04AA1A817D38705983DA +#define MISTREAM_H_103AEF1F266C04AA1A817D38705983DA + +#include "memlink.h" +#include "uexception.h" +#include "strmsize.h" +#include "utf8.h" +#include "uios.h" +#include "config.h" +#if WANT_STREAM_BOUNDS_CHECKING + #include <typeinfo> +#endif + +namespace ustl { + +class ostream; +class memlink; +class string; + +/// \class istream mistream.h ustl.h +/// \ingroup BinaryStreams +/// +/// \brief Helper class to read packed binary streams. +/// +/// This class contains a set of functions to read integral types from an +/// unstructured memory block. Unpacking binary file data can be done this +/// way, for instance. aligning the data is your responsibility, and can +/// be accomplished by proper ordering of reads and by calling the align() +/// function. Unaligned access is usually slower by orders of magnitude and, +/// on some architectures, such as PowerPC, can cause your program to crash. +/// Therefore, all read functions have asserts to check alignment. +/// Overreading the end of the stream will also cause a crash (an assert in +/// debug builds). Oh, and don't be intimidated by the size of the inlines +/// here. In the assembly code the compiler will usually chop everything down +/// to five instructions each. +/// +/// Alignment rules for your objects: +/// - Assume your writes start off 4-byte aligned. +/// - After completion, \ref istream::align the stream to at least 4. +/// - If data portability between 32bit and 64bit platforms is important +/// (it often is not, in config files and the like), ensure you are always +/// using fixed-size types and are aligning to a fixed grain. Avoid writing +/// 8-byte types, and if you do, manually align before doing so. +/// - Non-default alignment is allowed if you plan to frequently write this +/// object in array form and alignment would be costly. For example, an +/// array of uint16_t-sized objects may leave the stream uint16_t aligned +/// as long as you know about it and will default-align the stream after +/// writing the array (note: \ref vector will already do this for you) +/// +/// Example code: +/// \code +/// memblock b; +/// b.read_file ("test.file"); +/// ostream is (b); +/// is >> boolVar >> ios::talign<int>(); +/// is >> intVar >> floatVar; +/// is.read (binaryData, binaryDataSize); +/// is.align(); +/// \endcode +/// +class istream : public cmemlink, public ios_base { +public: + inline istream (void); + inline istream (const void* p, streamsize n); + inline explicit istream (const cmemlink& source); + explicit istream (const ostream& source); + inline iterator end (void) const { return (cmemlink::end()); } + inline void link (const void* p, streamsize n) { cmemlink::link (p, n); } + inline void link (const cmemlink& l) { cmemlink::link (l.cdata(), l.readable_size()); } + inline void link (const void* f, const void* l) { cmemlink::link (f, l); } + inline void relink (const void* p, streamsize n) { cmemlink::relink (p, n); m_Pos = 0; } + inline void relink (const cmemlink& l) { relink (l.cdata(), l.readable_size()); } + virtual void unlink (void) throw(); + inline virtual streamsize underflow (streamsize = 1) { return (remaining()); } + inline uoff_t pos (void) const { return (m_Pos); } + inline const_iterator ipos (void) const { return (begin() + pos()); } + inline streamsize remaining (void) const { return (size() - pos()); } + inline void seek (uoff_t newPos); + inline void iseek (const_iterator newPos); + inline void skip (streamsize nBytes); + inline bool aligned (streamsize grain = c_DefaultAlignment) const; + inline bool verify_remaining (const char* op, const char* type, streamsize n); + inline streamsize align_size (streamsize grain = c_DefaultAlignment) const; + inline void align (streamsize grain = c_DefaultAlignment); + inline void swap (istream& is); + inline void read (void* buffer, streamsize size); + inline void read (memlink& buf) { read (buf.begin(), buf.writable_size()); } + void read_strz (string& str); + streamsize readsome (void* s, streamsize n); + inline void read (istream&) { } + void write (ostream& os) const; + void text_write (ostringstream& os) const; + inline streamsize stream_size (void) const { return (remaining()); } + template <typename T> + inline void iread (T& v); + inline void ungetc (void) { seek (pos() - 1); } + inline off_t tellg (void) const { return (pos()); } + inline void seekg (off_t p, seekdir d = beg); +private: + streamoff m_Pos; ///< The current read position. +}; + +//---------------------------------------------------------------------- + +template <typename T, typename Stream> +inline streamsize required_stream_size (T, const Stream&) { return (1); } +template <typename T> +inline streamsize required_stream_size (T v, const istream&) { return (stream_size_of(v)); } + +template <typename Stream> +inline bool stream_at_eof (const Stream& stm) { return (stm.eof()); } +template <> +inline bool stream_at_eof (const istream&) { return (false); } + +/// \class istream_iterator +/// \ingroup BinaryStreamIterators +/// +/// \brief An iterator over an istream to use with uSTL algorithms. +/// +template <typename T, typename Stream = istream> +class istream_iterator { +public: + typedef T value_type; + typedef ptrdiff_t difference_type; + typedef const value_type* pointer; + typedef const value_type& reference; + typedef typename Stream::size_type size_type; +public: + istream_iterator (void) : m_pis (NULL), m_v() {} + explicit istream_iterator (Stream& is) : m_pis (&is), m_v() { Read(); } + istream_iterator (const istream_iterator& i) : m_pis (i.m_pis), m_v (i.m_v) {} + /// Reads and returns the next value. + inline const T& operator* (void) { return (m_v); } + inline istream_iterator& operator++ (void) { Read(); return (*this); } + inline istream_iterator& operator-- (void) { m_pis->seek (m_pis->pos() - 2 * stream_size_of(m_v)); return (operator++()); } + inline istream_iterator operator++ (int) { istream_iterator old (*this); operator++(); return (old); } + inline istream_iterator operator-- (int) { istream_iterator old (*this); operator--(); return (old); } + inline istream_iterator& operator+= (streamsize n) { while (n--) operator++(); return (*this); } + inline istream_iterator& operator-= (streamsize n) { m_pis->seek (m_pis->pos() - (n + 1) * stream_size_of(m_v)); return (operator++()); } + inline istream_iterator operator- (streamoff n) const { istream_iterator result (*this); return (result -= n); } + inline difference_type operator- (const istream_iterator& i) const { return (distance (i.m_pis->pos(), m_pis->pos()) / stream_size_of(m_v)); } + inline bool operator== (const istream_iterator& i) const { return ((!m_pis && !i.m_pis) || (m_pis && i.m_pis && m_pis->pos() == i.m_pis->pos())); } + inline bool operator< (const istream_iterator& i) const { return (!i.m_pis || (m_pis && m_pis->pos() < i.m_pis->pos())); } +private: + void Read (void) + { + if (!m_pis) + return; + const streamsize rs (required_stream_size (m_v, *m_pis)); + if (m_pis->remaining() < rs && m_pis->underflow (rs) < rs) { + m_pis = NULL; + return; + } + *m_pis >> m_v; + if (stream_at_eof (*m_pis)) + m_pis = NULL; + } +private: + Stream* m_pis; ///< The host stream. + T m_v; ///< Last read value; cached to be returnable as a const reference. +}; + +//---------------------------------------------------------------------- + +/// \brief Constructs a stream attached to nothing. +/// A stream attached to nothing is not usable. Call Link() functions +/// inherited from cmemlink to attach to some memory block. +/// +inline istream::istream (void) +: cmemlink (), + m_Pos (0) +{ +} + +/// Attaches the stream to a block at \p p of size \p n. +inline istream::istream (const void* p, streamsize n) +: cmemlink (p, n), + m_Pos (0) +{ +} + +/// Attaches to the block pointed to by \p source. +inline istream::istream (const cmemlink& source) +: cmemlink (source), + m_Pos (0) +{ +} + +/// Checks that \p n bytes are available in the stream, or else throws. +inline bool istream::verify_remaining (const char* op, const char* type, streamsize n) +{ + const streamsize rem = remaining(); + bool enough = n <= rem; + if (!enough) overrun (op, type, n, pos(), rem); + return (enough); +} + +/// Sets the current read position to \p newPos +inline void istream::seek (uoff_t newPos) +{ +#if WANT_STREAM_BOUNDS_CHECKING + if (newPos > size()) + USTL_THROW(stream_bounds_exception ("seekg", "byte", pos(), newPos - pos(), size())); +#else + assert (newPos <= size()); +#endif + m_Pos = newPos; +} + +/// Sets the current read position to \p newPos +inline void istream::iseek (const_iterator newPos) +{ + seek (distance (begin(), newPos)); +} + +/// Sets the current write position to \p p based on \p d. +inline void istream::seekg (off_t p, seekdir d) +{ + switch (d) { + case beg: seek (p); break; + case cur: seek (pos() + p); break; + case ios_base::end: seek (size() - p); break; + } +} + +/// Skips \p nBytes without reading them. +inline void istream::skip (streamsize nBytes) +{ + seek (pos() + nBytes); +} + +/// Returns the number of bytes to skip to be aligned on \p grain. +inline streamsize istream::align_size (streamsize grain) const +{ + return (Align (pos(), grain) - pos()); +} + +/// Returns \c true if the read position is aligned on \p grain +inline bool istream::aligned (streamsize grain) const +{ + assert (uintptr_t(begin()) % grain == 0 && "Streams should be attached aligned at the maximum element grain to avoid bus errors."); + return (pos() % grain == 0); +} + +/// aligns the read position on \p grain +inline void istream::align (streamsize grain) +{ + seek (Align (pos(), grain)); +} + +/// Reads type T from the stream via a direct pointer cast. +template <typename T> +inline void istream::iread (T& v) +{ + assert (aligned (alignof (v))); +#if WANT_STREAM_BOUNDS_CHECKING + if (!verify_remaining ("read", USTL_TYPENAME(v), sizeof(T))) + return; +#else + assert (remaining() >= sizeof(T)); +#endif + v = *reinterpret_cast<const T*>(ipos()); + m_Pos += sizeof(T); +} + +/// Swaps contents with \p is +inline void istream::swap (istream& is) +{ + cmemlink::swap (is); + ::ustl::swap (m_Pos, is.m_Pos); +} + +/// Reads \p n bytes into \p buffer. +inline void istream::read (void* buffer, size_type n) +{ +#if WANT_STREAM_BOUNDS_CHECKING + if (!verify_remaining ("read", "binary data", n)) + return; +#else + assert (remaining() >= n && "Reading past end of buffer. Make sure you are reading the right format."); +#endif + memcpy (reinterpret_cast<value_type*>(buffer), ipos(), n); + m_Pos += n; +} + +//---------------------------------------------------------------------- + +template <typename T> struct object_reader { + inline void operator()(istream& is, T& v) const { v.read (is); } +}; +template <typename T> struct integral_object_reader { + inline void operator()(istream& is, T& v) const { is.iread (v); } +}; +template <typename T> +inline istream& operator>> (istream& is, T& v) { + typedef typename tm::Select <numeric_limits<T>::is_integral, + integral_object_reader<T>, object_reader<T> >::Result object_reader_t; + object_reader_t()(is, v); + return (is); +} +template <typename T> +inline istream& operator>> (istream& is, const T& v) { v.read (is); return (is); } + +//---------------------------------------------------------------------- + +typedef istream_iterator<utf8subchar_t> istream_iterator_for_utf8; +typedef utf8in_iterator<istream_iterator_for_utf8> utf8istream_iterator; + +/// Returns a UTF-8 adaptor reading from \p is. +inline utf8istream_iterator utf8in (istream& is) +{ + istream_iterator_for_utf8 si (is); + return (utf8istream_iterator (si)); +} + +//---------------------------------------------------------------------- + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/mostream.h @@ -0,0 +1,294 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef MOSTREAM_H_24A8C5397E0848216573E5670930FC9A +#define MOSTREAM_H_24A8C5397E0848216573E5670930FC9A + +#include "memlink.h" +#include "uexception.h" +#include "utf8.h" +#include "uios.h" +#include "config.h" +#if WANT_STREAM_BOUNDS_CHECKING + #include <typeinfo> +#endif + +namespace ustl { + +class istream; +class string; + +/// \class ostream mostream.h ustl.h +/// \ingroup BinaryStreams +/// +/// \brief Helper class to write packed binary streams. +/// +/// This class contains a set of functions to write integral types into an +/// unstructured memory block. Packing binary file data can be done this +/// way, for instance. aligning the data is your responsibility, and can +/// be accomplished by proper ordering of writes and by calling \ref ostream::align. +/// Unaligned access is usually slower by orders of magnitude and, +/// on some architectures, such as PowerPC, can cause your program to crash. +/// Therefore, all write functions have asserts to check alignment. +/// See \ref istream documentation for rules on designing your data format. +/// Overwriting the end of the stream will also cause a crash (an assert in +/// debug builds). Oh, and don't be intimidated by the size of the inlines +/// here. In the assembly code the compiler will usually chop everything down +/// to five instructions each. +/// +/// Example code: +/// \code +/// memblock b; +/// ostream os (b); +/// os << boolVar << ios::talign<int>(); +/// os << intVar << floatVar; +/// os.write (binaryData, binaryDataSize); +/// os.align(); +/// b.resize (os.pos()); +/// b.write_file ("test.file"); +/// \endcode +/// +class ostream : public memlink, public ios_base { +public: + inline ostream (void); + inline ostream (void* p, streamsize n); + inline explicit ostream (const memlink& source); + inline iterator end (void) { return (memlink::end()); } + inline const_iterator end (void) const { return (memlink::end()); } + inline void seek (uoff_t newPos); + inline void iseek (const_iterator newPos); + inline void skip (streamsize nBytes); + inline uoff_t pos (void) const { return (m_Pos); } + inline iterator ipos (void) { return (begin() + pos()); } + inline const_iterator ipos (void) const { return (begin() + pos()); } + inline streamsize remaining (void) const; + inline bool aligned (streamsize grain = c_DefaultAlignment) const; + bool verify_remaining (const char* op, const char* type, size_t n); + inline streamsize align_size (streamsize grain = c_DefaultAlignment) const; + void align (streamsize grain = c_DefaultAlignment); + inline void write (const void* buffer, streamsize size); + inline void write (const cmemlink& buf); + void write_strz (const char* str); + void read (istream& is); + inline void write (ostream& os) const { os.write (begin(), pos()); } + void text_write (ostringstream& os) const; + inline size_t stream_size (void) const { return (pos()); } + void insert (iterator start, streamsize size); + void erase (iterator start, streamsize size); + inline void swap (ostream& os); + template <typename T> + inline void iwrite (const T& v); + inline virtual streamsize overflow (streamsize = 1){ return (remaining()); } + virtual void unlink (void) throw(); + inline void link (void* p, streamsize n) { memlink::link (p, n); } + inline void link (memlink& l) { memlink::link (l.data(), l.writable_size()); } + inline void link (void* f, void* l) { memlink::link (f, l); } + inline void relink (void* p, streamsize n) { memlink::relink (p, n); m_Pos = 0; } + inline void relink (memlink& l) { relink (l.data(), l.writable_size()); } + inline void seekp (off_t p, seekdir d = beg); + inline off_t tellp (void) const { return (pos()); } +protected: + inline void SetPos (uoff_t newPos) { m_Pos = newPos; } +private: + streamoff m_Pos; ///< Current write position. +}; + +//---------------------------------------------------------------------- + +/// \class ostream_iterator mostream.h ustl.h +/// \ingroup BinaryStreamIterators +/// +/// \brief An iterator over an ostream to use with uSTL algorithms. +/// +template <typename T, typename Stream = ostream> +class ostream_iterator { +public: + typedef T value_type; + typedef ptrdiff_t difference_type; + typedef value_type* pointer; + typedef value_type& reference; + typedef typename Stream::size_type size_type; +public: + inline explicit ostream_iterator (Stream& os) + : m_Os (os) {} + inline ostream_iterator (const ostream_iterator& iter) + : m_Os (iter.m_Os) {} + /// Writes \p v into the stream. + inline ostream_iterator& operator= (const T& v) + { m_Os << v; return (*this); } + inline ostream_iterator& operator* (void) { return (*this); } + inline ostream_iterator& operator++ (void) { return (*this); } + inline ostream_iterator operator++ (int) { return (*this); } + inline ostream_iterator& operator+= (streamsize n) { m_Os.skip (n); return (*this); } + inline bool operator== (const ostream_iterator& i) const + { return (m_Os.pos() == i.m_Os.pos()); } + inline bool operator< (const ostream_iterator& i) const + { return (m_Os.pos() < i.m_Os.pos()); } +private: + Stream& m_Os; +}; + +//---------------------------------------------------------------------- + +typedef ostream_iterator<utf8subchar_t> ostream_iterator_for_utf8; +typedef utf8out_iterator<ostream_iterator_for_utf8> utf8ostream_iterator; + +/// Returns a UTF-8 adaptor writing to \p os. +inline utf8ostream_iterator utf8out (ostream& os) +{ + ostream_iterator_for_utf8 si (os); + return (utf8ostream_iterator (si)); +} + +//---------------------------------------------------------------------- + +/// \brief Constructs a stream attached to nothing. +/// A stream attached to nothing is not usable. Call Link() functions +/// inherited from memlink to attach to some memory block. +/// +inline ostream::ostream (void) +: memlink (), + m_Pos (0) +{ +} + +/// Attaches the stream to a block at \p p of size \p n. +inline ostream::ostream (void* p, streamsize n) +: memlink (p, n), + m_Pos (0) +{ +} + +/// Attaches to the block pointed to by \p source. +inline ostream::ostream (const memlink& source) +: memlink (source), + m_Pos (0) +{ +} + +/// Checks that \p n bytes are available in the stream, or else throws. +inline bool ostream::verify_remaining (const char* op, const char* type, size_t n) +{ + const size_t rem = remaining(); + bool enough = n <= rem; + if (!enough) overrun (op, type, n, pos(), rem); + return (enough); +} + +/// Move the write pointer to \p newPos +inline void ostream::seek (uoff_t newPos) +{ +#if WANT_STREAM_BOUNDS_CHECKING + if (newPos > size()) + USTL_THROW(stream_bounds_exception ("seekp", "byte", pos(), newPos - pos(), size())); +#else + assert (newPos <= size()); +#endif + SetPos (newPos); +} + +/// Sets the current write position to \p newPos +inline void ostream::iseek (const_iterator newPos) +{ + seek (distance (begin(), const_cast<iterator>(newPos))); +} + +/// Sets the current write position to \p p based on \p d. +inline void ostream::seekp (off_t p, seekdir d) +{ + switch (d) { + case beg: seek (p); break; + case cur: seek (pos() + p); break; + case ios_base::end: seek (size() - p); break; + } +} + +/// Skips \p nBytes without writing anything. +inline void ostream::skip (streamsize nBytes) +{ + seek (pos() + nBytes); +} + +/// Returns number of bytes remaining in the write buffer. +inline streamsize ostream::remaining (void) const +{ + return (size() - pos()); +} + +/// Returns \c true if the write pointer is aligned on \p grain +inline bool ostream::aligned (streamsize grain) const +{ + assert (uintptr_t(begin()) % grain == 0 && "Streams should be attached aligned at the maximum element grain to avoid bus errors."); + return (pos() % grain == 0); +} + +/// Returns the number of bytes to skip to be aligned on \p grain. +inline streamsize ostream::align_size (streamsize grain) const +{ + return (Align (pos(), grain) - pos()); +} + +/// Writes \p n bytes from \p buffer. +inline void ostream::write (const void* buffer, size_type n) +{ +#if WANT_STREAM_BOUNDS_CHECKING + if (!verify_remaining ("write", "binary data", n)) + return; +#else + assert (remaining() >= n && "Buffer overrun. Check your stream size calculations."); +#endif + memcpy (ipos(), const_iterator(buffer), n); + m_Pos += n; +} + +/// Writes the contents of \p buf into the stream as a raw dump. +inline void ostream::write (const cmemlink& buf) +{ + write (buf.begin(), buf.size()); +} + +/// Writes type T into the stream via a direct pointer cast. +template <typename T> +inline void ostream::iwrite (const T& v) +{ + assert (aligned (alignof (v))); +#if WANT_STREAM_BOUNDS_CHECKING + if (!verify_remaining ("write", USTL_TYPENAME(v), sizeof(T))) + return; +#else + assert (remaining() >= sizeof(T)); +#endif + *reinterpret_cast<T*>(ipos()) = v; + SetPos (pos() + sizeof(T)); +} + +/// Swaps with \p os +inline void ostream::swap (ostream& os) +{ + memlink::swap (os); + ::ustl::swap (m_Pos, os.m_Pos); +} + +//---------------------------------------------------------------------- + +template <typename T> struct object_writer { + inline void operator()(ostream& os, const T& v) const { v.write (os); } +}; +template <typename T> struct integral_object_writer { + inline void operator()(ostream& os, const T& v) const { os.iwrite (v); } +}; +template <typename T> +inline ostream& operator<< (ostream& os, const T& v) { + typedef typename tm::Select <numeric_limits<T>::is_integral, + integral_object_writer<T>, object_writer<T> >::Result object_writer_t; + object_writer_t()(os, v); + return (os); +} + +//---------------------------------------------------------------------- + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/ofstream.h @@ -0,0 +1,81 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef FDOSTREAM_H_5E27FC3D530BF3CA04D6C73F5700EECC +#define FDOSTREAM_H_5E27FC3D530BF3CA04D6C73F5700EECC + +#include "sistream.h" +#include "sostream.h" +#include "fstream.h" +#include "config.h" + +namespace ustl { + +/// \class ofstream fdostream.h ustl.h +/// \ingroup DeviceStreams +/// \brief A string stream that writes to an fd. Implements cout and cerr. +class ofstream : public ostringstream { +public: + ofstream (void); + explicit ofstream (int Fd); + explicit ofstream (const char* filename, openmode mode = out); + virtual ~ofstream (void) throw(); + inline void open (const char* filename, openmode mode = out) { m_File.open (filename, mode); clear (m_File.rdstate()); } + void close (void); + inline bool is_open (void) const { return (m_File.is_open()); } + inline iostate exceptions (iostate v) { ostringstream::exceptions(v); return (m_File.exceptions(v)); } + inline void setstate (iostate v) { ostringstream::setstate(v); m_File.setstate(v); } + inline void clear (iostate v = goodbit) { ostringstream::clear(v); m_File.clear(v); } + inline off_t tellp (void) const { return (m_File.tellp() + ostringstream::tellp()); } + inline int fd (void) const { return (m_File.fd()); } + inline void stat (struct stat& rs) const { m_File.stat (rs); } + inline void set_nonblock (bool v = true) { m_File.set_nonblock (v); } + inline int ioctl (const char* rname, int request, long argument = 0) { return (m_File.ioctl (rname, request, argument)); } + inline int ioctl (const char* rname, int request, int argument) { return (m_File.ioctl (rname, request, argument)); } + inline int ioctl (const char* rname, int request, void* argument) { return (m_File.ioctl (rname, request, argument)); } + ofstream& seekp (off_t p, seekdir d = beg); + ofstream& flush (void); + virtual size_type overflow (size_type n = 1); +private: + fstream m_File; +}; + +/// \class ifstream fdostream.h ustl.h +/// \ingroup DeviceStreams +/// \brief A string stream that reads from an fd. Implements cin. +class ifstream : public istringstream { +public: + ifstream (void); + explicit ifstream (int Fd); + explicit ifstream (const char* filename, openmode mode = in); + inline void open (const char* filename, openmode mode = in) { m_File.open (filename, mode); clear (m_File.rdstate()); } + inline void close (void) { m_File.close(); clear (m_File.rdstate()); } + inline bool is_open (void) const { return (m_File.is_open()); } + inline iostate exceptions (iostate v) { istringstream::exceptions(v); return (m_File.exceptions(v)); } + inline void setstate (iostate v) { istringstream::setstate(v); m_File.setstate(v); } + inline void clear (iostate v = goodbit) { istringstream::clear(v); m_File.clear(v); } + inline off_t tellg (void) const { return (m_File.tellg() - remaining()); } + inline int fd (void) const { return (m_File.fd()); } + inline void stat (struct stat& rs) const { m_File.stat (rs); } + inline void set_nonblock (bool v = true) { m_File.set_nonblock (v); } + inline int ioctl (const char* rname, int request, long argument = 0) { return (m_File.ioctl (rname, request, argument)); } + inline int ioctl (const char* rname, int request, int argument) { return (m_File.ioctl (rname, request, argument)); } + inline int ioctl (const char* rname, int request, void* argument) { return (m_File.ioctl (rname, request, argument)); } + ifstream& seekg (off_t p, seekdir d = beg); + int sync (void); + virtual size_type underflow (size_type n = 1); +private: + string m_Buffer; + fstream m_File; +}; + +#ifdef CYGVAR_USTL_CIN_COUT_CERR +extern ofstream cout, cerr; +extern ifstream cin; +#endif + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/simd.h @@ -0,0 +1,466 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. +// +/// \file simd.h +/// \brief SIMD-type algorithms, with hardware acceleration, if available. +/// +/// All algorithms are container-based because iterator syntax is just too +/// damn verbose and because the specializations need to be able to tell +/// how many elements are in the container in order to choose proper SIMD +/// instruction set (i.e.: 4 floats select SSE, while 2 floats select 3dNow!) +/// Specializations are only for the tuple template because the container +/// must be of a fixed and compile-time-known size for the compiler to be +/// able to choose the specialization. + +#ifndef SIMD_H_39BE2D970DF4BD00508CCFFB482496F9 +#define SIMD_H_39BE2D970DF4BD00508CCFFB482496F9 + +#include "ulimits.h" +#if HAVE_MATH_H + #include <math.h> +#endif + +namespace ustl { +namespace simd { + +//---------------------------------------------------------------------- +// Generic algorithms +//---------------------------------------------------------------------- + +/// Applies \p op to each element in \p op1. +template <typename Ctr, typename UnaryOperation> +inline void packop (Ctr& op1, UnaryOperation op) +{ + foreach (typename Ctr::iterator, i, op1) + op (*i); +} + +/// Applies \p op to each element in \p op1 and \p op2 and stores in \p op2. +template <typename Ctr, typename BinaryOperation> +inline void packop (const Ctr& op1, Ctr& op2, BinaryOperation op) +{ + assert (op2.size() <= op1.size()); + typename Ctr::const_iterator i1 (op1.begin()); + typename Ctr::iterator i2 (op2.begin()); + for (; i2 != op2.end(); ++i1, ++i2) + *i2 = op (*i2, *i1); +} + +/// Applies \p op to corresponding elements in \p op1 and \p op2 and stores in \p result. +template <typename Ctr, typename BinaryOperation> +inline void packop (const Ctr& op1, const Ctr& op2, Ctr& result, BinaryOperation op) +{ + assert (op1.size() <= op2.size() && op1.size() <= result.size()); + passign (op1, result); + packop (op2, result); +} + +/// Copies \p op1 into \p result. +template <typename Ctr> +inline void passign (const Ctr& op1, Ctr& result) +{ + assert (op1.size() <= result.size()); + typename Ctr::iterator d (result.begin()); + foreach (typename Ctr::const_iterator, s, op1) + *d++ = *s; +} + +/// Copies \p result.size() elements from \p op1 to \p result. +template <typename Ctr> +inline void ipassign (typename Ctr::const_iterator op1, Ctr& result) +{ + foreach (typename Ctr::iterator, d, result) + *d = *op1++; +} + +template <typename Ctr1, typename Ctr2, typename ConvertFunction> +inline void pconvert (const Ctr1& op1, Ctr2& op2, ConvertFunction f) +{ + assert (op1.size() <= op2.size()); + typename Ctr1::const_iterator i1 (op1.begin()); + typename Ctr2::iterator i2 (op2.begin()); + for (; i1 != op1.end(); ++i1, ++i2) + *i2 = f (*i1); +} + +// Functionoids for SIMD operations, like saturation arithmetic, shifts, etc. +STD_BINARY_FUNCTOR (fpadds, T, ((b > numeric_limits<T>::max() - a) ? numeric_limits<T>::max() : a + b)) +STD_BINARY_FUNCTOR (fpsubs, T, ((a < numeric_limits<T>::min() + b) ? numeric_limits<T>::min() : a - b)) +STD_BINARY_FUNCTOR (fpshl, T, (a << b)) +STD_BINARY_FUNCTOR (fpshr, T, (a >> b)) +STD_BINARY_FUNCTOR (fpmin, T, (min (a, b))) +STD_BINARY_FUNCTOR (fpmax, T, (max (a, b))) +STD_BINARY_FUNCTOR (fpavg, T, ((a + b + 1) / 2)) +STD_CONVERSION_FUNCTOR (fcast, (D(a))) +#if HAVE_MATH_H +STD_UNARY_FUNCTOR (fpreciprocal,T, (1 / a)) +STD_UNARY_FUNCTOR (fpsqrt, T, (reset_mmx(), T (sqrt (a)))) +STD_UNARY_FUNCTOR (fprecipsqrt, T, (reset_mmx(), 1 / T(sqrt (a)))) +STD_UNARY_FUNCTOR (fsin, T, (reset_mmx(), T (sin (a)))) +STD_UNARY_FUNCTOR (fcos, T, (reset_mmx(), T (cos (a)))) +STD_UNARY_FUNCTOR (ftan, T, (reset_mmx(), T (tan (a)))) +#if HAVE_RINTF +STD_CONVERSION_FUNCTOR (fround, (reset_mmx(), D(rintf(a)))) +#else +STD_CONVERSION_FUNCTOR (fround, (reset_mmx(), D(rint(a)))) +#endif +template <> inline int32_t fround<double,int32_t>::operator()(const double& a) const { reset_mmx(); return (int32_t(rint(a))); } +#endif +template <> inline float fpavg<float>::operator()(const float& a, const float& b) const { return ((a + b) / 2); } +template <> inline double fpavg<double>::operator()(const double& a, const double& b) const { return ((a + b) / 2); } + +#define SIMD_PACKEDOP1(name, operation) \ +template <typename Ctr> \ +inline void name (Ctr& op1) \ +{ \ + typedef typename Ctr::value_type value_t; \ + packop (op1, operation<value_t>()); \ +} +#define SIMD_PACKEDOP2(name, operation) \ +template <typename Ctr> \ +inline void name (const Ctr& op1, Ctr& op2) \ +{ \ + typedef typename Ctr::value_type value_t; \ + packop (op1, op2, operation<value_t>()); \ +} +#define SIMD_PACKEDOP3(name, operation) \ +template <typename Ctr> \ +inline void name (const Ctr& op1, const Ctr& op2, Ctr& result) \ +{ \ + typedef typename Ctr::value_type value_t; \ + packop (op1, op2, result, operation<value_t>()); \ +} +#define SIMD_SINGLEOP1(name, operation) \ +template <typename T> \ +inline T name (T op) \ +{ \ + operation<T> obj; \ + return (obj(op)); \ +} +#define SIMD_CONVERTOP(name, operation) \ +template <typename Ctr1, typename Ctr2> \ +inline void name (const Ctr1& op1, Ctr2& op2) \ +{ \ + typedef typename Ctr1::value_type value1_t; \ + typedef typename Ctr2::value_type value2_t; \ + pconvert (op1, op2, operation<value1_t, value2_t>());\ +} + +SIMD_PACKEDOP2 (padd, plus) +SIMD_PACKEDOP2 (psub, minus) +SIMD_PACKEDOP2 (pmul, multiplies) +SIMD_PACKEDOP2 (pdiv, divides) +SIMD_PACKEDOP2 (pand, bitwise_and) +SIMD_PACKEDOP2 (por, bitwise_or) +SIMD_PACKEDOP2 (pxor, bitwise_xor) +SIMD_PACKEDOP2 (pshl, fpshl) +SIMD_PACKEDOP2 (pshr, fpshr) +SIMD_PACKEDOP2 (psubs, fpsubs) +SIMD_PACKEDOP2 (pmin, fpmin) +SIMD_PACKEDOP2 (pmax, fpmax) +SIMD_PACKEDOP2 (pavg, fpavg) + +SIMD_PACKEDOP3 (padd, plus) +SIMD_PACKEDOP3 (psub, minus) +SIMD_PACKEDOP3 (pmul, multiplies) +SIMD_PACKEDOP3 (pdiv, divides) +SIMD_PACKEDOP3 (pand, bitwise_and) +SIMD_PACKEDOP3 (por, bitwise_or) +SIMD_PACKEDOP3 (pxor, bitwise_xor) +SIMD_PACKEDOP3 (pshl, fpshl) +SIMD_PACKEDOP3 (pshr, fpshr) +SIMD_PACKEDOP3 (padds, fpadds) +SIMD_PACKEDOP3 (psubs, fpsubs) +SIMD_PACKEDOP3 (pmin, fpmin) +SIMD_PACKEDOP3 (pmax, fpmax) +SIMD_PACKEDOP3 (pavg, fpavg) + +#if HAVE_MATH_H +SIMD_PACKEDOP1 (precip, fpreciprocal) +SIMD_PACKEDOP1 (psqrt, fpsqrt) +SIMD_PACKEDOP1 (precipsqrt, fprecipsqrt) +SIMD_PACKEDOP1 (psin, fsin) +SIMD_PACKEDOP1 (pcos, fcos) +SIMD_PACKEDOP1 (ptan, ftan) + +SIMD_SINGLEOP1 (srecip, fpreciprocal) +SIMD_SINGLEOP1 (ssqrt, fpsqrt) +SIMD_SINGLEOP1 (srecipsqrt, fprecipsqrt) +SIMD_SINGLEOP1 (ssin, fsin) +SIMD_SINGLEOP1 (scos, fcos) +SIMD_SINGLEOP1 (stan, ftan) + +SIMD_CONVERTOP (pround, fround) + +template <typename T> inline int32_t sround (T op) { fround<T,int32_t> obj; return (obj (op)); } +#endif + +#undef SIMD_SINGLEOP1 +#undef SIMD_PACKEDOP3 +#undef SIMD_PACKEDOP2 +#undef SIMD_PACKEDOP1 + +//---------------------------------------------------------------------- +// Vector types to cast tuple data to +//---------------------------------------------------------------------- + +#if HAVE_VECTOR_EXTENSIONS && __GNUC__ >= 4 +#define VECTOR_ATTRIBUTE(mode,vs) __attribute__((vector_size(vs))) +#else +#define VECTOR_ATTRIBUTE(mode,vs) +#endif +typedef uint8_t v8qi_t VECTOR_ATTRIBUTE (V8QI,8); +typedef uint16_t v4hi_t VECTOR_ATTRIBUTE (V4HI,8); +typedef uint16_t v8hi_t VECTOR_ATTRIBUTE (V8HI,16); +typedef uint32_t v2si_t VECTOR_ATTRIBUTE (V2SI,8); +typedef uint32_t v4si_t VECTOR_ATTRIBUTE (V4SI,16); +#if HAVE_INT64_T +typedef uint64_t v1di_t VECTOR_ATTRIBUTE (V1DI,8); +#endif +typedef float v2sf_t VECTOR_ATTRIBUTE (V2SF,8); +typedef float v4sf_t VECTOR_ATTRIBUTE (V4SF,16); +typedef double v2df_t VECTOR_ATTRIBUTE (V2DF,16); +#undef VECTOR_ATTRIBUTE + +#define SIMDA_RI(n) "m"(oin[n]) +#define SIMDA_RO(n) "m"(oout[n]) +#define SIMDA_WI(n) "=m"(oin[n]) +#define SIMDA_WO(n) "=m"(oout[n]) + +//---------------------------------------------------------------------- +// Hardware accelerated specializations +//---------------------------------------------------------------------- + +#define SIMD_PKOP2_SPEC(n, type, optype) \ +template <> \ +inline void packop (const tuple<n,type>& oin, tuple<n,type>& oout, optype<type>) +#define SIMD_PASSIGN_SPEC(n, type) \ +template <> \ +inline void passign (const tuple<n,type>& oin, tuple<n,type>& oout) +#define SIMD_IPASSIGN_SPEC(n, type) \ +template <> \ +inline void ipassign (tuple<n,type>::const_iterator oin, tuple<n,type>& oout) +#define SIMD_CONVERT_SPEC(n, type1, type2, optype) \ +template <> \ +inline void pconvert (const tuple<n,type1>& oin, tuple<n,type2>& oout, optype<type1,type2>) + +#if CPU_HAS_MMX +#define STD_MMX_ARGS : "m"(oout[0]), "m"(oin[0]) : "mm0", "st", "memory" +#define DBL_MMX_ARGS : "m"(oout[0]), "m"(oout[2]), "m"(oin[0]), "m"(oin[2]) : "mm0", "mm1", "st", "st(1)", "memory" +#define MMX_PKOP2_SPEC(n,type,optype,instruction) \ +SIMD_PKOP2_SPEC(n,type,optype) \ +{ asm ("movq %0, %%mm0\n\t" #instruction " %1, %%mm0\n\tmovq %%mm0, %0" : STD_MMX_ARGS); reset_mmx(); } +#define MMX_DBL_PKOP2_SPEC(n,type,optype,instruction) \ +SIMD_PKOP2_SPEC(n,type,optype) \ +{ asm ("movq %0, %%mm0\n\tmovq %1, %%mm1\n\t" #instruction " %2, %%mm0\n\t" #instruction " %3, %%mm1\n\tmovq %%mm0, %0\n\tmovq %%mm1, %1" : DBL_MMX_ARGS); reset_mmx(); } +#define MMX_PASSIGN_SPEC(n,type) \ +SIMD_PASSIGN_SPEC(n,type) \ +{ asm ("movq %1, %%mm0\n\tmovq %%mm0, %0" : STD_MMX_ARGS); reset_mmx(); } +#define MMX_DBL_PASSIGN_SPEC(n,type) \ +SIMD_PASSIGN_SPEC(n,type) \ +{ asm ("movq %2, %%mm0\n\tmovq %3, %%mm1\n\tmovq %%mm0, %0\n\tmovq %%mm1, %1" : DBL_MMX_ARGS); reset_mmx(); } +#define MMX_IPASSIGN_SPEC(n,type) \ +SIMD_IPASSIGN_SPEC(n,type) \ +{ asm ("movq %1, %%mm0\n\tmovq %%mm0, %0" : STD_MMX_ARGS); reset_mmx(); } +#define MMX_DBL_IPASSIGN_SPEC(n,type) \ +SIMD_IPASSIGN_SPEC(n,type) \ +{ asm ("movq %2, %%mm0\n\tmovq %3, %%mm1\n\tmovq %%mm0, %0\n\tmovq %%mm1, %1" : DBL_MMX_ARGS); reset_mmx(); } + +MMX_PASSIGN_SPEC(8,uint8_t) +MMX_PKOP2_SPEC(8,uint8_t,plus,paddb) +MMX_PKOP2_SPEC(8,uint8_t,minus,psubb) +MMX_PKOP2_SPEC(8,uint8_t,bitwise_and,pand) +MMX_PKOP2_SPEC(8,uint8_t,bitwise_or,por) +MMX_PKOP2_SPEC(8,uint8_t,bitwise_xor,pxor) +MMX_PKOP2_SPEC(8,uint8_t,fpadds,paddusb) +MMX_PKOP2_SPEC(8,uint8_t,fpsubs,psubusb) + +MMX_PASSIGN_SPEC(8,int8_t) +MMX_PKOP2_SPEC(8,int8_t,plus,paddb) +MMX_PKOP2_SPEC(8,int8_t,minus,psubb) +MMX_PKOP2_SPEC(8,int8_t,bitwise_and,pand) +MMX_PKOP2_SPEC(8,int8_t,bitwise_or,por) +MMX_PKOP2_SPEC(8,int8_t,bitwise_xor,pxor) +MMX_PKOP2_SPEC(8,int8_t,fpadds,paddsb) +MMX_PKOP2_SPEC(8,int8_t,fpsubs,psubsb) + +MMX_PASSIGN_SPEC(4,uint16_t) +MMX_PKOP2_SPEC(4,uint16_t,plus,paddw) +MMX_PKOP2_SPEC(4,uint16_t,minus,psubw) +MMX_PKOP2_SPEC(4,uint16_t,bitwise_and,pand) +MMX_PKOP2_SPEC(4,uint16_t,bitwise_or,por) +MMX_PKOP2_SPEC(4,uint16_t,bitwise_xor,pxor) +/// \todo psllw does not work like other operations, it uses the first element for shift count. +//MMX_PKOP2_SPEC(4,uint16_t,fpshl,psllw) +//MMX_PKOP2_SPEC(4,uint16_t,fpshr,psrlw) +MMX_PKOP2_SPEC(4,uint16_t,fpadds,paddusw) +MMX_PKOP2_SPEC(4,uint16_t,fpsubs,psubusw) + +MMX_PASSIGN_SPEC(4,int16_t) +MMX_PKOP2_SPEC(4,int16_t,plus,paddw) +MMX_PKOP2_SPEC(4,int16_t,minus,psubw) +MMX_PKOP2_SPEC(4,int16_t,bitwise_and,pand) +MMX_PKOP2_SPEC(4,int16_t,bitwise_or,por) +MMX_PKOP2_SPEC(4,int16_t,bitwise_xor,pxor) +//MMX_PKOP2_SPEC(4,int16_t,fpshl,psllw) +//MMX_PKOP2_SPEC(4,int16_t,fpshr,psrlw) +MMX_PKOP2_SPEC(4,int16_t,fpadds,paddsw) +MMX_PKOP2_SPEC(4,int16_t,fpsubs,psubsw) + +MMX_PASSIGN_SPEC(2,uint32_t) +MMX_PKOP2_SPEC(2,uint32_t,plus,paddd) +MMX_PKOP2_SPEC(2,uint32_t,minus,psubd) +MMX_PKOP2_SPEC(2,uint32_t,bitwise_and,pand) +MMX_PKOP2_SPEC(2,uint32_t,bitwise_or,por) +MMX_PKOP2_SPEC(2,uint32_t,bitwise_xor,pxor) +//MMX_PKOP2_SPEC(2,uint32_t,fpshl,pslld) +//MMX_PKOP2_SPEC(2,uint32_t,fpshr,psrld) + +MMX_PASSIGN_SPEC(2,int32_t) +MMX_PKOP2_SPEC(2,int32_t,plus,paddd) +MMX_PKOP2_SPEC(2,int32_t,minus,psubd) +MMX_PKOP2_SPEC(2,int32_t,bitwise_and,pand) +MMX_PKOP2_SPEC(2,int32_t,bitwise_or,por) +MMX_PKOP2_SPEC(2,int32_t,bitwise_xor,pxor) +//MMX_PKOP2_SPEC(2,int32_t,fpshl,pslld) +//MMX_PKOP2_SPEC(2,int32_t,fpshr,psrld) + +MMX_DBL_PKOP2_SPEC(4,uint32_t,plus,paddd) +MMX_DBL_PKOP2_SPEC(4,uint32_t,minus,psubd) +MMX_DBL_PKOP2_SPEC(4,uint32_t,bitwise_and,pand) +MMX_DBL_PKOP2_SPEC(4,uint32_t,bitwise_or,por) +MMX_DBL_PKOP2_SPEC(4,uint32_t,bitwise_xor,pxor) +//MMX_DBL_PKOP2_SPEC(2,uint32_t,fpshl,pslld) +//MMX_DBL_PKOP2_SPEC(2,uint32_t,fpshr,psrld) + +MMX_DBL_PKOP2_SPEC(4,int32_t,plus,paddd) +MMX_DBL_PKOP2_SPEC(4,int32_t,minus,psubd) +MMX_DBL_PKOP2_SPEC(4,int32_t,bitwise_and,pand) +MMX_DBL_PKOP2_SPEC(4,int32_t,bitwise_or,por) +MMX_DBL_PKOP2_SPEC(4,int32_t,bitwise_xor,pxor) +//MMX_DBL_PKOP2_SPEC(2,int32_t,fpshl,pslld) +//MMX_DBL_PKOP2_SPEC(2,int32_t,fpshr,psrld) + +#if CPU_HAS_SSE || CPU_HAS_3DNOW +MMX_PKOP2_SPEC(8,uint8_t,fpavg,pavgb) +MMX_PKOP2_SPEC(8,int8_t,fpavg,pavgb) +MMX_PKOP2_SPEC(4,uint16_t,fpavg,pavgw) +MMX_PKOP2_SPEC(4,int16_t,fpavg,pavgw) +MMX_PKOP2_SPEC(8,uint8_t,fpmin,pminub) +MMX_PKOP2_SPEC(8,uint8_t,fpmax,pmaxub) +MMX_PKOP2_SPEC(4,int16_t,fpmax,pmaxsw) +MMX_PKOP2_SPEC(4,int16_t,fpmin,pminsw) +#endif // CPU_HAS_SSE || CPU_HAS_3DNOW + +#if CPU_HAS_3DNOW +MMX_PASSIGN_SPEC(2,float) +MMX_PKOP2_SPEC(2,float,plus,pfadd) +MMX_PKOP2_SPEC(2,float,minus,pfsub) +MMX_PKOP2_SPEC(2,float,multiplies,pfmul) +MMX_PKOP2_SPEC(2,float,fpmin,pfmin) +MMX_PKOP2_SPEC(2,float,fpmax,pfmax) +#ifndef CPU_HAS_SSE +MMX_DBL_PKOP2_SPEC(4,float,plus,pfadd) +MMX_DBL_PKOP2_SPEC(4,float,minus,pfsub) +MMX_DBL_PKOP2_SPEC(4,float,multiplies,pfmul) +MMX_DBL_PKOP2_SPEC(4,float,fpmin,pfmin) +MMX_DBL_PKOP2_SPEC(4,float,fpmax,pfmax) +#endif +#endif // CPU_HAS_3DNOW + +MMX_IPASSIGN_SPEC(8,uint8_t) +MMX_IPASSIGN_SPEC(4,uint16_t) +MMX_IPASSIGN_SPEC(2,uint32_t) +MMX_IPASSIGN_SPEC(2,float) + +#ifndef CPU_HAS_SSE +MMX_DBL_PASSIGN_SPEC(4,float) +MMX_DBL_PASSIGN_SPEC(4,uint32_t) +MMX_DBL_PASSIGN_SPEC(4,int32_t) +MMX_DBL_IPASSIGN_SPEC(4,float) +MMX_DBL_IPASSIGN_SPEC(4,uint32_t) +MMX_DBL_IPASSIGN_SPEC(4,int32_t) +#endif + +#undef MMX_IPASSIGN_SPEC +#undef MMX_PASSIGN_SPEC +#undef MMX_PKOP2_SPEC +#undef STD_MMX_ARGS +#endif // CPU_HAS_MMX + +#if CPU_HAS_SSE +#define STD_SSE_ARGS : "m"(oout[0]), "m"(oin[0]) : "xmm0", "memory" +#define SSE_PKOP2_SPEC(n,type,optype,instruction) \ +SIMD_PKOP2_SPEC(n,type,optype) \ +{ asm ("movups %0, %%xmm0\n\tmovups %1, %%xmm1\n\t" #instruction " %%xmm1, %%xmm0\n\tmovups %%xmm0, %0" : STD_SSE_ARGS);} +#define SSE_PASSIGN_SPEC(n,type) \ +SIMD_PASSIGN_SPEC(n,type) \ +{ asm ("movups %1, %%xmm0\n\tmovups %%xmm0, %0" : STD_SSE_ARGS);} +#define SSE_IPASSIGN_SPEC(n,type) \ +SIMD_IPASSIGN_SPEC(n,type) \ +{ asm ("movups %1, %%xmm0\n\tmovups %%xmm0, %0" : STD_SSE_ARGS);} +SSE_PASSIGN_SPEC(4,float) +SSE_PASSIGN_SPEC(4,int32_t) +SSE_PASSIGN_SPEC(4,uint32_t) +SSE_PKOP2_SPEC(4,float,plus,addps) +SSE_PKOP2_SPEC(4,float,minus,subps) +SSE_PKOP2_SPEC(4,float,multiplies,mulps) +SSE_PKOP2_SPEC(4,float,divides,divps) +SSE_PKOP2_SPEC(4,float,bitwise_and,andps) +SSE_PKOP2_SPEC(4,float,bitwise_or,orps) +SSE_PKOP2_SPEC(4,float,bitwise_xor,xorps) +SSE_PKOP2_SPEC(4,float,fpmax,maxps) +SSE_PKOP2_SPEC(4,float,fpmin,minps) + +SIMD_CONVERT_SPEC(4,float,int32_t,fround) { + asm ("cvtps2pi %2, %%mm0\n\t" + "cvtps2pi %3, %%mm1\n\t" + "movq %%mm0, %0\n\t" + "movq %%mm1, %1" + : DBL_MMX_ARGS); + reset_mmx(); +} +SIMD_CONVERT_SPEC(4,int32_t,float,fround) { + asm ("cvtpi2ps %2, %%xmm0\n\t" + "shufps $0x4E,%%xmm0,%%xmm0\n\t" + "cvtpi2ps %1, %%xmm0\n\t" + "movups %%xmm0, %0" + :: "m"(oout[0]), "m"(oin[0]), "m"(oin[2]) : "xmm0", "memory"); +} +template <> inline int32_t fround<float,int32_t>::operator()(const float& a) const { + register int32_t rv; + asm ("movss %1, %%xmm0\n\t" + "cvtss2si %%xmm0, %0" + : "=r"(rv) : "m"(a) : "xmm0" ); + return (rv); +} +template <> inline uint32_t fround<float,uint32_t>::operator()(const float& a) const { + register uint32_t rv; + asm ("movss %1, %%xmm0\n\t" + "cvtss2si %%xmm0, %0" + : "=r"(rv) : "m"(a) : "xmm0" ); + return (rv); +} + +SSE_IPASSIGN_SPEC(4,float) +SSE_IPASSIGN_SPEC(4,int32_t) +SSE_IPASSIGN_SPEC(4,uint32_t) + +#undef SSE_IPASSIGN_SPEC +#undef SSE_PASSIGN_SPEC +#undef SSE_PKOP2_SPEC +#undef STD_SSE_ARGS +#endif // CPU_HAS_SSE + +#undef SIMDA_RI +#undef SIMDA_RO +#undef SIMDA_WI +#undef SIMDA_WO +#undef SIMD_PACKEDOP_SPEC + +} // namespace simd +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/sistream.h @@ -0,0 +1,153 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef SISTREAM_H_0CCA102229A49F5D65EE852E62B27CE2 +#define SISTREAM_H_0CCA102229A49F5D65EE852E62B27CE2 + +#include "mistream.h" +#include "ustring.h" + +namespace ustl { + +/// \class istringstream sistream.h ustl.h +/// \ingroup TextStreams +/// +/// \brief A stream that reads textual data from a memory block. +/// +class istringstream : public istream { +public: + static const size_type c_MaxDelimiters = 16; ///< Maximum number of word delimiters. +public: + istringstream (void); + istringstream (const void* p, size_type n); + explicit istringstream (const cmemlink& source); + void iread (int8_t& v) { v = skip_delimiters(); } + void iread (int32_t& v); + void iread (double& v); + void iread (bool& v); + void iread (wchar_t& v); + void iread (string& v); +#if HAVE_INT64_T + void iread (int64_t& v); +#endif +#if HAVE_LONG_LONG && (!HAVE_INT64_T || SIZE_OF_LONG_LONG > 8) + void iread (long long& v); +#endif + inline string str (void) const { string s; s.link (*this); return (s); } + inline istringstream& str (const string& s) { link (s); return (*this); } + inline istringstream& get (char& c) { return (read (&c, sizeof(c))); } + inline int get (void) { char c; get(c); return (c); } + istringstream& get (char* p, size_type n, char delim = '\n'); + istringstream& get (string& s, char delim = '\n'); + istringstream& getline (char* p, size_type n, char delim = '\n'); + istringstream& getline (string& s, char delim = '\n'); + istringstream& ignore (size_type n, char delim = '\0'); + inline char peek (void) { int8_t v; iread (v); ungetc(); return (v); } + inline istringstream& putback (char) { ungetc(); return (*this); } + inline istringstream& unget (void) { ungetc(); return (*this); } + inline void set_delimiters (const char* delimiters); + inline void set_base (short base); + inline void set_decimal_separator (char) { } + inline void set_thousand_separator (char) { } + istringstream& read (void* buffer, size_type size); + inline istringstream& read (memlink& buf) { return (read (buf.begin(), buf.size())); } + inline istringstream& seekg (off_t p, seekdir d =beg) { istream::seekg(p,d); return (*this); } + inline int sync (void) { skip (remaining()); return (0); } +protected: + char skip_delimiters (void); +private: + inline void read_strz (string&) { assert (!"Reading nul characters is not allowed from text streams"); } + inline bool is_delimiter (char c) const; + template <typename T> void read_number (T& v); +private: + char m_Delimiters [c_MaxDelimiters]; + uint8_t m_Base; +}; + +//---------------------------------------------------------------------- + +/// Sets the numeric base used to read numbers. +inline void istringstream::set_base (short base) +{ + m_Base = base; +} + +/// Sets delimiters to the contents of \p delimiters. +inline void istringstream::set_delimiters (const char* delimiters) +{ +#if (__i386__ || __x86_64__) && CPU_HAS_SSE && HAVE_VECTOR_EXTENSIONS + typedef uint32_t v16ud_t __attribute__((vector_size(16))); + asm("xorps\t%%xmm0, %%xmm0\n\tmovups\t%%xmm0, %0":"=m"(*noalias_cast<v16ud_t*>(m_Delimiters))::"xmm0"); +#else + memset (m_Delimiters, 0, sizeof(m_Delimiters)); +#endif + memcpy (m_Delimiters, delimiters, min (strlen(delimiters),sizeof(m_Delimiters)-1)); +} + +/// Reads one type as another. +template <typename RealT, typename CastT> +inline void _cast_read (istringstream& is, RealT& v) +{ + CastT cv; + is.iread (cv); + v = RealT (cv); +} + +/// Reads a line of text from \p is into \p s +inline istringstream& getline (istringstream& is, string& s) + { return (is.getline (s)); } + +//---------------------------------------------------------------------- + +template <typename T> struct object_text_reader { + inline void operator()(istringstream& is, T& v) const { v.text_read (is); } +}; +template <typename T> struct integral_text_object_reader { + inline void operator()(istringstream& is, T& v) const { is.iread (v); } +}; +template <typename T> +inline istringstream& operator>> (istringstream& is, T& v) { + typedef typename tm::Select <numeric_limits<T>::is_integral, + integral_text_object_reader<T>, object_text_reader<T> >::Result object_reader_t; + object_reader_t()(is, v); + return (is); +} + +//---------------------------------------------------------------------- + +template <> struct object_text_reader<string> { + inline void operator()(istringstream& is, string& v) const { is.iread (v); } +}; +#define ISTRSTREAM_CAST_OPERATOR(RealT, CastT) \ +template <> struct integral_text_object_reader<RealT> { \ + inline void operator() (istringstream& is, RealT& v) const \ + { _cast_read<RealT,CastT>(is, v); } \ +}; +ISTRSTREAM_CAST_OPERATOR (uint8_t, int8_t) +ISTRSTREAM_CAST_OPERATOR (int16_t, int32_t) +ISTRSTREAM_CAST_OPERATOR (uint16_t, int32_t) +ISTRSTREAM_CAST_OPERATOR (uint32_t, int32_t) +ISTRSTREAM_CAST_OPERATOR (float, double) +#if HAVE_THREE_CHAR_TYPES +ISTRSTREAM_CAST_OPERATOR (char, int8_t) +#endif +#if HAVE_INT64_T +ISTRSTREAM_CAST_OPERATOR (uint64_t, int64_t) +#endif +#if SIZE_OF_LONG == SIZE_OF_INT +// This works only properly if stdint.h typedefs int to int32_t. If stdint.h +// typedefs long to int32_t then this causes compiler errors. So make shure +// that your stdint.h file typedefs int to int32_t. +ISTRSTREAM_CAST_OPERATOR (long, int) +ISTRSTREAM_CAST_OPERATOR (unsigned long,int) +#endif +#if HAVE_LONG_LONG && (!HAVE_INT64_T || SIZE_OF_LONG_LONG > 8) +ISTRSTREAM_CAST_OPERATOR (unsigned long long, long long) +#endif +#undef ISTRSTREAM_CAST_OPERATOR + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/sostream.h @@ -0,0 +1,161 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef SOSTREAM_H_5323DC8C26E181D43278F2F53FDCF19F +#define SOSTREAM_H_5323DC8C26E181D43278F2F53FDCF19F + +#include "ustring.h" +#include "mostream.h" + +namespace ustl { + +class string; + +/// \class ostringstream sostream.h ustl.h +/// \ingroup TextStreams +/// +/// \brief This stream writes textual data into a memory block. +/// +class ostringstream : public ostream { +public: + ostringstream (const string& v = ""); + ostringstream (void* p, size_t n); + void iwrite (uint8_t v); + void iwrite (wchar_t v); + inline void iwrite (int v) { iformat (v); } + inline void iwrite (unsigned int v) { iformat (v); } + inline void iwrite (long int v) { iformat (v); } + inline void iwrite (unsigned long int v) { iformat (v); } + inline void iwrite (float v) { iformat (v); } + inline void iwrite (double v) { iformat (v); } + void iwrite (bool v); + inline void iwrite (const char* s) { write (s, strlen(s)); } + inline void iwrite (const string& v) { write (v.begin(), v.size()); } + inline void iwrite (fmtflags f); +#if HAVE_LONG_LONG + inline void iwrite (long long v) { iformat (v); } + inline void iwrite (unsigned long long v) { iformat (v); } +#endif + inline size_type max_size (void) const { return (m_Buffer.max_size()); } + inline ostringstream& put (char c) { iwrite (uint8_t(c)); return (*this); } + int vformat (const char* fmt, va_list args); + int format (const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))); + inline void set_base (uint16_t b) { m_Base = b; } + inline void set_width (uint16_t w) { m_Width = w; } + inline void set_decimal_separator (char) { } + inline void set_thousand_separator (char) { } + inline void set_precision (uint16_t v) { m_Precision = v; } + void link (void* p, size_type n); + inline void link (memlink& l) { link (l.data(), l.writable_size()); } + inline const string& str (void) { flush(); return (m_Buffer); } + void str (const string& s); + ostringstream& write (const void* buffer, size_type size); + inline ostringstream& write (const cmemlink& buf) { return (write (buf.begin(), buf.size())); } + inline ostringstream& seekp (off_t p, seekdir d =beg) { ostream::seekp(p,d); return (*this); } + ostringstream& flush (void) { m_Buffer.resize (pos()); return (*this); } + virtual size_type overflow (size_type n = 1); +protected: + inline void reserve (size_type n) { m_Buffer.reserve (n, false); } + inline size_type capacity (void) const { return (m_Buffer.capacity()); } +private: + inline void write_strz (const char*) { assert (!"Writing nul characters into a text stream is not allowed"); } + inline char* encode_dec (char* fmt, uint32_t n) const; + void fmtstring (char* fmt, const char* typestr, bool bInteger) const; + template <typename T> + void iformat (T v); +private: + string m_Buffer; ///< The output buffer. + uint32_t m_Flags; ///< See ios_base::fmtflags. + uint16_t m_Width; ///< Field width. + uint8_t m_Base; ///< Numeric base for writing numbers. + uint8_t m_Precision; ///< Number of digits after the decimal separator. +}; + +//---------------------------------------------------------------------- + +template <typename T> +inline const char* printf_typestring (const T&) { return (""); } +#define PRINTF_TYPESTRING_SPEC(type,str) \ +template <> inline const char* printf_typestring (const type&) { return (str); } +PRINTF_TYPESTRING_SPEC (int, "d") +PRINTF_TYPESTRING_SPEC (unsigned int, "u") +PRINTF_TYPESTRING_SPEC (long, "ld") +PRINTF_TYPESTRING_SPEC (unsigned long, "lu") +PRINTF_TYPESTRING_SPEC (float, "f") +PRINTF_TYPESTRING_SPEC (double, "lf") +#if HAVE_LONG_LONG +PRINTF_TYPESTRING_SPEC (long long, "lld") +PRINTF_TYPESTRING_SPEC (unsigned long long, "llu") +#endif +#undef PRINTF_TYPESTRING_SPEC + +template <typename T> +void ostringstream::iformat (T v) +{ + char fmt [16]; + fmtstring (fmt, printf_typestring(v), numeric_limits<T>::is_integer); + format (fmt, v); +} + +/// Sets the flag \p f in the stream. +inline void ostringstream::iwrite (fmtflags f) +{ + switch (f) { + case oct: set_base (8); break; + case dec: set_base (10); break; + case hex: set_base (16); break; + case left: m_Flags |= left; m_Flags &= ~right; break; + case right: m_Flags |= right; m_Flags &= ~left; break; + default: m_Flags |= f; break; + } +} + +//---------------------------------------------------------------------- + +template <typename T> struct object_text_writer { + inline void operator()(ostringstream& os, const T& v) const { v.text_write (os); } +}; +template <typename T> struct integral_text_object_writer { + inline void operator()(ostringstream& os, const T& v) const { os.iwrite (v); } +}; +template <typename T> +inline ostringstream& operator<< (ostringstream& os, const T& v) { + typedef typename tm::Select <numeric_limits<T>::is_integral, + integral_text_object_writer<T>, object_text_writer<T> >::Result object_writer_t; + object_writer_t()(os, v); + return (os); +} +// Needed because if called with a char[], numeric_limits will not work. Should be removed if I find out how to partial specialize for arrays... +inline ostringstream& operator<< (ostringstream& os, const char* v) + { os.iwrite (v); return (os); } +inline ostringstream& operator<< (ostringstream& os, char* v) + { os.iwrite (v); return (os); } + +//---------------------------------------------------------------------- + +template <> struct object_text_writer<string> { + inline void operator()(ostringstream& os, const string& v) const { os.iwrite (v); } +}; +template <typename T> struct integral_text_object_writer<T*> { + inline void operator() (ostringstream& os, const T* const& v) const + { os.iwrite ((uintptr_t)(v)); } +}; +#define OSTRSTREAM_CAST_OPERATOR(RealT, CastT) \ +template <> inline ostringstream& operator<< (ostringstream& os, const RealT& v) \ + { os.iwrite ((CastT)(v)); return (os); } +OSTRSTREAM_CAST_OPERATOR (uint8_t* const, const char*) +OSTRSTREAM_CAST_OPERATOR (int8_t, uint8_t) +OSTRSTREAM_CAST_OPERATOR (short int, int) +OSTRSTREAM_CAST_OPERATOR (unsigned short, unsigned int) +#if HAVE_THREE_CHAR_TYPES +OSTRSTREAM_CAST_OPERATOR (char, uint8_t) +#endif +#undef OSTRSTREAM_CAST_OPERATOR + +//---------------------------------------------------------------------- + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/strmsize.h @@ -0,0 +1,82 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. +// +/// \file strmsize.h +/// \brief This file contains stream_size_of functions for basic types and *STREAMABLE macros. +/// stream_size_of functions return the size of the object's data that is written or +/// read from a stream. + +#ifndef STRMSIZE_H_052FF16B2D8A608761BF10333D065073 +#define STRMSIZE_H_052FF16B2D8A608761BF10333D065073 + +namespace ustl { + +/// For partial specialization of stream_size_of for objects +template <typename T> struct object_stream_size { + inline streamsize operator()(const T& v) const { return (v.stream_size()); } +}; +template <typename T> struct integral_object_stream_size { + inline streamsize operator()(const T& v) const { return (sizeof(v)); } +}; +/// Returns the size of the given object. Overloads for standard types are available. +template <typename T> +inline streamsize stream_size_of (const T& v) { + typedef typename tm::Select <numeric_limits<T>::is_integral, + integral_object_stream_size<T>, object_stream_size<T> >::Result stream_sizer_t; + return (stream_sizer_t()(v)); +} + +} // namespace ustl + +// +// Extra overloads in this macro are needed because it is the one used for +// marshalling pointers. Passing a pointer to stream_size_of creates a +// conversion ambiguity between converting to const pointer& and converting +// to bool; the compiler always chooses the bool conversion (because it +// requires 1 conversion instead of 2 for the other choice). There is little +// point in adding the overloads to other macros, since they are never used +// for pointers. +// +/// Declares that T is to be written as is into binary streams. +#define INTEGRAL_STREAMABLE(T) \ + namespace ustl { \ + inline istream& operator>> (istream& is, T& v) { is.iread(v); return (is); } \ + inline ostream& operator<< (ostream& os, const T& v) { os.iwrite(v); return (os); } \ + inline ostream& operator<< (ostream& os, T& v) { os.iwrite(v); return (os); } \ + template <> inline streamsize stream_size_of (const T& v) { return (sizeof(v)); } \ + } + +/// Declares that T contains read, write, and stream_size methods. This is no longer needed and is deprecated. +#define STD_STREAMABLE(T) + +/// Declares \p T to be writable to text streams. This is no longer needed and is deprecated. +#define TEXT_STREAMABLE(T) + +/// Declares that T is to be cast into TSUB for streaming. +#define CAST_STREAMABLE(T,TSUB) \ + namespace ustl { \ + inline istream& operator>> (istream& is, T& v) { TSUB sv; is >> sv; v = (T)(sv); return (is); } \ + inline ostream& operator<< (ostream& os, const T& v) { os << TSUB(v); return (os); } \ + template <> inline streamsize stream_size_of (const T& v) { return (stream_size_of (TSUB(v))); } \ + } + +/// Placed into a class it declares the methods required by STD_STREAMABLE. Syntactic sugar. +#define DECLARE_STD_STREAMABLE \ + public: \ + void read (istream& is); \ + void write (ostream& os) const; \ + streamsize stream_size (void) const + +/// Specifies that \p T is printed by using it as an index into \p Names string array. +#define LOOKUP_TEXT_STREAMABLE(T,Names,nNames) \ + namespace ustl { \ + inline ostringstream& operator<< (ostringstream& os, const T& v) \ + { \ + os << Names[min(uoff_t(v),uoff_t(nNames-1))]; \ + return (os); \ + } \ + } + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/traits.h @@ -0,0 +1,251 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2007-2009 by Mike Sharov <msharov@users.sourceforge.net> +// +// This implementation is adapted from the Loki library, distributed under +// the MIT license with Copyright (c) 2001 by Andrei Alexandrescu. + +#ifndef TRAITS_H_4AA3DDE15E16C947392711ED08FB1FF6 +#define TRAITS_H_4AA3DDE15E16C947392711ED08FB1FF6 + +#include "typelist.h" + +namespace ustl { +namespace tm { +namespace { + +//---------------------------------------------------------------------- +// Type classes and type modifiers +//---------------------------------------------------------------------- + +typedef tl::Seq<unsigned char, unsigned short, unsigned, unsigned long>::Type + StdUnsignedInts; +typedef tl::Seq<signed char, short, int, long>::Type StdSignedInts; +typedef tl::Seq<bool, char, wchar_t>::Type StdOtherInts; +typedef tl::Seq<float, double>::Type StdFloats; + +template <typename U> struct AddPointer { typedef U* Result; }; +template <typename U> struct AddPointer<U&> { typedef U* Result; }; +template <typename U> struct AddReference { typedef U& Result; }; +template <typename U> struct AddReference<U&> { typedef U& Result; }; +template <> struct AddReference<void> { typedef NullType Result; }; +template <typename U> struct AddParameterType { typedef const U& Result; }; +template <typename U> struct AddParameterType<U&> { typedef U& Result; }; +template <> struct AddParameterType<void> { typedef NullType Result; }; + +//---------------------------------------------------------------------- +// Function pointer testers +//---------------------------------------------------------------------- +// Macros expand to numerous parameters + +template <typename T> +struct IsFunctionPointerRaw { enum { result = false}; }; +template <typename T> +struct IsMemberFunctionPointerRaw { enum { result = false}; }; + +#define TM_FPR_MAXN 9 +#define TM_FPR_TYPE(n) PASTE(T,n) +#define TM_FPR_TYPENAME(n) typename TM_FPR_TYPE(n) + +// First specialize for regular functions +template <typename T> +struct IsFunctionPointerRaw<T(*)(void)> +{enum {result = true};}; + +#define TM_FPR_SPEC(n) \ +template <typename T, COMMA_LIST(n, TM_FPR_TYPENAME)> \ +struct IsFunctionPointerRaw<T(*)(COMMA_LIST(n, TM_FPR_TYPE))> \ +{ enum { result = true }; } + +LIST (TM_FPR_MAXN, TM_FPR_SPEC, ;); + +// Then for those with an ellipsis argument +template <typename T> +struct IsFunctionPointerRaw<T(*)(...)> +{enum {result = true};}; + +#define TM_FPR_SPEC_ELLIPSIS(n) \ +template <typename T, COMMA_LIST(n, TM_FPR_TYPENAME)> \ +struct IsFunctionPointerRaw<T(*)(COMMA_LIST(n, TM_FPR_TYPE), ...)> \ +{ enum { result = true }; } + +LIST (TM_FPR_MAXN, TM_FPR_SPEC_ELLIPSIS, ;); + +// Then for member function pointers +template <typename T, typename S> +struct IsMemberFunctionPointerRaw<T (S::*)(void)> +{ enum { result = true }; }; + +#define TM_MFPR_SPEC(n) \ +template <typename T, typename S, COMMA_LIST(n, TM_FPR_TYPENAME)> \ +struct IsMemberFunctionPointerRaw<T (S::*)(COMMA_LIST(n, TM_FPR_TYPE))> \ +{ enum { result = true };}; + +LIST (TM_FPR_MAXN, TM_MFPR_SPEC, ;); + +// Then for member function pointers with an ellipsis argument +template <typename T, typename S> +struct IsMemberFunctionPointerRaw<T (S::*)(...)> +{ enum { result = true }; }; + +#define TM_MFPR_SPEC_ELLIPSIS(n) \ +template <typename T, typename S, COMMA_LIST(n, TM_FPR_TYPENAME)> \ +struct IsMemberFunctionPointerRaw<T (S::*)(COMMA_LIST(n, TM_FPR_TYPE), ...)> \ +{ enum { result = true }; }; + +LIST (TM_FPR_MAXN, TM_MFPR_SPEC_ELLIPSIS, ;); + +// Then for const member function pointers (getting tired yet?) +template <typename T, typename S> +struct IsMemberFunctionPointerRaw<T (S::*)(void) const> +{ enum { result = true }; }; + +#define TM_CMFPR_SPEC(n) \ +template <typename T, typename S, COMMA_LIST(n, TM_FPR_TYPENAME)> \ +struct IsMemberFunctionPointerRaw<T (S::*)(COMMA_LIST(n, TM_FPR_TYPE)) const> \ +{ enum { result = true };}; + +LIST (TM_FPR_MAXN, TM_CMFPR_SPEC, ;); + +// Finally for const member function pointers with an ellipsis argument (whew!) +template <typename T, typename S> +struct IsMemberFunctionPointerRaw<T (S::*)(...) const> +{ enum { result = true }; }; + +#define TM_CMFPR_SPEC_ELLIPSIS(n) \ +template <typename T, typename S, COMMA_LIST(n, TM_FPR_TYPENAME)> \ +struct IsMemberFunctionPointerRaw<T (S::*)(COMMA_LIST(n, TM_FPR_TYPE), ...) const> \ +{ enum { result = true }; }; + +LIST (TM_FPR_MAXN, TM_CMFPR_SPEC_ELLIPSIS, ;); + +#undef TM_FPR_SPEC +#undef TM_FPR_SPEC_ELLIPSIS +#undef TM_MFPR_SPEC +#undef TM_MFPR_SPEC_ELLIPSIS +#undef TM_CMFPR_SPEC +#undef TM_CMFPR_SPEC_ELLIPSIS +#undef TM_FPR_TYPENAME +#undef TM_FPR_TYPE +#undef TM_FPR_MAXN + +} // namespace + +//---------------------------------------------------------------------- +// Type traits template +//---------------------------------------------------------------------- + +/// Figures out at compile time various properties of any given type +/// Invocations (T is a type, TypeTraits<T>::Propertie): +/// +/// - isPointer : returns true if T is a pointer type +/// - PointeeType : returns the type to which T points if T is a pointer +/// type, NullType otherwise +/// - isReference : returns true if T is a reference type +/// - ReferredType : returns the type to which T refers if T is a reference +/// type, NullType otherwise +/// - isMemberPointer : returns true if T is a pointer to member type +/// - isStdUnsignedInt: returns true if T is a standard unsigned integral type +/// - isStdSignedInt : returns true if T is a standard signed integral type +/// - isStdIntegral : returns true if T is a standard integral type +/// - isStdFloat : returns true if T is a standard floating-point type +/// - isStdArith : returns true if T is a standard arithmetic type +/// - isStdFundamental: returns true if T is a standard fundamental type +/// - isUnsignedInt : returns true if T is a unsigned integral type +/// - isSignedInt : returns true if T is a signed integral type +/// - isIntegral : returns true if T is a integral type +/// - isFloat : returns true if T is a floating-point type +/// - isArith : returns true if T is a arithmetic type +/// - isFundamental : returns true if T is a fundamental type +/// - ParameterType : returns the optimal type to be used as a parameter for +/// functions that take Ts +/// - isConst : returns true if T is a const-qualified type +/// - NonConstType : Type with removed 'const' qualifier from T, if any +/// - isVolatile : returns true if T is a volatile-qualified type +/// - NonVolatileType : Type with removed 'volatile' qualifier from T, if any +/// - UnqualifiedType : Type with removed 'const' and 'volatile' qualifiers from +/// T, if any +/// - ConstParameterType: returns the optimal type to be used as a parameter +/// for functions that take 'const T's +/// +template <typename T> +class TypeTraits { +private: + #define TMTT1 template <typename U> struct + #define TMTT2 template <typename U, typename V> struct + TMTT1 ReferenceTraits { enum { result = false }; typedef U ReferredType; }; + TMTT1 ReferenceTraits<U&> { enum { result = true }; typedef U ReferredType; }; + TMTT1 PointerTraits { enum { result = false }; typedef NullType PointeeType; }; + TMTT1 PointerTraits<U*> { enum { result = true }; typedef U PointeeType; }; + TMTT1 PointerTraits<U*&> { enum { result = true }; typedef U PointeeType; }; + TMTT1 PToMTraits { enum { result = false }; }; + TMTT2 PToMTraits<U V::*> { enum { result = true }; }; + TMTT2 PToMTraits<U V::*&> { enum { result = true }; }; + TMTT1 FunctionPointerTraits { enum { result = IsFunctionPointerRaw<U>::result }; }; + TMTT1 PToMFunctionTraits { enum { result = IsMemberFunctionPointerRaw<U>::result }; }; + TMTT1 UnConst { typedef U Result; enum { isConst = false }; }; + TMTT1 UnConst<const U> { typedef U Result; enum { isConst = true }; }; + TMTT1 UnConst<const U&> { typedef U& Result; enum { isConst = true }; }; + TMTT1 UnVolatile { typedef U Result; enum { isVolatile = false }; }; + TMTT1 UnVolatile<volatile U>{ typedef U Result; enum { isVolatile = true }; }; + TMTT1 UnVolatile<volatile U&> {typedef U& Result;enum { isVolatile = true }; }; + #undef TMTT2 + #undef TMTT1 +public: + typedef typename UnConst<T>::Result + NonConstType; + typedef typename UnVolatile<T>::Result + NonVolatileType; + typedef typename UnVolatile<typename UnConst<T>::Result>::Result + UnqualifiedType; + typedef typename PointerTraits<UnqualifiedType>::PointeeType + PointeeType; + typedef typename ReferenceTraits<T>::ReferredType + ReferredType; + + enum { isConst = UnConst<T>::isConst }; + enum { isVolatile = UnVolatile<T>::isVolatile }; + enum { isReference = ReferenceTraits<UnqualifiedType>::result }; + enum { isFunction = FunctionPointerTraits<typename AddPointer<T>::Result >::result }; + enum { isFunctionPointer= FunctionPointerTraits< + typename ReferenceTraits<UnqualifiedType>::ReferredType >::result }; + enum { isMemberFunctionPointer= PToMFunctionTraits< + typename ReferenceTraits<UnqualifiedType>::ReferredType >::result }; + enum { isMemberPointer = PToMTraits< + typename ReferenceTraits<UnqualifiedType>::ReferredType >::result || + isMemberFunctionPointer }; + enum { isPointer = PointerTraits< + typename ReferenceTraits<UnqualifiedType>::ReferredType >::result || + isFunctionPointer }; + enum { isStdUnsignedInt = tl::IndexOf<StdUnsignedInts, UnqualifiedType>::value >= 0 || + tl::IndexOf<StdUnsignedInts, + typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0}; + enum { isStdSignedInt = tl::IndexOf<StdSignedInts, UnqualifiedType>::value >= 0 || + tl::IndexOf<StdSignedInts, + typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0}; + enum { isStdIntegral = isStdUnsignedInt || isStdSignedInt || + tl::IndexOf<StdOtherInts, UnqualifiedType>::value >= 0 || + tl::IndexOf<StdOtherInts, + typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0}; + enum { isStdFloat = tl::IndexOf<StdFloats, UnqualifiedType>::value >= 0 || + tl::IndexOf<StdFloats, + typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0}; + enum { isStdArith = isStdIntegral || isStdFloat }; + enum { isStdFundamental = isStdArith || isStdFloat || Conversion<T, void>::sameType }; + + enum { isUnsignedInt = isStdUnsignedInt }; + enum { isSignedInt = isStdSignedInt }; + enum { isIntegral = isStdIntegral || isUnsignedInt || isSignedInt }; + enum { isFloat = isStdFloat }; + enum { isArith = isIntegral || isFloat }; + enum { isFundamental = isStdFundamental || isArith }; + + typedef typename Select<isStdArith || isPointer || isMemberPointer, T, + typename AddParameterType<T>::Result>::Result + ParameterType; +}; + +} // namespace tm +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/typelist.h @@ -0,0 +1,223 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2007-2009 by Mike Sharov <msharov@users.sourceforge.net> +// +// This implementation is adapted from the Loki library, distributed under +// the MIT license with Copyright (c) 2001 by Andrei Alexandrescu. + +#ifndef TYPELIST_H_2A8F84704780530D531716D41B3EA3FE +#define TYPELIST_H_2A8F84704780530D531716D41B3EA3FE + +#include "metamac.h" +#include "typet.h" + +namespace ustl { +namespace tm { + +/// The building block of typelists. Use it throught the Seq templates. +template <typename T, typename U> +struct Typelist { + typedef T Head; + typedef U Tail; +}; + +/// Namespace containing typelist-related functionality. +namespace tl { + +//---------------------------------------------------------------------- +// Seq template definitions. The macros expand to a spec per arg count +// +#define TL_MAX_SEQ_TYPES 9 +#define TL_MAX_SEQ_SPECS 8 +#define TL_SEQ_TYPE(n) T##n +#define TL_SEQ_TYPENAME(n) typename TL_SEQ_TYPE(n) +#define TL_SEQ_NULLTYPE_DEFAULT(n) TL_SEQ_TYPENAME(n)=NullType +#define TL_SEQ_TL_END(n) > +#define TL_SEQ_ONE_TYPELIST(n) Typelist<TL_SEQ_TYPE(n) + +/// Creates a typelist from a sequence of types +template <COMMA_LIST(TL_MAX_SEQ_TYPES,TL_SEQ_NULLTYPE_DEFAULT)> +struct Seq { + typedef COMMA_LIST(TL_MAX_SEQ_TYPES,TL_SEQ_ONE_TYPELIST), + NullType REPEAT(TL_MAX_SEQ_TYPES,TL_SEQ_TL_END) Type; +}; + +#define TL_SEQ_SPEC(n) \ +template <COMMA_LIST (n, TL_SEQ_TYPENAME)> \ +struct Seq<COMMA_LIST (n, TL_SEQ_TYPE)> { \ + typedef COMMA_LIST(n,TL_SEQ_ONE_TYPELIST), \ + NullType REPEAT(n,TL_SEQ_TL_END) Type; \ +} +LIST(TL_MAX_SEQ_SPECS,TL_SEQ_SPEC, ;); + +#undef TL_SEQ_SPEC +#undef TL_SEQ_TL_END +#undef TL_SEQ_ONE_TYPELIST +#undef TL_SEQ_NULLTYPE_DEFAULT +#undef TL_SEQ_TYPE +#undef TL_MAX_SEQ_SPECS + +//---------------------------------------------------------------------- +// Various utility functions follow. + +/// Length<List>::value is the number of types in the typelist. +template <typename List> struct Length { }; +template <> struct Length<NullType> { enum { value = 0 }; }; +template <typename T, typename U> +struct Length<Typelist<T, U> > { enum { value = 1 + Length<U>::value }; }; + +/// TypeAt<List, i>::Result is the ith type in List +template <typename List, unsigned index> struct TypeAt { }; +template <class Head, class Tail> +struct TypeAt<Typelist<Head, Tail>, 0> { + typedef Head Result; +}; +template <class Head, class Tail, unsigned index> +struct TypeAt<Typelist<Head, Tail>, index> { + typedef typename TypeAt<Tail, index-1>::Result Result; +}; + +/// TypeAtNonStrict<List,i,DefaultType>::Result is List[i] or DefaultType if out of range. +template <typename List, unsigned index, typename DefaultType = NullType> +struct TypeAtNonStrict { + typedef DefaultType Result; +}; +template <typename Head, typename Tail, typename DefaultType> +struct TypeAtNonStrict<Typelist<Head, Tail>, 0, DefaultType> { + typedef Head Result; +}; +template <typename Head, typename Tail, unsigned index, typename DefaultType> +struct TypeAtNonStrict<Typelist<Head, Tail>, index, DefaultType> { + typedef typename TypeAtNonStrict<Tail, index-1, DefaultType>::Result Result; +}; + +/// IndexOf<List,T>::value is the position of T in List, or -1 if not found. +template <typename List, typename T> struct IndexOf; +template <typename T> +struct IndexOf<NullType, T> { enum { value = -1 }; }; +template <typename T, typename Tail> +struct IndexOf<Typelist<T, Tail>, T> { enum { value = 0 }; }; +template <typename Head, typename Tail, typename T> +struct IndexOf<Typelist<Head, Tail>, T> { +private: + enum { iintail = IndexOf<Tail, T>::value }; +public: + enum { value = (iintail == -1 ? -1 : 1+iintail) }; +}; + +/// Appends a type or a typelist to another in Append<TList, T>::Result +template <typename List, typename T> struct Append; +template <> struct Append<NullType, NullType> { typedef NullType Result; }; +template <typename T> struct Append<NullType, T> { + typedef Typelist<T,NullType> Result; +}; +template <typename Head, typename Tail> +struct Append<NullType, Typelist<Head, Tail> > { + typedef Typelist<Head, Tail> Result; +}; +template <typename Head, typename Tail, typename T> +struct Append<Typelist<Head, Tail>, T> { + typedef Typelist<Head, typename Append<Tail, T>::Result> Result; +}; + +// Erase<List, T>::Result contains List without the first T. +template <typename TList, typename T> struct Erase; +template <typename T> +struct Erase<NullType, T> { typedef NullType Result; }; +template <typename T, typename Tail> +struct Erase<Typelist<T, Tail>, T> { typedef Tail Result; }; +template <typename Head, typename Tail, typename T> +struct Erase<Typelist<Head, Tail>, T> { + typedef Typelist<Head, typename Erase<Tail, T>::Result> Result; +}; + +// EraseAll<List, T>::Result contains List without any T. +template <typename List, typename T> struct EraseAll; +template <typename T> +struct EraseAll<NullType, T> { typedef NullType Result; }; +template <typename T, typename Tail> +struct EraseAll<Typelist<T, Tail>, T> { + typedef typename EraseAll<Tail, T>::Result Result; +}; +template <typename Head, typename Tail, typename T> +struct EraseAll<Typelist<Head, Tail>, T> { + typedef Typelist<Head, typename EraseAll<Tail, T>::Result> Result; +}; + +/// Removes all duplicate types in a typelist +template <typename List> struct NoDuplicates; +template <> struct NoDuplicates<NullType> { typedef NullType Result; }; +template <typename Head, typename Tail> +struct NoDuplicates< Typelist<Head, Tail> > { +private: + typedef typename NoDuplicates<Tail>::Result L1; + typedef typename Erase<L1, Head>::Result L2; +public: + typedef Typelist<Head, L2> Result; +}; + +// Replaces the first occurence of a type in a typelist, with another type +template <typename List, typename T, typename U> struct Replace; +template <typename T, typename U> +struct Replace<NullType, T, U> { typedef NullType Result; }; +template <typename T, typename Tail, typename U> +struct Replace<Typelist<T, Tail>, T, U> { + typedef Typelist<U, Tail> Result; +}; +template <typename Head, typename Tail, typename T, typename U> +struct Replace<Typelist<Head, Tail>, T, U> { + typedef Typelist<Head, typename Replace<Tail, T, U>::Result> Result; +}; + +// Replaces all occurences of a type in a typelist, with another type +template <typename List, typename T, typename U> struct ReplaceAll; +template <typename T, typename U> +struct ReplaceAll<NullType, T, U> { typedef NullType Result; }; +template <typename T, typename Tail, typename U> +struct ReplaceAll<Typelist<T, Tail>, T, U> { + typedef Typelist<U, typename ReplaceAll<Tail, T, U>::Result> Result; +}; +template <typename Head, typename Tail, typename T, typename U> +struct ReplaceAll<Typelist<Head, Tail>, T, U> { + typedef Typelist<Head, typename ReplaceAll<Tail, T, U>::Result> Result; +}; + +// Reverses a typelist +template <typename List> struct Reverse; +template <> struct Reverse<NullType> { typedef NullType Result; }; +template <typename Head, typename Tail> +struct Reverse< Typelist<Head, Tail> > { + typedef typename Append<typename Reverse<Tail>::Result, Head>::Result Result; +}; + +// Finds the type in a typelist that is the most derived from a given type +template <typename List, typename T> struct MostDerived; +template <typename T> struct MostDerived<NullType, T> { typedef T Result; }; +template <typename Head, typename Tail, typename T> +struct MostDerived<Typelist<Head, Tail>, T> { +private: + typedef typename MostDerived<Tail, T>::Result Candidate; +public: + typedef typename Select<SuperSubclass<Candidate,Head>::value, Head, Candidate>::Result Result; +}; + +// Arranges the types in a typelist so that the most derived types appear first +template <typename List> struct DerivedToFront; +template <> struct DerivedToFront<NullType> { typedef NullType Result; }; +template <typename Head, typename Tail> +struct DerivedToFront< Typelist<Head, Tail> > { +private: + typedef typename MostDerived<Tail, Head>::Result TheMostDerived; + typedef typename Replace<Tail, TheMostDerived, Head>::Result Temp; + typedef typename DerivedToFront<Temp>::Result L; +public: + typedef Typelist<TheMostDerived, L> Result; +}; + +//---------------------------------------------------------------------- + +} // namespace tl +} // namespace tm +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/typet.h @@ -0,0 +1,98 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2007-2009 by Mike Sharov <msharov@users.sourceforge.net> +// +// This implementation is adapted from the Loki library, distributed under +// the MIT license with Copyright (c) 2001 by Andrei Alexandrescu. + +#ifndef TYPET_H_70B4C9693A05E0B405B225F356DE5450 +#define TYPET_H_70B4C9693A05E0B405B225F356DE5450 + +namespace ustl { +/// Template metaprogramming tools +namespace tm { + +/// An empty type useful as a placeholder. +class NullType { }; + +/// Converts an integer to a type. +template <int v> struct Int2Type { enum { value = v }; }; + +/// Converts an type to a unique empty type. +template <typename T> struct Type2Type { typedef T OriginalType; }; + +/// Selects type Result = flag ? T : U +template <bool flag, typename T, typename U> +struct Select { typedef T Result; }; +template <typename T, typename U> +struct Select<false, T, U> { typedef U Result; }; + +/// IsSameType<T,U>::value is true when T=U +template <typename T, typename U> +struct IsSameType { enum { value = false }; }; +template <typename T> +struct IsSameType<T,T> { enum { value = true }; }; + +/// \brief Checks for conversion possibilities between T and U +/// Conversion<T,U>::exists is true if T is convertible to U +/// Conversion<T,U>::exists2Way is true if U is also convertible to T +/// Conversion<T,U>::sameType is true if U is T +template <typename T, typename U> +class Conversion { + typedef char UT; + typedef short TT; + static UT Test (U); + static TT Test (...); + static T MakeT (void); +public: + enum { + exists = sizeof(UT) == sizeof(Test(MakeT())), + exists2Way = exists && Conversion<U,T>::exists, + sameType = false + }; +}; +template <typename T> +struct Conversion<T, T> { enum { exists = true, exists2Way = true, sameType = true }; }; +template <typename T> +struct Conversion<void, T> { enum { exists = false, exists2Way = false, sameType = false }; }; +template <typename T> +struct Conversion<T, void> { enum { exists = false, exists2Way = false, sameType = false }; }; +template <> +struct Conversion<void, void> { enum { exists = true, exists2Way = true, sameType = true }; }; + +/// SuperSubclass<T,U>::value is true when U is derived from T, or when U is T +template <typename T, typename U> +struct SuperSubclass { + enum { value = (::ustl::tm::Conversion<const volatile U*, const volatile T*>::exists && + !::ustl::tm::Conversion<const volatile T*, const volatile void*>::sameType) }; + enum { dontUseWithIncompleteTypes = sizeof(T)==sizeof(U) }; // Dummy enum to make sure that both classes are fully defined. +}; +template <> +struct SuperSubclass<void, void> { enum { value = false }; }; +template <typename U> +struct SuperSubclass<void, U> { + enum { value = false }; + enum { dontUseWithIncompleteTypes = 0==sizeof(U) }; +}; +template <typename T> +struct SuperSubclass<T, void> { + enum { value = false }; + enum { dontUseWithIncompleteTypes = 0==sizeof(T) }; +}; + +/// SuperSubclassStrict<T,U>::value is true when U is derived from T +template <typename T, typename U> +struct SuperSubclassStrict { + enum { value = SuperSubclass<T,U>::value && + !::ustl::tm::Conversion<const volatile T*, const volatile U*>::sameType }; +}; + +// static assert support +template <bool> struct CompileTimeError; +template <> struct CompileTimeError<true> {}; +#define static_assert(cond,msg) { ::ustl::tm::CompileTimeError<!!(cond)> ERROR_##msg; (void) ERROR_##msg; } + +} // namespace tm +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/ualgo.h @@ -0,0 +1,667 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UALGO_H_711AB4214D417A51166694D47A662D6E +#define UALGO_H_711AB4214D417A51166694D47A662D6E + +#include "upair.h" +#include "ualgobase.h" +#include "ufunction.h" +#include "upredalgo.h" +#include "umemory.h" +#include <stdlib.h> // for rand() + +namespace ustl { + +/// Swaps corresponding elements of [first, last) and [result,) +/// \ingroup SwapAlgorithms +/// +template <typename ForwardIterator1, typename ForwardIterator2> +inline ForwardIterator2 swap_ranges (ForwardIterator1 first, ForwardIterator2 last, ForwardIterator2 result) +{ + for (; first != last; ++first, ++result) + iter_swap (first, result); + return (result); +} + +/// Returns the first iterator i in the range [first, last) such that +/// *i == value. Returns last if no such iterator exists. +/// \ingroup SearchingAlgorithms +/// +template <typename InputIterator, typename EqualityComparable> +inline InputIterator find (InputIterator first, InputIterator last, const EqualityComparable& value) +{ + while (first != last && !(*first == value)) + ++ first; + return (first); +} + +/// Returns the first iterator such that *i == *(i + 1) +/// \ingroup SearchingAlgorithms +/// +template <typename ForwardIterator> +ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last) +{ + if (first != last) + for (ForwardIterator prev = first; ++first != last; ++ prev) + if (*prev == *first) + return (prev); + return (last); +} + +/// Returns the pointer to the first pair of unequal elements. +/// \ingroup SearchingAlgorithms +/// +template <typename InputIterator> +pair<InputIterator,InputIterator> +mismatch (InputIterator first1, InputIterator last1, InputIterator first2) +{ + while (first1 != last1 && *first1 == *first2) + ++ first1, ++ first2; + return (make_pair (first1, first2)); +} + +/// \brief Returns true if two ranges are equal. +/// This is an extension, present in uSTL and SGI STL. +/// \ingroup SearchingAlgorithms +/// +template <typename InputIterator> +inline bool equal (InputIterator first1, InputIterator last1, InputIterator first2) +{ + return (mismatch (first1, last1, first2).first == last1); +} + +/// Count finds the number of elements in [first, last) that are equal +/// to value. More precisely, the first version of count returns the +/// number of iterators i in [first, last) such that *i == value. +/// \ingroup SearchingAlgorithms +/// +template <typename InputIterator, typename EqualityComparable> +inline size_t count (InputIterator first, InputIterator last, const EqualityComparable& value) +{ + size_t total = 0; + for (; first != last; ++first) + if (*first == value) + ++ total; + return (total); +} + +/// +/// The first version of transform performs the operation op(*i) for each +/// iterator i in the range [first, last), and assigns the result of that +/// operation to *o, where o is the corresponding output iterator. That is, +/// for each n such that 0 <= n < last - first, it performs the assignment +/// *(result + n) = op(*(first + n)). +/// The return value is result + (last - first). +/// \ingroup MutatingAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename InputIterator, typename OutputIterator, typename UnaryFunction> +inline OutputIterator transform (InputIterator first, InputIterator last, OutputIterator result, UnaryFunction op) +{ + for (; first != last; ++result, ++first) + *result = op (*first); + return (result); +} + +/// +/// The second version of transform is very similar, except that it uses a +/// Binary Function instead of a Unary Function: it performs the operation +/// op(*i1, *i2) for each iterator i1 in the range [first1, last1) and assigns +/// the result to *o, where i2 is the corresponding iterator in the second +/// input range and where o is the corresponding output iterator. That is, +/// for each n such that 0 <= n < last1 - first1, it performs the assignment +/// *(result + n) = op(*(first1 + n), *(first2 + n). +/// The return value is result + (last1 - first1). +/// \ingroup MutatingAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename InputIterator1, typename InputIterator2, typename OutputIterator, typename BinaryFunction> +inline OutputIterator transform (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result, BinaryFunction op) +{ + for (; first1 != last1; ++result, ++first1, ++first2) + *result = op (*first1, *first2); + return (result); +} + +/// Replace replaces every element in the range [first, last) equal to +/// old_value with new_value. That is: for every iterator i, +/// if *i == old_value then it performs the assignment *i = new_value. +/// \ingroup MutatingAlgorithms +/// +template <typename ForwardIterator, typename T> +inline void replace (ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value) +{ + for (; first != last; ++first) + if (*first == old_value) + *first = new_value; +} + +/// Replace_copy copies elements from the range [first, last) to the range +/// [result, result + (last-first)), except that any element equal to old_value +/// is not copied; new_value is copied instead. More precisely, for every +/// integer n such that 0 <= n < last-first, replace_copy performs the +/// assignment *(result+n) = new_value if *(first+n) == old_value, and +/// *(result+n) = *(first+n) otherwise. +/// \ingroup MutatingAlgorithms +/// +template <typename InputIterator, typename OutputIterator, typename T> +inline OutputIterator replace_copy (InputIterator first, InputIterator last, OutputIterator result, const T& old_value, const T& new_value) +{ + for (; first != last; ++result, ++first) + *result = (*first == old_value) ? new_value : *first; +} + +/// Generate assigns the result of invoking gen, a function object that +/// takes no arguments, to each element in the range [first, last). +/// \ingroup GeneratorAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename ForwardIterator, typename Generator> +inline void generate (ForwardIterator first, ForwardIterator last, Generator gen) +{ + for (; first != last; ++first) + *first = gen(); +} + +/// Generate_n assigns the result of invoking gen, a function object that +/// takes no arguments, to each element in the range [first, first+n). +/// The return value is first + n. +/// \ingroup GeneratorAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename OutputIterator, typename Generator> +inline OutputIterator generate_n (OutputIterator first, size_t n, Generator gen) +{ + for (uoff_t i = 0; i != n; ++i, ++first) + *first = gen(); + return (first); +} + +/// \brief Reverse reverses a range. +/// That is: for every i such that 0 <= i <= (last - first) / 2), +/// it exchanges *(first + i) and *(last - (i + 1)). +/// \ingroup MutatingAlgorithms +/// +template <typename BidirectionalIterator> +inline void reverse (BidirectionalIterator first, BidirectionalIterator last) +{ + for (; distance (first, --last) > 0; ++first) + iter_swap (first, last); +} + +/// \brief Reverses [first,last) and writes it to \p output. +/// \ingroup MutatingAlgorithms +/// +template <typename BidirectionalIterator, typename OutputIterator> +inline OutputIterator reverse_copy (BidirectionalIterator first, BidirectionalIterator last, OutputIterator result) +{ + for (; first != last; ++result) + *result = *--last; + return (result); +} + +/// \brief Exchanges ranges [first, middle) and [middle, last) +/// \ingroup MutatingAlgorithms +/// +template <typename ForwardIterator> +ForwardIterator rotate (ForwardIterator first, ForwardIterator middle, ForwardIterator last) +{ + if (first == middle || middle == last) + return (first); + reverse (first, middle); + reverse (middle, last); + for (;first != middle && middle != last; ++first) + iter_swap (first, --last); + reverse (first, (first == middle ? last : middle)); + return (first); +} + +/// Specialization for pointers, which can be treated identically. +template <typename T> +inline T* rotate (T* first, T* middle, T* last) +{ + rotate_fast (first, middle, last); + return (first); +} + + +/// \brief Exchanges ranges [first, middle) and [middle, last) into \p result. +/// \ingroup MutatingAlgorithms +/// +template <typename ForwardIterator, typename OutputIterator> +inline OutputIterator rotate_copy (ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator result) +{ + return (copy (first, middle, copy (middle, last, result))); +} + +/// \brief Combines two sorted ranges. +/// \ingroup SortingAlgorithms +/// +template <typename InputIterator1, typename InputIterator2, typename OutputIterator> +OutputIterator merge (InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, OutputIterator result) +{ + for (; first1 != last1 && first2 != last2; ++result) { + if (*first1 < *first2) + *result = *first1++; + else + *result = *first2++; + } + if (first1 < last1) + return (copy (first1, last1, result)); + else + return (copy (first2, last2, result)); +} + +/// Combines two sorted ranges from the same container. +/// \ingroup SortingAlgorithms +/// +template <typename InputIterator> +void inplace_merge (InputIterator first, InputIterator middle, InputIterator last) +{ + for (; middle != last; ++first) { + while (*first < *middle) + ++ first; + reverse (first, middle); + reverse (first, ++middle); + } +} + +/// Remove_copy copies elements that are not equal to value from the range +/// [first, last) to a range beginning at result. The return value is the +/// end of the resulting range. This operation is stable, meaning that the +/// relative order of the elements that are copied is the same as in the +/// range [first, last). +/// \ingroup MutatingAlgorithms +/// +template <typename InputIterator, typename OutputIterator, typename T> +OutputIterator remove_copy (InputIterator first, InputIterator last, OutputIterator result, const T& value) +{ + for (; first != last; ++first) { + if (!(*first == value)) { + *result = *first; + ++ result; + } + } + return (result); +} + +/// Remove_copy copies elements pointed to by iterators in [rfirst, rlast) +/// from the range [first, last) to a range beginning at result. The return +/// value is the end of the resulting range. This operation is stable, meaning +/// that the relative order of the elements that are copied is the same as in the +/// range [first, last). Range [rfirst, rlast) is assumed to be sorted. +/// This algorithm is a uSTL extension. +/// \ingroup MutatingAlgorithms +/// +template <typename InputIterator, typename OutputIterator, typename RInputIterator> +OutputIterator remove_copy (InputIterator first, InputIterator last, OutputIterator result, RInputIterator rfirst, RInputIterator rlast) +{ + for (; first != last; ++first) { + while (rfirst != rlast && *rfirst < first) + ++ rfirst; + if (rfirst == rlast || first != *rfirst) { + *result = *first; + ++ result; + } + } + return (result); +} + +/// Remove removes from the range [first, last) all elements that are equal to +/// value. That is, remove returns an iterator new_last such that the range +/// [first, new_last) contains no elements equal to value. [1] The iterators +/// in the range [new_last, last) are all still dereferenceable, but the +/// elements that they point to are unspecified. Remove is stable, meaning +/// that the relative order of elements that are not equal to value is +/// unchanged. +/// \ingroup MutatingAlgorithms +/// +template <typename ForwardIterator, typename T> +inline ForwardIterator remove (ForwardIterator first, ForwardIterator last, const T& value) +{ + return (remove_copy (first, last, first, value)); +} + +/// Unique_copy copies elements from the range [first, last) to a range +/// beginning with result, except that in a consecutive group of duplicate +/// elements only the first one is copied. The return value is the end of +/// the range to which the elements are copied. This behavior is similar +/// to the Unix filter uniq. +/// \ingroup MutatingAlgorithms +/// +template <typename InputIterator, typename OutputIterator> +OutputIterator unique_copy (InputIterator first, InputIterator last, OutputIterator result) +{ + if (first != last) { + *result = *first; + while (++first != last) + if (!(*first == *result)) + *++result = *first; + ++ result; + } + return (result); +} + +/// Every time a consecutive group of duplicate elements appears in the range +/// [first, last), the algorithm unique removes all but the first element. +/// That is, unique returns an iterator new_last such that the range [first, +/// new_last) contains no two consecutive elements that are duplicates. +/// The iterators in the range [new_last, last) are all still dereferenceable, +/// but the elements that they point to are unspecified. Unique is stable, +/// meaning that the relative order of elements that are not removed is +/// unchanged. +/// \ingroup MutatingAlgorithms +/// +template <typename ForwardIterator> +inline ForwardIterator unique (ForwardIterator first, ForwardIterator last) +{ + return (unique_copy (first, last, first)); +} + +/// Returns the furthermost iterator i in [first, last) such that, +/// for every iterator j in [first, i), *j < value +/// Assumes the range is sorted. +/// \ingroup SearchingAlgorithms +/// +template <typename ForwardIterator, typename LessThanComparable> +ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const LessThanComparable& value) +{ + ForwardIterator mid; + while (first != last) { + mid = advance (first, distance (first,last) / 2); + if (*mid < value) + first = mid + 1; + else + last = mid; + } + return (first); +} + +/// Performs a binary search inside the sorted range. +/// \ingroup SearchingAlgorithms +/// +template <typename ForwardIterator, typename LessThanComparable> +inline bool binary_search (ForwardIterator first, ForwardIterator last, const LessThanComparable& value) +{ + ForwardIterator found = lower_bound (first, last, value); + return (found != last && !(value < *found)); +} + +/// Returns the furthermost iterator i in [first,last) such that for +/// every iterator j in [first,i), value < *j is false. +/// \ingroup SearchingAlgorithms +/// +template <typename ForwardIterator, typename LessThanComparable> +ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const LessThanComparable& value) +{ + ForwardIterator mid; + while (first != last) { + mid = advance (first, distance (first,last) / 2); + if (value < *mid) + last = mid; + else + first = mid + 1; + } + return (last); +} + +/// Returns pair<lower_bound,upper_bound> +/// \ingroup SearchingAlgorithms +/// +template <typename ForwardIterator, typename LessThanComparable> +inline pair<ForwardIterator,ForwardIterator> equal_range (ForwardIterator first, ForwardIterator last, const LessThanComparable& value) +{ + pair<ForwardIterator,ForwardIterator> rv; + rv.second = rv.first = lower_bound (first, last, value); + while (rv.second != last && !(value < *(rv.second))) + ++ rv.second; + return (rv); +} + +/// Randomly permute the elements of the container. +/// \ingroup GeneratorAlgorithms +/// +template <typename RandomAccessIterator> +void random_shuffle (RandomAccessIterator first, RandomAccessIterator last) +{ + for (; first != last; ++ first) + iter_swap (first, first + (rand() % distance (first, last))); +} + +/// \brief Generic compare function adaptor to pass to qsort +/// \ingroup FunctorObjects +template <typename ConstPointer, typename Compare> +int qsort_adapter (const void* p1, const void* p2) +{ + ConstPointer i1 = reinterpret_cast<ConstPointer>(p1); + ConstPointer i2 = reinterpret_cast<ConstPointer>(p2); + Compare comp; + return (comp (*i1, *i2) ? -1 : (comp (*i2, *i1) ? 1 : 0)); +} + +/// Sorts the container +/// \ingroup SortingAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename RandomAccessIterator, typename Compare> +void sort (RandomAccessIterator first, RandomAccessIterator last, Compare) +{ + typedef typename iterator_traits<RandomAccessIterator>::value_type value_type; + typedef typename iterator_traits<RandomAccessIterator>::const_pointer const_pointer; + qsort (first, distance (first, last), sizeof(value_type), + &qsort_adapter<const_pointer, Compare>); +} + +/// Sorts the container +/// \ingroup SortingAlgorithms +/// +template <typename RandomAccessIterator> +inline void sort (RandomAccessIterator first, RandomAccessIterator last) +{ + typedef typename iterator_traits<RandomAccessIterator>::value_type value_type; + sort (first, last, less<value_type>()); +} + +/// Sorts the container preserving order of equal elements. +/// \ingroup SortingAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename RandomAccessIterator, typename Compare> +void stable_sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp) +{ + for (RandomAccessIterator j, i = first; ++i < last;) { // Insertion sort + for (j = i; j-- > first && comp(*i, *j);) ; + if (++j != i) rotate (j, i, i + 1); + } +} + +/// Sorts the container +/// \ingroup SortingAlgorithms +/// +template <typename RandomAccessIterator> +inline void stable_sort (RandomAccessIterator first, RandomAccessIterator last) +{ + typedef typename iterator_traits<RandomAccessIterator>::value_type value_type; + stable_sort (first, last, less<value_type>()); +} + +/// \brief Searches for the first subsequence [first2,last2) in [first1,last1) +/// \ingroup SearchingAlgorithms +template <typename ForwardIterator1, typename ForwardIterator2> +inline ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) +{ + typedef typename iterator_traits<ForwardIterator1>::value_type value_type; + return (search (first1, last1, first2, last2, equal_to<value_type>())); +} + +/// \brief Searches for the last subsequence [first2,last2) in [first1,last1) +/// \ingroup SearchingAlgorithms +template <typename ForwardIterator1, typename ForwardIterator2> +inline ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2) +{ + typedef typename iterator_traits<ForwardIterator1>::value_type value_type; + return (find_end (first1, last1, first2, last2, equal_to<value_type>())); +} + +/// \brief Searches for the first occurence of \p count \p values in [first, last) +/// \ingroup SearchingAlgorithms +template <typename Iterator, typename T> +inline Iterator search_n (Iterator first, Iterator last, size_t count, const T& value) +{ + typedef typename iterator_traits<Iterator>::value_type value_type; + return (search_n (first, last, count, value, equal_to<value_type>())); +} + +/// \brief Searches [first1,last1) for the first occurrence of an element from [first2,last2) +/// \ingroup SearchingAlgorithms +template <typename InputIterator, typename ForwardIterator> +inline InputIterator find_first_of (InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2) +{ + typedef typename iterator_traits<InputIterator>::value_type value_type; + return (find_first_of (first1, last1, first2, last2, equal_to<value_type>())); +} + +/// \brief Returns true if [first2,last2) is a subset of [first1,last1) +/// \ingroup ConditionAlgorithms +/// \ingroup SetAlgorithms +template <typename InputIterator1, typename InputIterator2> +inline bool includes (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2) +{ + typedef typename iterator_traits<InputIterator1>::value_type value_type; + return (includes (first1, last1, first2, last2, less<value_type>())); +} + +/// \brief Merges [first1,last1) with [first2,last2) +/// +/// Result will contain every element that is in either set. If duplicate +/// elements are present, max(n,m) is placed in the result. +/// +/// \ingroup SetAlgorithms +template <typename InputIterator1, typename InputIterator2, typename OutputIterator> +inline OutputIterator set_union (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) +{ + typedef typename iterator_traits<InputIterator1>::value_type value_type; + return (set_union (first1, last1, first2, last2, result, less<value_type>())); +} + +/// \brief Creates a set containing elements shared by the given ranges. +/// \ingroup SetAlgorithms +template <typename InputIterator1, typename InputIterator2, typename OutputIterator> +inline OutputIterator set_intersection (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) +{ + typedef typename iterator_traits<InputIterator1>::value_type value_type; + return (set_intersection (first1, last1, first2, last2, result, less<value_type>())); +} + +/// \brief Removes from [first1,last1) elements present in [first2,last2) +/// \ingroup SetAlgorithms +template <typename InputIterator1, typename InputIterator2, typename OutputIterator> +inline OutputIterator set_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) +{ + typedef typename iterator_traits<InputIterator1>::value_type value_type; + return (set_difference (first1, last1, first2, last2, result, less<value_type>())); +} + +/// \brief Performs union of sets A-B and B-A. +/// \ingroup SetAlgorithms +template <typename InputIterator1, typename InputIterator2, typename OutputIterator> +inline OutputIterator set_symmetric_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result) +{ + typedef typename iterator_traits<InputIterator1>::value_type value_type; + return (set_symmetric_difference (first1, last1, first2, last2, result, less<value_type>())); +} + +/// \brief Returns true if the given range is sorted. +/// \ingroup ConditionAlgorithms +template <typename ForwardIterator> +inline bool is_sorted (ForwardIterator first, ForwardIterator last) +{ + typedef typename iterator_traits<ForwardIterator>::value_type value_type; + return (is_sorted (first, last, less<value_type>())); +} + +/// \brief Compares two given containers like strcmp compares strings. +/// \ingroup ConditionAlgorithms +template <typename InputIterator1, typename InputIterator2> +inline bool lexicographical_compare (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2) +{ + typedef typename iterator_traits<InputIterator1>::value_type value_type; + return (lexicographical_compare (first1, last1, first2, last2, less<value_type>())); +} + +/// \brief Creates the next lexicographical permutation of [first,last). +/// Returns false if no further permutations can be created. +/// \ingroup GeneratorAlgorithms +template <typename BidirectionalIterator> +inline bool next_permutation (BidirectionalIterator first, BidirectionalIterator last) +{ + typedef typename iterator_traits<BidirectionalIterator>::value_type value_type; + return (next_permutation (first, last, less<value_type>())); +} + +/// \brief Creates the previous lexicographical permutation of [first,last). +/// Returns false if no further permutations can be created. +/// \ingroup GeneratorAlgorithms +template <typename BidirectionalIterator> +inline bool prev_permutation (BidirectionalIterator first, BidirectionalIterator last) +{ + typedef typename iterator_traits<BidirectionalIterator>::value_type value_type; + return (prev_permutation (first, last, less<value_type>())); +} + +/// \brief Returns iterator to the max element in [first,last) +/// \ingroup SearchingAlgorithms +template <typename ForwardIterator> +inline ForwardIterator max_element (ForwardIterator first, ForwardIterator last) +{ + typedef typename iterator_traits<ForwardIterator>::value_type value_type; + return (max_element (first, last, less<value_type>())); +} + +/// \brief Returns iterator to the min element in [first,last) +/// \ingroup SearchingAlgorithms +template <typename ForwardIterator> +inline ForwardIterator min_element (ForwardIterator first, ForwardIterator last) +{ + typedef typename iterator_traits<ForwardIterator>::value_type value_type; + return (min_element (first, last, less<value_type>())); +} + +/// \brief Makes [first,middle) a part of the sorted array. +/// Contents of [middle,last) is undefined. This implementation just calls stable_sort. +/// \ingroup SortingAlgorithms +template <typename RandomAccessIterator> +inline void partial_sort (RandomAccessIterator first, RandomAccessIterator middle, RandomAccessIterator last) +{ + typedef typename iterator_traits<RandomAccessIterator>::value_type value_type; + partial_sort (first, middle, last, less<value_type>()); +} + +/// \brief Puts \p nth element into its sorted position. +/// In this implementation, the entire array is sorted. I can't think of any +/// use for it where the time gained would be useful. +/// \ingroup SortingAlgorithms +/// \ingroup SearchingAlgorithms +/// +template <typename RandomAccessIterator> +inline void nth_element (RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last) +{ + partial_sort (first, nth, last); +} + +/// \brief Like partial_sort, but outputs to [result_first,result_last) +/// \ingroup SortingAlgorithms +template <typename InputIterator, typename RandomAccessIterator> +inline RandomAccessIterator partial_sort_copy (InputIterator first, InputIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last) +{ + typedef typename iterator_traits<InputIterator>::value_type value_type; + return (partial_sort_copy (first, last, result_first, result_last, less<value_type>())); +} + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/ualgobase.h @@ -0,0 +1,321 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UALGOBASE_H_683A0BE77546133C4CE0E3622CFAA2EB +#define UALGOBASE_H_683A0BE77546133C4CE0E3622CFAA2EB + +#include "uutility.h" +#include <string.h> + +namespace ustl { + +/// Assigns the contents of a to b and the contents of b to a. +/// This is used as a primitive operation by many other algorithms. +/// \ingroup SwapAlgorithms +/// +template <typename Assignable> +inline void swap (Assignable& a, Assignable& b) +{ + Assignable tmp = a; + a = b; + b = tmp; +} + +/// Equivalent to swap (*a, *b) +/// \ingroup SwapAlgorithms +/// +template <typename Iterator> +inline void iter_swap (Iterator a, Iterator b) +{ + swap (*a, *b); +} + +/// Copy copies elements from the range [first, last) to the range +/// [result, result + (last - first)). That is, it performs the assignments +/// *result = *first, *(result + 1) = *(first + 1), and so on. [1] Generally, +/// for every integer n from 0 to last - first, copy performs the assignment +/// *(result + n) = *(first + n). Assignments are performed in forward order, +/// i.e. in order of increasing n. +/// \ingroup MutatingAlgorithms +/// +template <typename InputIterator, typename OutputIterator> +inline OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result) +{ + for (; first != last; ++result, ++first) + *result = *first; + return (result); +} + +/// Copy_n copies elements from the range [first, first + n) to the range +/// [result, result + n). That is, it performs the assignments +/// *result = *first, *(result + 1) = *(first + 1), and so on. Generally, +/// for every integer i from 0 up to (but not including) n, copy_n performs +/// the assignment *(result + i) = *(first + i). Assignments are performed +/// in forward order, i.e. in order of increasing n. +/// \ingroup MutatingAlgorithms +/// +template <typename InputIterator, typename OutputIterator> +inline OutputIterator copy_n (InputIterator first, size_t count, OutputIterator result) +{ + for (; count; --count, ++result, ++first) + *result = *first; + return (result); +} + +/// \brief Copy copies elements from the range (last, first] to result. +/// \ingroup MutatingAlgorithms +/// Copies elements starting at last, decrementing both last and result. +/// +template <typename InputIterator, typename OutputIterator> +inline OutputIterator copy_backward (InputIterator first, InputIterator last, OutputIterator result) +{ + while (first != last) + *--result = *--last; + return (result); +} + +/// For_each applies the function object f to each element in the range +/// [first, last); f's return value, if any, is ignored. Applications are +/// performed in forward order, i.e. from first to last. For_each returns +/// the function object after it has been applied to each element. +/// \ingroup MutatingAlgorithms +/// +template <typename InputIterator, typename UnaryFunction> +inline UnaryFunction for_each (InputIterator first, InputIterator last, UnaryFunction f) +{ + for (; first != last; ++first) + f (*first); + return (f); +} + +/// Fill assigns the value value to every element in the range [first, last). +/// That is, for every iterator i in [first, last), +/// it performs the assignment *i = value. +/// \ingroup GeneratorAlgorithms +/// +template <typename ForwardIterator, typename T> +inline void fill (ForwardIterator first, ForwardIterator last, const T& value) +{ + for (; first != last; ++first) + *first = value; +} + +/// Fill_n assigns the value value to every element in the range +/// [first, first+count). That is, for every iterator i in [first, first+count), +/// it performs the assignment *i = value. The return value is first + count. +/// \ingroup GeneratorAlgorithms +/// +template <typename OutputIterator, typename T> +inline OutputIterator fill_n (OutputIterator first, size_t count, const T& value) +{ + for (; count; --count, ++first) + *first = value; + return (first); +} + +#if CPU_HAS_MMX +extern "C" void copy_n_fast (const void* src, size_t count, void* dest) throw(); +#else +inline void copy_n_fast (const void* src, size_t count, void* dest) throw() + { memcpy (dest, src, count); } +#endif +#if __i386__ || __x86_64__ +extern "C" void copy_backward_fast (const void* first, const void* last, void* result) throw(); +#else +inline void copy_backward_fast (const void* first, const void* last, void* result) throw() +{ + const size_t nBytes (distance (first, last)); + memmove (advance (result, -nBytes), first, nBytes); +} +#endif +extern "C" void fill_n8_fast (uint8_t* dest, size_t count, uint8_t v) throw(); +extern "C" void fill_n16_fast (uint16_t* dest, size_t count, uint16_t v) throw(); +extern "C" void fill_n32_fast (uint32_t* dest, size_t count, uint32_t v) throw(); +extern "C" void rotate_fast (void* first, void* middle, void* last) throw(); + +#if __GNUC__ >= 4 +/// \brief Computes the number of 1 bits in a number. +/// \ingroup ConditionAlgorithms +inline size_t popcount (uint32_t v) { return (__builtin_popcount (v)); } +#if HAVE_INT64_T +inline size_t popcount (uint64_t v) { return (__builtin_popcountll (v)); } +#endif +#else +size_t popcount (uint32_t v); +#if HAVE_INT64_T +size_t popcount (uint64_t v); +#endif // HAVE_INT64_T +#endif // __GNUC__ + +//---------------------------------------------------------------------- +// Optimized versions for standard types +//---------------------------------------------------------------------- + +#if WANT_UNROLLED_COPY + +template <typename T> +inline T* unrolled_copy (const T* first, size_t count, T* result) +{ + copy_n_fast (first, count * sizeof(T), result); + return (advance (result, count)); +} + +template <> +inline uint8_t* copy_backward (const uint8_t* first, const uint8_t* last, uint8_t* result) +{ + copy_backward_fast (first, last, result); + return (result); +} + +template <typename T> +inline T* unrolled_fill (T* result, size_t count, T value) +{ + for (; count; --count, ++result) + *result = value; + return (result); +} +template <> inline uint8_t* unrolled_fill (uint8_t* result, size_t count, uint8_t value) + { fill_n8_fast (result, count, value); return (advance (result, count)); } +template <> inline uint16_t* unrolled_fill (uint16_t* result, size_t count, uint16_t value) + { fill_n16_fast (result, count, value); return (advance (result, count)); } +template <> inline uint32_t* unrolled_fill (uint32_t* result, size_t count, uint32_t value) + { fill_n32_fast (result, count, value); return (advance (result, count)); } +template <> inline float* unrolled_fill (float* result, size_t count, float value) + { fill_n32_fast ((uint32_t*) result, count, *noalias_cast<uint32_t*>(&value)); return (advance (result, count)); } + +#if CPU_HAS_MMX +#define UNROLLED_COPY_SPECIALIZATION(type) \ +template <> inline type* copy (const type* first, const type* last, type* result) \ +{ return (unrolled_copy (first, distance (first, last), result)); } \ +template <> inline type* copy_n (const type* first, size_t count, type* result) \ +{ return (unrolled_copy (first, count, result)); } +#define UNROLLED_FILL_SPECIALIZATION(type) \ +template <> inline void fill (type* first, type* last, const type& value) \ +{ unrolled_fill (first, distance (first, last), value); } \ +template <> inline type* fill_n (type* first, size_t count, const type& value) \ +{ return (unrolled_fill (first, count, value)); } +UNROLLED_COPY_SPECIALIZATION(uint8_t) +UNROLLED_FILL_SPECIALIZATION(uint8_t) +UNROLLED_COPY_SPECIALIZATION(uint16_t) +UNROLLED_FILL_SPECIALIZATION(uint16_t) +UNROLLED_COPY_SPECIALIZATION(uint32_t) +UNROLLED_FILL_SPECIALIZATION(uint32_t) +UNROLLED_COPY_SPECIALIZATION(float) +UNROLLED_FILL_SPECIALIZATION(float) +#undef UNROLLED_FILL_SPECIALIZATION +#undef UNROLLED_COPY_SPECIALIZATION +#endif // WANT_UNROLLED_COPY +#endif // CPU_HAS_MMX + +// Specializations for void* and char*, aliasing the above optimized versions. +// +// All these need duplication with const and non-const arguments, since +// otherwise the compiler will default to the unoptimized version for +// pointers not const in the caller's context, such as local variables. +// These are all inline, but they sure slow down compilation... :( +// +#define COPY_ALIAS_FUNC(ctype, type, alias_type) \ +template <> inline type* copy (ctype* first, ctype* last, type* result) \ +{ return ((type*) copy ((const alias_type*) first, (const alias_type*) last, (alias_type*) result)); } +#if WANT_UNROLLED_COPY +#if HAVE_THREE_CHAR_TYPES +COPY_ALIAS_FUNC(const char, char, uint8_t) +COPY_ALIAS_FUNC(char, char, uint8_t) +#endif +COPY_ALIAS_FUNC(const int8_t, int8_t, uint8_t) +COPY_ALIAS_FUNC(int8_t, int8_t, uint8_t) +COPY_ALIAS_FUNC(uint8_t, uint8_t, uint8_t) +COPY_ALIAS_FUNC(const int16_t, int16_t, uint16_t) +COPY_ALIAS_FUNC(int16_t, int16_t, uint16_t) +COPY_ALIAS_FUNC(uint16_t, uint16_t, uint16_t) +#if CPU_HAS_MMX || (SIZE_OF_LONG > 4) +COPY_ALIAS_FUNC(const int32_t, int32_t, uint32_t) +COPY_ALIAS_FUNC(int32_t, int32_t, uint32_t) +COPY_ALIAS_FUNC(uint32_t, uint32_t, uint32_t) +#endif +#endif +COPY_ALIAS_FUNC(const void, void, uint8_t) +COPY_ALIAS_FUNC(void, void, uint8_t) +#undef COPY_ALIAS_FUNC +#define COPY_BACKWARD_ALIAS_FUNC(ctype, type, alias_type) \ +template <> inline type* copy_backward (ctype* first, ctype* last, type* result) \ +{ return ((type*) copy_backward ((const alias_type*) first, (const alias_type*) last, (alias_type*) result)); } +#if WANT_UNROLLED_COPY +#if HAVE_THREE_CHAR_TYPES +COPY_BACKWARD_ALIAS_FUNC(char, char, uint8_t) +#endif +COPY_BACKWARD_ALIAS_FUNC(uint8_t, uint8_t, uint8_t) +COPY_BACKWARD_ALIAS_FUNC(int8_t, int8_t, uint8_t) +COPY_BACKWARD_ALIAS_FUNC(uint16_t, uint16_t, uint8_t) +COPY_BACKWARD_ALIAS_FUNC(const uint16_t, uint16_t, uint8_t) +COPY_BACKWARD_ALIAS_FUNC(int16_t, int16_t, uint8_t) +COPY_BACKWARD_ALIAS_FUNC(const int16_t, int16_t, uint8_t) +#endif +COPY_BACKWARD_ALIAS_FUNC(void, void, uint8_t) +COPY_BACKWARD_ALIAS_FUNC(const void, void, uint8_t) +#undef COPY_BACKWARD_ALIAS_FUNC +#define FILL_ALIAS_FUNC(type, alias_type, v_type) \ +template <> inline void fill (type* first, type* last, const v_type& value) \ +{ fill ((alias_type*) first, (alias_type*) last, (const alias_type&) value); } +FILL_ALIAS_FUNC(void, uint8_t, char) +FILL_ALIAS_FUNC(void, uint8_t, uint8_t) +#if WANT_UNROLLED_COPY +#if HAVE_THREE_CHAR_TYPES +FILL_ALIAS_FUNC(char, uint8_t, char) +FILL_ALIAS_FUNC(char, uint8_t, uint8_t) +#endif +FILL_ALIAS_FUNC(int8_t, uint8_t, int8_t) +FILL_ALIAS_FUNC(int16_t, uint16_t, int16_t) +#if CPU_HAS_MMX || (SIZE_OF_LONG > 4) +FILL_ALIAS_FUNC(int32_t, uint32_t, int32_t) +#endif +#endif +#undef FILL_ALIAS_FUNC +#define COPY_N_ALIAS_FUNC(ctype, type, alias_type) \ +template <> inline type* copy_n (ctype* first, size_t count, type* result) \ +{ return ((type*) copy_n ((const alias_type*) first, count, (alias_type*) result)); } +COPY_N_ALIAS_FUNC(const void, void, uint8_t) +COPY_N_ALIAS_FUNC(void, void, uint8_t) +#if WANT_UNROLLED_COPY +#if HAVE_THREE_CHAR_TYPES +COPY_N_ALIAS_FUNC(const char, char, uint8_t) +COPY_N_ALIAS_FUNC(char, char, uint8_t) +#endif +COPY_N_ALIAS_FUNC(int8_t, int8_t, uint8_t) +COPY_N_ALIAS_FUNC(uint8_t, uint8_t, uint8_t) +COPY_N_ALIAS_FUNC(const int8_t, int8_t, uint8_t) +COPY_N_ALIAS_FUNC(int16_t, int16_t, uint16_t) +COPY_N_ALIAS_FUNC(uint16_t, uint16_t, uint16_t) +COPY_N_ALIAS_FUNC(const int16_t, int16_t, uint16_t) +#if CPU_HAS_MMX || (SIZE_OF_LONG > 4) +COPY_N_ALIAS_FUNC(int32_t, int32_t, uint32_t) +COPY_N_ALIAS_FUNC(uint32_t, uint32_t, uint32_t) +COPY_N_ALIAS_FUNC(const int32_t, int32_t, uint32_t) +#endif +#endif +#undef COPY_N_ALIAS_FUNC +#define FILL_N_ALIAS_FUNC(type, alias_type, v_type) \ +template <> inline type* fill_n (type* first, size_t n, const v_type& value) \ +{ return ((type*) fill_n ((alias_type*) first, n, (const alias_type&) value)); } +FILL_N_ALIAS_FUNC(void, uint8_t, char) +FILL_N_ALIAS_FUNC(void, uint8_t, uint8_t) +#if WANT_UNROLLED_COPY +#if HAVE_THREE_CHAR_TYPES +FILL_N_ALIAS_FUNC(char, uint8_t, char) +FILL_N_ALIAS_FUNC(char, uint8_t, uint8_t) +#endif +FILL_N_ALIAS_FUNC(int8_t, uint8_t, int8_t) +FILL_N_ALIAS_FUNC(int16_t, uint16_t, int16_t) +#if CPU_HAS_MMX || (SIZE_OF_LONG > 4) +FILL_N_ALIAS_FUNC(int32_t, uint32_t, int32_t) +#endif +#endif +#undef FILL_N_ALIAS_FUNC + +extern const char _FmtPrtChr[2][8]; + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/ubitset.h @@ -0,0 +1,129 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UBITSET_H_7B6450EC1400CBA45DCE0127739F82EE +#define UBITSET_H_7B6450EC1400CBA45DCE0127739F82EE + +#include "ustring.h" +#include "ufunction.h" + +namespace ustl { + +typedef uint32_t bitset_value_type; + +void convert_to_bitstring (const bitset_value_type* v, size_t n, string& buf); +void convert_from_bitstring (const string& buf, bitset_value_type* v, size_t n); + +/// \class bitset ubitset.h ustl.h +/// \ingroup Sequences +/// +/// \brief bitset is a fixed-size block of memory with addressable bits. +/// +/// Normally used for state flags; allows setting and unsetting of individual +/// bits as well as bitwise operations on the entire set. The interface is +/// most like that of unsigned integers, and is intended to be used as such. +/// If you were using begin() and end() functions in STL's bitset, you would +/// not be able to do the same thing here, because those functions return +/// host type iterators, not bits. +/// +template <size_t Size> +class bitset { +public: + typedef bitset_value_type value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef pointer iterator; + typedef const_pointer const_iterator; + typedef size_t difference_type; + typedef size_t size_type; +private: + static const size_t s_WordBits = BitsInType (value_type); + static const size_t s_nWords = Size / s_WordBits + ((Size % s_WordBits) != 0); + static const size_t s_nBits = s_nWords * s_WordBits; +private: + inline value_type& BitRef (uoff_t n) { assert (n < Size); return (m_Bits [n / s_WordBits]); } + inline value_type BitRef (uoff_t n) const { assert (n < Size); return (m_Bits [n / s_WordBits]); } + inline value_type Mask (uoff_t n) const { assert (n < Size); return (1 << (n % s_WordBits)); } +public: + inline bitset (value_type v = 0) { fill_n (m_Bits, s_nWords, 0); m_Bits[0] = v; } + inline bitset (const string& buf) { convert_from_bitstring (buf, m_Bits, s_nWords); } + inline void flip (uoff_t n) { BitRef(n) ^= Mask(n); } + inline void reset (void) { fill_n (m_Bits, s_nWords, 0); } + inline void clear (void) { fill_n (m_Bits, s_nWords, 0); } + inline void set (void) { fill_n (m_Bits, s_nWords, -1); } + inline bitset operator~ (void) const { bitset rv (*this); rv.flip(); return (rv); } + inline size_type size (void) const { return (Size); } + inline size_type capacity (void) const { return (s_nBits); } + inline bool test (uoff_t n) const { return (BitRef(n) & Mask(n)); } + inline bool operator[] (uoff_t n) const { return (test(n)); } + inline const_iterator begin (void) const { return (m_Bits); } + inline iterator begin (void) { return (m_Bits); } + inline const_iterator end (void) const { return (m_Bits + s_nWords); } + inline iterator end (void) { return (m_Bits + s_nWords); } + /// Returns the value_type with the equivalent bits. If size() > 1, you'll get only the first BitsInType(value_type) bits. + inline value_type to_value (void) const { return (m_Bits[0]); } + /// Flips all the bits in the set. + inline void flip (void) { transform (begin(), end(), begin(), bitwise_not<value_type>()); } + /// Sets or clears bit \p n. + inline void set (uoff_t n, bool val = true) + { + value_type& br (BitRef (n)); + const value_type mask (Mask (n)); + const value_type bOn (br | mask), bOff (br & ~mask); + br = val ? bOn : bOff; + } + // Sets the value of the bitrange \p first through \p last to the equivalent number of bits from \p v. + inline void set (uoff_t first, uoff_t DebugArg(last), value_type v) + { + assert (size_t (distance (first, last)) <= s_WordBits && "Bit ranges must be 32 bits or smaller"); + assert (first / s_WordBits == last / s_WordBits && "Bit ranges can not cross dword (4 byte) boundary"); + assert ((v & BitMask(value_type,distance(first,last))) == v && "The value is too large to fit in the given bit range"); + BitRef(first) |= v << (first % s_WordBits); + } + /// Clears the bit \p n. + inline void reset (uoff_t n) { set (n, false); } + /// Returns a string with bits MSB "001101001..." LSB. + inline string to_string (void) const + { + string rv (Size, '0'); + convert_to_bitstring (m_Bits, s_nWords, rv); + return (rv); + } + inline value_type at (uoff_t n) const { return (test(n)); } + /// Returns the value in bits \p first through \p last. + inline value_type at (uoff_t first, uoff_t last) const + { + assert (size_t (distance (first, last)) <= s_WordBits && "Bit ranges must be 32 bits or smaller"); + assert (first / s_WordBits == last / s_WordBits && "Bit ranges can not cross dword (4 byte) boundary"); + return ((BitRef(first) >> (first % s_WordBits)) & BitMask(value_type,distance(first, last))); + } + inline bool any (void) const { value_type sum = 0; foreach (const_iterator, i, *this) sum |= *i; return (sum); } + inline bool none (void) const { return (!any()); } + inline size_t count (void) const { size_t sum = 0; foreach (const_iterator, i, *this) sum += popcount(*i); return (sum); } + inline bool operator== (const bitset<Size>& v) const + { return (s_nWords == 1 ? (m_Bits[0] == v.m_Bits[0]) : equal (begin(), end(), v.begin())); } + inline const bitset operator& (const bitset<Size>& v) + { bitset<Size> result; transform (begin(), end(), v.begin(), result.begin(), bitwise_and<value_type>()); return (result); } + inline const bitset operator| (const bitset<Size>& v) + { bitset<Size> result; transform (begin(), end(), v.begin(), result.begin(), bitwise_or<value_type>()); return (result); } + inline const bitset operator^ (const bitset<Size>& v) + { bitset<Size> result; transform (begin(), end(), v.begin(), result.begin(), bitwise_xor<value_type>()); return (result); } + inline const bitset& operator&= (const bitset<Size>& v) + { transform (begin(), end(), v.begin(), begin(), bitwise_and<value_type>()); return (*this); } + inline const bitset& operator|= (const bitset<Size>& v) + { transform (begin(), end(), v.begin(), begin(), bitwise_or<value_type>()); return (*this); } + inline const bitset& operator^= (const bitset<Size>& v) + { transform (begin(), end(), v.begin(), begin(), bitwise_xor<value_type>()); return (*this); } + inline void read (istream& is) { nr_container_read (is, *this); } + inline void write (ostream& os) const { nr_container_write (os, *this); } + inline void text_write (ostringstream& os) const { os << to_string(); } + inline size_t stream_size (void) const { return (sizeof(m_Bits)); } +private: + value_type m_Bits [s_nWords]; +}; + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/uctralgo.h @@ -0,0 +1,470 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UCTRALGO_H_0D1AEDFA74B09791489FE25B1EC644B0 +#define UCTRALGO_H_0D1AEDFA74B09791489FE25B1EC644B0 + +namespace ustl { + +/// Copy copies elements from the range [first, last) to the range +/// [result, result + (last - first)). That is, it performs the assignments +/// *result = *first, *(result + 1) = *(first + 1), and so on. [1] Generally, +/// for every integer n from 0 to last - first, copy performs the assignment +/// *(result + n) = *(first + n). Assignments are performed in forward order, +/// i.e. in order of increasing n. +/// \ingroup MutatingAlgorithms +/// +template <typename Container, typename OutputIterator> +inline OutputIterator copy (const Container& ctr, OutputIterator result) +{ + return (copy (ctr.begin(), ctr.end(), result)); +} + +/// Copy_if copies elements from the range [first, last) to the range +/// [result, result + (last - first)) if pred(*i) returns true. +/// \ingroup MutatingAlgorithms +/// +template <typename Container, typename OutputIterator, typename Predicate> +inline OutputIterator copy_if (Container& ctr, OutputIterator result, Predicate pred) +{ + return (copy_if (ctr.begin(), ctr.end(), result, pred)); +} + +/// For_each applies the function object f to each element in the range +/// [first, last); f's return value, if any, is ignored. Applications are +/// performed in forward order, i.e. from first to last. For_each returns +/// the function object after it has been applied to each element. +/// \ingroup MutatingAlgorithms +/// +template <typename Container, typename UnaryFunction> +inline UnaryFunction for_each (Container& ctr, UnaryFunction f) +{ + return (for_each (ctr.begin(), ctr.end(), f)); +} + +/// For_each applies the function object f to each element in the range +/// [first, last); f's return value, if any, is ignored. Applications are +/// performed in forward order, i.e. from first to last. For_each returns +/// the function object after it has been applied to each element. +/// \ingroup MutatingAlgorithms +/// +template <typename Container, typename UnaryFunction> +inline UnaryFunction for_each (const Container& ctr, UnaryFunction f) +{ + return (for_each (ctr.begin(), ctr.end(), f)); +} + +/// Returns the first iterator i in the range [first, last) such that +/// *i == value. Returns last if no such iterator exists. +/// \ingroup SearchingAlgorithms +/// +template <typename Container, typename EqualityComparable> +inline typename Container::const_iterator find (const Container& ctr, const EqualityComparable& value) +{ + return (find (ctr.begin(), ctr.end(), value)); +} +template <typename Container, typename EqualityComparable> +inline typename Container::iterator find (Container& ctr, const EqualityComparable& value) +{ + return (find (ctr.begin(), ctr.end(), value)); +} + +/// Returns the first iterator i in the range [first, last) such that +/// pred(*i) is true. Returns last if no such iterator exists. +/// \ingroup SearchingAlgorithms +/// +template <typename Container, typename Predicate> +inline typename Container::const_iterator find_if (const Container& ctr, Predicate pred) +{ + return (find_if (ctr.begin(), ctr.end(), pred)); +} +template <typename Container, typename Predicate> +inline typename Container::iterator find_if (Container& ctr, Predicate pred) +{ + return (find_if (ctr.begin(), ctr.end(), pred)); +} + +/// Count finds the number of elements in [first, last) that are equal +/// to value. More precisely, the first version of count returns the +/// number of iterators i in [first, last) such that *i == value. +/// \ingroup ConditionAlgorithms +/// +template <typename Container, typename EqualityComparable> +inline size_t count (const Container& ctr, const EqualityComparable& value) +{ + return (count (ctr.begin(), ctr.end(), value)); +} + +/// Count_if finds the number of elements in [first, last) that satisfy the +/// predicate pred. More precisely, the first version of count_if returns the +/// number of iterators i in [first, last) such that pred(*i) is true. +/// \ingroup ConditionAlgorithms +/// +template <typename Container, typename Predicate> +inline size_t count_if (const Container& ctr, Predicate pred) +{ + return (count_if (ctr.begin(), ctr.end(), pred)); +} + +/// The first version of transform performs the operation op(*i) for each +/// iterator i in the range [first, last), and assigns the result of that +/// operation to *o, where o is the corresponding output iterator. That is, +/// for each n such that 0 <= n < last - first, it performs the assignment +/// *(result + n) = op(*(first + n)). +/// The return value is result + (last - first). +/// \ingroup MutatingAlgorithms +/// +template <typename Container, typename UnaryFunction> +inline void transform (Container& ctr, UnaryFunction op) +{ + transform (ctr.begin(), ctr.end(), ctr.begin(), op); +} + +/// The first version of transform performs the operation op(*i) for each +/// iterator i in the range [first, last), and assigns the result of that +/// operation to *o, where o is the corresponding output iterator. That is, +/// for each n such that 0 <= n < last - first, it performs the assignment +/// *(result + n) = op(*(first + n)). +/// The return value is result + (last - first). +/// \ingroup MutatingAlgorithms +/// +template <typename Container, typename OutputIterator, typename UnaryFunction> +inline OutputIterator transform (Container& ctr, OutputIterator result, UnaryFunction op) +{ + return (transform (ctr.begin(), ctr.end(), result, op)); +} + +/// The second version of transform is very similar, except that it uses a +/// Binary Function instead of a Unary Function: it performs the operation +/// op(*i1, *i2) for each iterator i1 in the range [first1, last1) and assigns +/// the result to *o, where i2 is the corresponding iterator in the second +/// input range and where o is the corresponding output iterator. That is, +/// for each n such that 0 <= n < last1 - first1, it performs the assignment +/// *(result + n) = op(*(first1 + n), *(first2 + n). +/// The return value is result + (last1 - first1). +/// \ingroup MutatingAlgorithms +/// +template <typename Container, typename InputIterator, typename OutputIterator, typename BinaryFunction> +inline OutputIterator transform (Container& ctr, InputIterator first, OutputIterator result, BinaryFunction op) +{ + return (transform (ctr.begin(), ctr.end(), first, result, op)); +} + +/// Replace replaces every element in the range [first, last) equal to +/// old_value with new_value. That is: for every iterator i, +/// if *i == old_value then it performs the assignment *i = new_value. +/// \ingroup MutatingAlgorithms +/// +template <typename Container, typename T> +inline void replace (Container& ctr, const T& old_value, const T& new_value) +{ + replace (ctr.begin(), ctr.end(), old_value, new_value); +} + +/// Replace_if replaces every element in the range [first, last) for which +/// pred returns true with new_value. That is: for every iterator i, if +/// pred(*i) is true then it performs the assignment *i = new_value. +/// \ingroup MutatingAlgorithms +/// +template <typename Container, typename Predicate, typename T> +inline void replace_if (Container& ctr, Predicate pred, const T& new_value) +{ + replace_if (ctr.begin(), ctr.end(), pred, new_value); +} + +/// Replace_copy copies elements from the range [first, last) to the range +/// [result, result + (last-first)), except that any element equal to old_value +/// is not copied; new_value is copied instead. More precisely, for every +/// integer n such that 0 <= n < last-first, replace_copy performs the +/// assignment *(result+n) = new_value if *(first+n) == old_value, and +/// *(result+n) = *(first+n) otherwise. +/// \ingroup MutatingAlgorithms +/// +template <typename Container, typename OutputIterator, typename T> +inline OutputIterator replace_copy (const Container& ctr, OutputIterator result, const T& old_value, const T& new_value) +{ + return (replace_copy (ctr.begin(), ctr.end(), result, old_value, new_value)); +} + +/// Replace_copy_if copies elements from the range [first, last) to the range +/// [result, result + (last-first)), except that any element for which pred is +/// true is not copied; new_value is copied instead. More precisely, for every +/// integer n such that 0 <= n < last-first, replace_copy_if performs the +/// assignment *(result+n) = new_value if pred(*(first+n)), +/// and *(result+n) = *(first+n) otherwise. +/// \ingroup MutatingAlgorithms +/// +template <typename Container, typename OutputIterator, typename Predicate, typename T> +inline OutputIterator replace_copy_if (const Container& ctr, OutputIterator result, Predicate pred, const T& new_value) +{ + return (replace_copy_if (ctr.begin(), ctr.end(), result, pred, new_value)); +} + +/// Fill assigns the value value to every element in the range [first, last). +/// That is, for every iterator i in [first, last), +/// it performs the assignment *i = value. +/// \ingroup GeneratorAlgorithms +/// +template <typename Container, typename T> +inline void fill (Container& ctr, const T& value) +{ + fill (ctr.begin(), ctr.end(), value); +} + +/// Generate assigns the result of invoking gen, a function object that +/// takes no arguments, to each element in the range [first, last). +/// \ingroup GeneratorAlgorithms +/// +template <typename Container, typename Generator> +inline void generate (Container& ctr, Generator gen) +{ + generate (ctr.begin(), ctr.end(), gen); +} + +/// Randomly permute the elements of the container. +/// \ingroup GeneratorAlgorithms +/// +template <typename Container> +inline void random_shuffle (Container& ctr) +{ + random_shuffle (ctr.begin(), ctr.end()); +} + +/// Remove_copy copies elements that are not equal to value from the range +/// [first, last) to a range beginning at result. The return value is the +/// end of the resulting range. This operation is stable, meaning that the +/// relative order of the elements that are copied is the same as in the +/// range [first, last). +/// \ingroup MutatingAlgorithms +/// +template <typename Container, typename OutputIterator, typename T> +inline OutputIterator remove_copy (const Container& ctr, OutputIterator result, const T& value) +{ + return (remove_copy (ctr.begin(), ctr.end(), result, value)); +} + +/// Remove_copy_if copies elements from the range [first, last) to a range +/// beginning at result, except that elements for which pred is true are not +/// copied. The return value is the end of the resulting range. This operation +/// is stable, meaning that the relative order of the elements that are copied +/// is the same as in the range [first, last). +/// \ingroup MutatingAlgorithms +/// +template <typename Container, typename OutputIterator, typename Predicate> +inline OutputIterator remove_copy_if (const Container& ctr, OutputIterator result, Predicate pred) +{ + return (remove_copy_if (ctr.begin(), ctr.end(), result, pred)); +} + +/// Remove removes from the range [first, last) all elements that are equal to +/// value. That is, remove returns an iterator new_last such that the range +/// [first, new_last) contains no elements equal to value. Remove is stable, +/// meaning that the relative order of elements that are not equal to value is +/// unchanged. +/// \ingroup MutatingAlgorithms +/// +template <typename Container, typename T> +inline void remove (Container& ctr, const T& value) +{ + ctr.erase (remove_copy (ctr.begin(), ctr.end(), ctr.begin(), value), ctr.end()); +} + +/// Remove removes from the range [first, last) all elements that have an iterator +/// in range [rfirst, rlast). The range is assumed to be sorted. That is, remove +/// returns an iterator new_last such that the range [first, new_last) contains +/// no elements whose iterators are in [rfirst, rlast). Remove is stable, +/// meaning that the relative order of elements that are not equal to value is +/// unchanged. This version of the algorithm is a uSTL extension. +/// \ingroup MutatingAlgorithms +/// +template <typename Container, typename ForwardIterator> +inline void remove (Container& ctr, ForwardIterator rfirst, ForwardIterator rlast) +{ + ctr.erase (remove_copy (ctr.begin(), ctr.end(), ctr.begin(), rfirst, rlast), ctr.end()); +} + +/// Remove_if removes from the range [first, last) every element x such that +/// pred(x) is true. That is, remove_if returns an iterator new_last such that +/// the range [first, new_last) contains no elements for which pred is true. +/// The iterators in the range [new_last, last) are all still dereferenceable, +/// but the elements that they point to are unspecified. Remove_if is stable, +/// meaning that the relative order of elements that are not removed is +/// unchanged. +/// \ingroup MutatingAlgorithms +/// +template <typename Container, typename Predicate> +inline void remove_if (Container& ctr, Predicate pred) +{ + ctr.erase (remove_copy_if (ctr.begin(), ctr.end(), ctr.begin(), pred), ctr.end()); +} + +/// Unique_copy copies elements from the range [first, last) to a range +/// beginning with result, except that in a consecutive group of duplicate +/// elements only the first one is copied. The return value is the end of +/// the range to which the elements are copied. This behavior is similar +/// to the Unix filter uniq. +/// \ingroup MutatingAlgorithms +/// +template <typename Container, typename OutputIterator> +inline OutputIterator unique_copy (const Container& ctr, OutputIterator result) +{ + return (unique_copy (ctr.begin(), ctr.end(), result)); +} + +/// Every time a consecutive group of duplicate elements appears in the range +/// [first, last), the algorithm unique removes all but the first element. +/// That is, unique returns an iterator new_last such that the range [first, +/// new_last) contains no two consecutive elements that are duplicates. +/// The iterators in the range [new_last, last) are all still dereferenceable, +/// but the elements that they point to are unspecified. Unique is stable, +/// meaning that the relative order of elements that are not removed is +/// unchanged. +/// \ingroup MutatingAlgorithms +/// +template <typename Container> +inline void unique (Container& ctr) +{ + ctr.erase (unique_copy (ctr.begin(), ctr.end(), ctr.begin()), ctr.end()); +} + +/// Every time a consecutive group of duplicate elements appears in the range +/// [first, last), the algorithm unique removes all but the first element. +/// That is, unique returns an iterator new_last such that the range [first, +/// new_last) contains no two consecutive elements that are duplicates. +/// The iterators in the range [new_last, last) are all still dereferenceable, +/// but the elements that they point to are unspecified. Unique is stable, +/// meaning that the relative order of elements that are not removed is +/// unchanged. +/// \ingroup MutatingAlgorithms +/// +template <typename Container, typename BinaryPredicate> +inline void unique (Container& ctr, BinaryPredicate binary_pred) +{ + ctr.erase (unique_copy (ctr.begin(), ctr.end(), ctr.begin(), binary_pred), ctr.end()); +} + +/// Reverse reverses a range. +/// That is: for every i such that 0 <= i <= (last - first) / 2), +/// it exchanges *(first + i) and *(last - (i + 1)). +/// \ingroup MutatingAlgorithms +/// +template <typename Container> +inline void reverse (Container& ctr) +{ + reverse (ctr.begin(), ctr.end()); +} + +/// Exchanges ranges [first, middle) and [middle, last) +/// \ingroup MutatingAlgorithms +/// +template <typename Container> +inline void rotate (Container& ctr, off_t offset) +{ + assert (size_t(offset > 0 ? offset : -offset) < ctr.size()); + if (offset > 0) + rotate (ctr.begin(), ctr.end() - offset, ctr.end()); + else + rotate (ctr.begin(), ctr.begin() - offset, ctr.end()); +} + +/// Returns the furthermost iterator i in [first, last) such that, +/// for every iterator j in [first, i), *j < value +/// Assumes the range is sorted. +/// \ingroup SearchingAlgorithms +/// +template <typename Container, typename LessThanComparable> +inline typename Container::const_iterator lower_bound (const Container& ctr, const LessThanComparable& value) +{ + return (lower_bound (ctr.begin(), ctr.end(), value)); +} +template <typename Container, typename LessThanComparable> +inline typename Container::iterator lower_bound (Container& ctr, const LessThanComparable& value) +{ + return (lower_bound (ctr.begin(), ctr.end(), value)); +} + +/// Returns the furthermost iterator i in [first,last) such that for +/// every iterator j in [first,i), value < *j is false. +/// \ingroup SearchingAlgorithms +/// +template <typename Container, typename LessThanComparable> +inline typename Container::const_iterator upper_bound (const Container& ctr, const LessThanComparable& value) +{ + return (upper_bound (ctr.begin(), ctr.end(), value)); +} +template <typename Container, typename LessThanComparable> +inline typename Container::iterator upper_bound (Container& ctr, const LessThanComparable& value) +{ + return (upper_bound (ctr.begin(), ctr.end(), value)); +} + +/// Performs a binary search for \p value. +/// Assumes the range is sorted. +/// \ingroup SearchingAlgorithms +/// +template <typename Container> +inline bool binary_search (const Container& ctr, const typename Container::value_type& value) +{ + return (binary_search (ctr.begin(), ctr.end(), value)); +} +template <typename Container> +inline bool binary_search (Container& ctr, const typename Container::value_type& value) +{ + return (binary_search (ctr.begin(), ctr.end(), value)); +} + +/// Returns pair<lower_bound,upper_bound> +/// \ingroup SearchingAlgorithms +/// +template <typename Container, typename LessThanComparable> +inline pair<typename Container::const_iterator,typename Container::const_iterator> equal_range (const Container& ctr, const LessThanComparable& value) +{ + return (equal_range (ctr.begin(), ctr.end(), value)); +} +template <typename Container, typename LessThanComparable> +inline pair<typename Container::iterator,typename Container::iterator> equal_range (Container& ctr, const LessThanComparable& value) +{ + return (equal_range (ctr.begin(), ctr.end(), value)); +} + +/// Sorts the container +/// \ingroup SortingAlgorithms +/// +template <typename Container> +inline void sort (Container& ctr) +{ + sort (ctr.begin(), ctr.end()); +} + +/// Sorts the container +/// \ingroup SortingAlgorithms +/// +template <typename Container, typename Compare> +inline void sort (Container& ctr, Compare comp) +{ + sort (ctr.begin(), ctr.end(), comp); +} + +/// Sorts the container +/// \ingroup SortingAlgorithms +/// +template <typename Container> +inline void stable_sort (Container& ctr) +{ + stable_sort (ctr.begin(), ctr.end()); +} + +/// Sorts the container +/// \ingroup SortingAlgorithms +/// +template <typename Container, typename Compare> +inline void stable_sort (Container& ctr, Compare comp) +{ + stable_sort (ctr.begin(), ctr.end(), comp); +} + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/uctrstrm.h @@ -0,0 +1,181 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. +// +/// \file uctrstrm.h +/// +/// \brief Serialization templates for standard containers. +/// Because containers are templates, a single operator>> is impossible. +/// Making virtual read/write is also impossible because not all containers +/// contain serializable elements. Therefore, use the macros in this file. + +#ifndef UCTRSTRM_H_75B2C3EA4980DDDC6B6DFFF767A3B7AC +#define UCTRSTRM_H_75B2C3EA4980DDDC6B6DFFF767A3B7AC + +#include "mistream.h" +#include "sostream.h" +#include "uiosfunc.h" +#include <typeinfo> + +namespace ustl { + +//---------------------------------------------------------------------- +// Macros for easily declaring a container streamable. +//---------------------------------------------------------------------- + +/// \brief Declares container template \p type streamable. +/// +/// Use TEMPLATE_TYPE and TEMPLATE_DECL macros to pass in templated +/// type with commas and the template declaration. +/// +#define STD_TEMPLATE_CTR_STREAMABLE(type, template_decl) \ + template_decl \ + inline istream& operator>> (istream& is, type& v) \ + { return (container_read (is, v)); } \ + template_decl \ + inline ostream& operator<< (ostream& os, const type& v) \ + { return (container_write (os, v)); } \ + template_decl \ + inline ostringstream& operator<< (ostringstream& os, const type& v) \ + { return (container_text_write (os, v)); } \ + template_decl \ + struct object_stream_size<type > { \ + inline size_t operator()(const type& v) const \ + { return (container_stream_size (v)); } \ + }; + +/// \brief Declares non-resizable container template \p type streamable. +#define STD_TEMPLATE_NR_CTR_STREAMABLE(type, template_decl) \ + template_decl \ + inline istream& operator>> (istream& is, type& v) \ + { return (nr_container_read (is, v)); } \ + template_decl \ + inline ostream& operator<< (ostream& os, const type& v) \ + { return (nr_container_write (os, v)); } \ + template_decl \ + inline ostringstream& operator<< (ostringstream& os, const type& v) \ + { return (container_text_write (os, v)); } \ + template_decl \ + struct object_stream_size<type > { \ + inline size_t operator()(const type& v) const \ + { return (nr_container_stream_size (v)); } \ + }; + +//---------------------------------------------------------------------- +// Fixed size container serialization. +//---------------------------------------------------------------------- + +/// Reads fixed size container \p v from stream \p is. +template <typename Container> +inline istream& nr_container_read (istream& is, Container& v) +{ + foreach (typename Container::iterator, i, v) + is >> *i; + return (is); +} + +/// Writes fixed size container \p v into stream \p os. +template <typename Container> +inline ostream& nr_container_write (ostream& os, const Container& v) +{ + foreach (typename Container::const_iterator, i, v) + os << *i; + return (os); +} + +/// Computes the stream size of a fixed size standard container. +template <typename Container> +inline size_t nr_container_stream_size (const Container& v) +{ + typedef typename Container::const_iterator vciter_t; + typedef typename iterator_traits<vciter_t>::value_type value_type; + if (!v.size()) + return (0); + size_t s = 0, dvs; + vciter_t i = v.begin(); + do { + dvs = stream_size_of(*i); + s += dvs; + } while (++i != v.end() && !__builtin_constant_p(dvs)); + if (__builtin_constant_p(dvs)) + s *= v.size(); + return (s); +} + +//---------------------------------------------------------------------- +// Resizable container serialization. +//---------------------------------------------------------------------- + +/// Reads container \p v from stream \p is. +template <typename Container> +istream& container_read (istream& is, Container& v) +{ + typedef typename Container::value_type value_type; + typedef typename Container::iterator iterator; + typedef typename Container::written_size_type written_size_type; + written_size_type n = 0; + is >> n; + const size_t expectedSize = n * stream_size_of(value_type()); + if (!is.verify_remaining ("read", USTL_TYPENAME(v), expectedSize)) + return (is); + if (alignof(NullValue<value_type>()) > alignof(n)) + is >> ios::talign<value_type>(); + v.resize (n); + nr_container_read (is, v); + is >> ios::talign<written_size_type>(); + return (is); +} + +/// Writes the vector to stream \p os. +template <typename Container> +ostream& container_write (ostream& os, const Container& v) +{ + typedef typename Container::value_type value_type; + typedef typename Container::written_size_type written_size_type; + const written_size_type sz (v.size()); + os << sz; + if (alignof(NullValue<value_type>()) > alignof(sz)) + os << ios::talign<value_type>(); + nr_container_write (os, v); + os << ios::talign<written_size_type>(); + return (os); +} + +/// Computes the stream size of a standard container. +template <typename Container> +size_t container_stream_size (const Container& v) +{ + typedef typename Container::value_type value_type; + typedef typename Container::written_size_type written_size_type; + const written_size_type sz (v.size()); + size_t sizeSize = stream_size_of (sz); + if (alignof(NullValue<value_type>()) > alignof(sz)) + sizeSize = Align (sizeSize, alignof(NullValue<value_type>())); + return (Align (sizeSize + nr_container_stream_size (v), alignof(sz))); +} + +/// \brief Writes element \p v into stream \p os as text. +/// Specialize to custom print elements. +template <typename T> +inline ostringstream& container_element_text_write (ostringstream& os, const T& v) +{ return (os << v); } + +/// Writes container \p v into stream \p os as text. +template <typename Container> +ostringstream& container_text_write (ostringstream& os, const Container& v) +{ + typename Container::const_iterator i = v.begin(); + os << '('; + while (i < v.end()) { + container_element_text_write (os, *i); + os << ",)"[++i == v.end()]; + } + return (os); +} + +//---------------------------------------------------------------------- + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/uexception.h @@ -0,0 +1,186 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UEXCEPTION_H_18DE3EF55C4F00673268F0D66546AF5D +#define UEXCEPTION_H_18DE3EF55C4F00673268F0D66546AF5D + +#include "utypes.h" +#ifndef WITHOUT_LIBSTDCPP + #include <exception> + #include <new> +#endif +#include "bktrace.h" + +#if WITHOUT_LIBSTDCPP +namespace std { +/// If you write a replacement terminate handler, it must be of this type. +typedef void (*terminate_handler) (void); +/// If you write a replacement unexpected handler, it must be of this type. +typedef void (*unexpected_handler) (void); +/// Takes a new handler function as an argument, returns the old function. +terminate_handler set_terminate (terminate_handler pHandler) throw(); +/// The runtime will call this function if exception handling must be +/// abandoned for any reason. It can also be called by the user. +void terminate (void) __attribute__ ((__noreturn__)); +/// Takes a new handler function as an argument, returns the old function. +unexpected_handler set_unexpected (unexpected_handler pHandler) throw(); +/// The runtime will call this function if an exception is thrown which +/// violates the function's exception specification. +void unexpected (void) __attribute__ ((__noreturn__)); +/// Returns true when the caught exception violates the throw specification. +bool uncaught_exception() throw(); +} // namespace std +#endif + +namespace ustl { + +class string; + +typedef uint32_t xfmt_t; + +enum { + xfmt_Exception, + xfmt_BadAlloc, + xfmt_LibcException = 12, + xfmt_FileException = 13, + xfmt_StreamBoundsException = 14 +}; + +/// \class exception uexception.h ustl.h +/// \ingroup Exceptions +/// +/// \brief Base class for exceptions, equivalent to std::exception. +/// +#if WITHOUT_LIBSTDCPP +class exception { +#else +class exception : public std::exception { +#endif +public: + typedef const CBacktrace& rcbktrace_t; +public: + inline exception (void) throw() : m_Format (xfmt_Exception) {} + inline virtual ~exception (void) throw() {} + inline virtual const char* what (void) const throw() { return ("error"); } + virtual void info (string& msgbuf, const char* fmt = NULL) const throw(); + virtual void read (istream& is); + virtual void write (ostream& os) const; + void text_write (ostringstream& os) const; + inline virtual size_t stream_size (void) const { return (sizeof(m_Format) + sizeof(uint32_t) + m_Backtrace.stream_size()); } + /// Format of the exception is used to lookup exception::info format string. + /// Another common use is the instantiation of serialized exceptions, used + /// by the error handler node chain to troubleshoot specific errors. + inline xfmt_t format (void) const { return (m_Format); } + inline rcbktrace_t backtrace (void) const { return (m_Backtrace); } +protected: + inline void set_format (xfmt_t fmt) { m_Format = fmt; } +private: + CBacktrace m_Backtrace; ///< Backtrace of the throw point. + xfmt_t m_Format; ///< Format of the exception's data. +}; + +/// \class bad_cast uexception.h ustl.h +/// \ingroup Exceptions +/// +/// \brief Thrown to indicate a bad dynamic_cast usage. +/// +class bad_cast : public exception { +public: + inline explicit bad_cast (void) throw() : exception() {} + inline virtual const char* what (void) const throw() { return ("bad cast"); } +}; + +//---------------------------------------------------------------------- + +/// \class bad_alloc uexception.h ustl.h +/// \ingroup Exceptions +/// +/// \brief Exception thrown on memory allocation failure by memblock::reserve. +/// +#if WITHOUT_LIBSTDCPP +class bad_alloc : public exception { +#else +class bad_alloc : public std::bad_alloc, public exception { +#endif +public: + explicit bad_alloc (size_t nBytes = 0) throw(); + inline virtual const char* what (void) const throw() { return ("memory allocation failed"); } + virtual void info (string& msgbuf, const char* fmt = NULL) const throw(); + virtual void read (istream& is); + virtual void write (ostream& os) const; + virtual size_t stream_size (void) const; +protected: + size_t m_nBytesRequested; ///< Number of bytes requested by the failed allocation. +}; + +/// \class libc_exception uexception.h ustl.h +/// \ingroup Exceptions +/// +/// \brief Thrown when a libc function returns an error. +/// +/// Contains an errno and description. This is a uSTL extension. +/// +class libc_exception : public exception { +public: + explicit libc_exception (const char* operation) throw(); + libc_exception (const libc_exception& v) throw(); + const libc_exception& operator= (const libc_exception& v); + inline virtual const char* what (void) const throw() { return ("libc function failed"); } + virtual void info (string& msgbuf, const char* fmt = NULL) const throw(); + virtual void read (istream& is); + virtual void write (ostream& os) const; + virtual size_t stream_size (void) const; +protected: + intptr_t m_Errno; ///< Error code returned by the failed operation. + const char* m_Operation; ///< Name of the failed operation. +}; + +/// \class file_exception uexception.h ustl.h +/// \ingroup Exceptions +/// +/// \brief File-related exceptions. +/// +/// Contains the file name. This is a uSTL extension. +/// +class file_exception : public libc_exception { +public: + file_exception (const char* operation, const char* filename) throw(); + inline virtual const char* what (void) const throw() { return ("file error"); } + virtual void info (string& msgbuf, const char* fmt = NULL) const throw(); + virtual void read (istream& is); + virtual void write (ostream& os) const; + virtual size_t stream_size (void) const; +protected: + char m_Filename [PATH_MAX]; ///< Name of the file causing the error. +}; + +/// \class stream_bounds_exception uexception.h ustl.h +/// \ingroup Exceptions +/// +/// \brief Stream bounds checking. +/// +/// Only thrown in debug builds unless you say otherwise in config.h +/// This is a uSTL extension. +/// +class stream_bounds_exception : public libc_exception { +public: + stream_bounds_exception (const char* operation, const char* type, uoff_t offset, size_t expected, size_t remaining) throw(); + inline virtual const char* what (void) const throw() { return ("stream bounds exception"); } + virtual void info (string& msgbuf, const char* fmt = NULL) const throw(); + virtual void read (istream& is); + virtual void write (ostream& os) const; + virtual size_t stream_size (void) const; +protected: + const char* m_TypeName; + uoff_t m_Offset; + size_t m_Expected; + size_t m_Remaining; +}; + +const char* demangle_type_name (char* buf, size_t bufSize, size_t* pdmSize = NULL); + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/ufunction.h @@ -0,0 +1,465 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UFUNCTION_H_221ABA8551801799263C927234C085F3 +#define UFUNCTION_H_221ABA8551801799263C927234C085F3 + +namespace ustl { + +//---------------------------------------------------------------------- +// Standard functors +//---------------------------------------------------------------------- + +/// \brief void-returning function abstract interface. +/// \ingroup FunctorObjects +template <typename Result> +struct void_function { + typedef Result result_type; +}; + +/// \brief \p Result f (\p Arg) function abstract interface. +/// \ingroup FunctorObjects +template <typename Arg, typename Result> +struct unary_function { + typedef Arg argument_type; + typedef Result result_type; +}; + +/// \brief \p Result f (\p Arg1, \p Arg2) function abstract interface. +/// \ingroup FunctorObjects +template <typename Arg1, typename Arg2, typename Result> +struct binary_function { + typedef Arg1 first_argument_type; + typedef Arg2 second_argument_type; + typedef Result result_type; +}; + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#define STD_BINARY_FUNCTOR(name, rv, func) \ +template <class T> struct name : public binary_function<T,T,rv> \ +{ inline rv operator()(const T& a, const T& b) const { return func; } }; +#define STD_UNARY_FUNCTOR(name, rv, func) \ +template <class T> struct name : public unary_function<T,rv> \ +{ inline rv operator()(const T& a) const { return func; } }; +#define STD_CONVERSION_FUNCTOR(name, func) \ +template <class S, class D> struct name : public unary_function<S,D> \ +{ inline D operator()(const S& a) const { return func; } }; + +STD_BINARY_FUNCTOR (plus, T, (a + b)) +STD_BINARY_FUNCTOR (minus, T, (a - b)) +STD_BINARY_FUNCTOR (divides, T, (a / b)) +STD_BINARY_FUNCTOR (modulus, T, (a % b)) +STD_BINARY_FUNCTOR (multiplies, T, (a * b)) +STD_BINARY_FUNCTOR (logical_and, T, (a && b)) +STD_BINARY_FUNCTOR (logical_or, T, (a || b)) +STD_UNARY_FUNCTOR (logical_not, T, (!a)) +STD_BINARY_FUNCTOR (bitwise_or, T, (a | b)) +STD_BINARY_FUNCTOR (bitwise_and, T, (a & b)) +STD_BINARY_FUNCTOR (bitwise_xor, T, (a ^ b)) +STD_UNARY_FUNCTOR (bitwise_not, T, (~a)) +STD_UNARY_FUNCTOR (negate, T, (-a)) +STD_BINARY_FUNCTOR (equal_to, bool, (a == b)) +STD_BINARY_FUNCTOR (not_equal_to, bool, (!(a == b))) +STD_BINARY_FUNCTOR (greater, bool, (b < a)) +STD_BINARY_FUNCTOR (less, bool, (a < b)) +STD_BINARY_FUNCTOR (greater_equal, bool, (!(a < b))) +STD_BINARY_FUNCTOR (less_equal, bool, (!(b < a))) +STD_BINARY_FUNCTOR (compare, int, (a < b ? -1 : (b < a))) +STD_UNARY_FUNCTOR (identity, T, (a)) + +#endif // DOXYGEN_SHOULD_SKIP_THIS + +/// \brief Selects and returns the first argument. +/// \ingroup FunctorObjects +template <class T1, class T2> struct project1st : public binary_function<T1,T2,T1> { inline const T1& operator()(const T1& a, const T2&) const { return (a); } }; +/// \brief Selects and returns the second argument. +/// \ingroup FunctorObjects +template <class T1, class T2> struct project2nd : public binary_function<T1,T2,T2> { inline const T2& operator()(const T1&, const T2& a) const { return (a); } }; + +//---------------------------------------------------------------------- +// Generic function to functor converters. +//---------------------------------------------------------------------- + +/// \brief Wrapper object for unary function pointers. +/// Use the ptr_fun accessor to create this object. +/// \ingroup FunctorObjects +template <typename Arg, typename Result> +class pointer_to_unary_function : public unary_function<Arg,Result> { +public: + typedef Arg argument_type; + typedef Result result_type; + typedef Result (*pfunc_t)(Arg); +public: + explicit inline pointer_to_unary_function (pfunc_t pfn) : m_pfn (pfn) {} + inline result_type operator() (argument_type v) const { return (m_pfn(v)); } +private: + pfunc_t m_pfn; ///< Pointer to the wrapped function. +}; + +/// \brief Wrapper object for binary function pointers. +/// Use the ptr_fun accessor to create this object. +/// \ingroup FunctorObjects +template <typename Arg1, typename Arg2, typename Result> +class pointer_to_binary_function : public binary_function<Arg1,Arg2,Result> { +public: + typedef Arg1 first_argument_type; + typedef Arg2 second_argument_type; + typedef Result result_type; + typedef Result (*pfunc_t)(Arg1, Arg2); +public: + explicit inline pointer_to_binary_function (pfunc_t pfn) : m_pfn (pfn) {} + inline result_type operator() (first_argument_type v1, second_argument_type v2) const { return (m_pfn(v1, v2)); } +private: + pfunc_t m_pfn; ///< Pointer to the wrapped function. +}; + +/// ptr_fun(pfn) wraps function pointer pfn into a functor class that calls it. +/// \ingroup FunctorAccessors +template <typename Arg, typename Result> +inline pointer_to_unary_function<Arg,Result> ptr_fun (Result (*pfn)(Arg)) +{ + return (pointer_to_unary_function<Arg,Result> (pfn)); +} + +/// ptr_fun(pfn) wraps function pointer pfn into a functor class that calls it. +/// \ingroup FunctorAccessors +template <typename Arg1, typename Arg2, typename Result> +inline pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun (Result (*pfn)(Arg1,Arg2)) +{ + return (pointer_to_binary_function<Arg1,Arg2,Result> (pfn)); +} + +//---------------------------------------------------------------------- +// Negators. +//---------------------------------------------------------------------- + +/// \brief Wraps a unary function to return its logical negative. +/// Use the unary_negator accessor to create this object. +/// \ingroup FunctorObjects +template <class UnaryFunction> +class unary_negate : public unary_function<typename UnaryFunction::argument_type, + typename UnaryFunction::result_type> { +public: + typedef typename UnaryFunction::argument_type argument_type; + typedef typename UnaryFunction::result_type result_type; +public: + explicit inline unary_negate (UnaryFunction pfn) : m_pfn (pfn) {} + inline result_type operator() (argument_type v) const { return (!m_pfn(v)); } +private: + UnaryFunction m_pfn; +}; + +/// Returns the functor that negates the result of *pfn(). +/// \ingroup FunctorAccessors +template <class UnaryFunction> +inline unary_negate<UnaryFunction> unary_negator (UnaryFunction pfn) +{ + return (unary_negate<UnaryFunction>(pfn)); +} + +//---------------------------------------------------------------------- +// Argument binders +//---------------------------------------------------------------------- + +/// \brief Converts a binary function to a unary function +/// by binding a constant value to the first argument. +/// Use the bind1st accessor to create this object. +/// \ingroup FunctorObjects +template <class BinaryFunction> +class binder1st : public unary_function<typename BinaryFunction::second_argument_type, + typename BinaryFunction::result_type> { +public: + typedef typename BinaryFunction::first_argument_type arg1_t; + typedef typename BinaryFunction::second_argument_type arg2_t; + typedef typename BinaryFunction::result_type result_t; +public: + inline binder1st (const BinaryFunction& pfn, const arg1_t& v) : m_pfn (pfn), m_Value(v) {} + inline result_t operator()(arg2_t v2) const { return (m_pfn (m_Value, v2)); } +protected: + BinaryFunction m_pfn; + arg1_t m_Value; +}; + +/// \brief Converts a binary function to a unary function +/// by binding a constant value to the second argument. +/// Use the bind2nd accessor to create this object. +/// \ingroup FunctorObjects +template <class BinaryFunction> +class binder2nd : public unary_function<typename BinaryFunction::first_argument_type, + typename BinaryFunction::result_type> { +public: + typedef typename BinaryFunction::first_argument_type arg1_t; + typedef typename BinaryFunction::second_argument_type arg2_t; + typedef typename BinaryFunction::result_type result_t; +public: + inline binder2nd (const BinaryFunction& pfn, const arg2_t& v) : m_pfn (pfn), m_Value(v) {} + inline result_t operator()(arg1_t v1) const { return (m_pfn (v1, m_Value)); } +protected: + BinaryFunction m_pfn; + arg2_t m_Value; +}; + +/// Converts \p pfn into a unary function by binding the first argument to \p v. +/// \ingroup FunctorAccessors +template <typename BinaryFunction> +inline binder1st<BinaryFunction> +bind1st (BinaryFunction pfn, typename BinaryFunction::first_argument_type v) +{ + return (binder1st<BinaryFunction> (pfn, v)); +} + +/// Converts \p pfn into a unary function by binding the second argument to \p v. +/// \ingroup FunctorAccessors +template <typename BinaryFunction> +inline binder2nd<BinaryFunction> +bind2nd (BinaryFunction pfn, typename BinaryFunction::second_argument_type v) +{ + return (binder2nd<BinaryFunction> (pfn, v)); +} + +//---------------------------------------------------------------------- +// Composition adapters +//---------------------------------------------------------------------- + +/// \brief Chains two unary functions together. +/// +/// When f(x) and g(x) are composed, the result is function c(x)=f(g(x)). +/// Use the \ref compose1 accessor to create this object. +/// This template is an extension, implemented by SGI STL and uSTL. +/// \ingroup FunctorObjects +/// +template <typename Operation1, typename Operation2> +class unary_compose : public unary_function<typename Operation2::argument_type, + typename Operation1::result_type> { +public: + typedef typename Operation2::argument_type arg_t; + typedef const arg_t& rcarg_t; + typedef typename Operation1::result_type result_t; +public: + inline unary_compose (const Operation1& f, const Operation2& g) : m_f(f), m_g(g) {} + inline result_t operator() (rcarg_t x) const { return m_f(m_g(x)); } +protected: + Operation1 m_f; ///< f(x), if c(x) = f(g(x)) + Operation2 m_g; ///< g(x), if c(x) = f(g(x)) +}; + +/// Creates a \ref unary_compose object whose function c(x)=f(g(x)) +/// \ingroup FunctorAccessors +template <typename Operation1, typename Operation2> +inline unary_compose<Operation1, Operation2> +compose1 (const Operation1& f, const Operation2& g) +{ return unary_compose<Operation1,Operation2>(f, g); } + +/// \brief Chains two unary functions through a binary function. +/// +/// When f(x,y), g(x), and h(x) are composed, the result is function +/// c(x)=f(g(x),h(x)). Use the \ref compose2 accessor to create this +/// object. This template is an extension, implemented by SGI STL and uSTL. +/// \ingroup FunctorObjects +/// +template <typename Operation1, typename Operation2, typename Operation3> +class binary_compose : public unary_function<typename Operation2::argument_type, + typename Operation1::result_type> { +public: + typedef typename Operation2::argument_type arg_t; + typedef const arg_t& rcarg_t; + typedef typename Operation1::result_type result_t; +public: + inline binary_compose (const Operation1& f, const Operation2& g, const Operation3& h) : m_f(f), m_g(g), m_h(h) {} + inline result_t operator() (rcarg_t x) const { return m_f(m_g(x), m_h(x)); } +protected: + Operation1 m_f; ///< f(x,y), if c(x) = f(g(x),h(x)) + Operation2 m_g; ///< g(x), if c(x) = f(g(x),h(x)) + Operation3 m_h; ///< h(x), if c(x) = f(g(x),h(x)) +}; + +/// Creates a \ref binary_compose object whose function c(x)=f(g(x),h(x)) +/// \ingroup FunctorAccessors +template <typename Operation1, typename Operation2, typename Operation3> +inline binary_compose<Operation1, Operation2, Operation3> +compose2 (const Operation1& f, const Operation2& g, const Operation3& h) +{ return binary_compose<Operation1, Operation2, Operation3> (f, g, h); } + +//---------------------------------------------------------------------- +// Member function adaptors +//---------------------------------------------------------------------- + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#define MEM_FUN_T(WrapperName, ClassName, ArgType, FuncType, CallType) \ + template <typename Ret, class T> \ + class ClassName : public unary_function<ArgType,Ret> { \ + public: \ + typedef Ret (T::*func_t) FuncType; \ + public: \ + explicit inline ClassName (func_t pf) : m_pf (pf) {} \ + inline Ret operator() (ArgType p) const { return ((p CallType m_pf)()); } \ + private: \ + func_t m_pf; \ + }; \ + \ + template <class Ret, typename T> \ + inline ClassName<Ret,T> WrapperName (Ret (T::*pf) FuncType) \ + { \ + return (ClassName<Ret,T> (pf)); \ + } + +MEM_FUN_T(mem_fun, mem_fun_t, T*, (void), ->*) +MEM_FUN_T(mem_fun, const_mem_fun_t, const T*, (void) const, ->*) +MEM_FUN_T(mem_fun_ref, mem_fun_ref_t, T&, (void), .*) +MEM_FUN_T(mem_fun_ref, const_mem_fun_ref_t, const T&, (void) const, .*) + +#define EXT_MEM_FUN_T(ClassName, HostType, FuncType) \ + template <class T, typename Ret, typename V> \ + class ClassName : public unary_function<V,void> { \ + public: \ + typedef Ret (T::*func_t)(V) FuncType; \ + public: \ + inline ClassName (HostType t, func_t pf) : m_t (t), m_pf (pf) {} \ + inline Ret operator() (V v) const { return ((m_t->*m_pf)(v)); } \ + private: \ + HostType m_t; \ + func_t m_pf; \ + }; \ + \ + template <class T, typename Ret, typename V> \ + inline ClassName<T,Ret,V> mem_fun (HostType p, Ret (T::*pf)(V) FuncType) \ + { \ + return (ClassName<T,Ret,V> (p, pf)); \ + } + +EXT_MEM_FUN_T(ext_mem_fun_t, T*, ) +EXT_MEM_FUN_T(const_ext_mem_fun_t, const T*, const) + +#endif // DOXYGEN_SHOULD_SKIP_THIS + +//---------------------------------------------------------------------- +// Member variable adaptors (uSTL extension) +//---------------------------------------------------------------------- + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#define MEM_VAR_T(FunctorName, ArgType, VarType, BaseClass, CallImpl) \ + template <typename Function, class T, typename VT> \ + class FunctorName##_t : public BaseClass { \ + public: \ + typedef ArgType argument_type; \ + typedef typename Function::result_type result_type; \ + typedef VarType mem_var_ptr_t; \ + public: \ + inline FunctorName##_t (mem_var_ptr_t pv, Function pfn) : m_pv(pv), m_pfn(pfn) {} \ + inline result_type operator() CallImpl \ + private: \ + mem_var_ptr_t m_pv; \ + Function m_pfn; \ + }; \ + \ + template <typename Function, class T, typename VT> \ + inline FunctorName##_t<Function, T, VT> \ + FunctorName (VT T::*mvp, Function pfn) \ + { \ + return (FunctorName##_t<Function,T,VT> (mvp, pfn)); \ + } + +#define FUNCTOR_UNARY_BASE(ArgType) unary_function<ArgType, typename Function::result_type> +#define FUNCTOR_BINARY_BASE(ArgType) binary_function<ArgType, ArgType, typename Function::result_type> + +#define MEM_VAR_UNARY_ARGS (argument_type p) const \ + { return (m_pfn(p.*m_pv)); } +#define MEM_VAR_BINARY_ARGS (argument_type p1, argument_type p2) const \ + { return (m_pfn(p1.*m_pv, p2.*m_pv)); } + +MEM_VAR_T(mem_var1, T&, VT T::*, FUNCTOR_UNARY_BASE(T&), MEM_VAR_UNARY_ARGS) +MEM_VAR_T(const_mem_var1, const T&, const VT T::*, FUNCTOR_UNARY_BASE(T&), MEM_VAR_UNARY_ARGS) +MEM_VAR_T(mem_var2, T&, VT T::*, FUNCTOR_BINARY_BASE(T&), MEM_VAR_BINARY_ARGS) +MEM_VAR_T(const_mem_var2, const T&, const VT T::*, FUNCTOR_BINARY_BASE(T&), MEM_VAR_BINARY_ARGS) + +#undef MEM_VAR_UNARY_ARGS +#undef MEM_VAR_BINARY_ARGS + +#endif // DOXYGEN_SHOULD_SKIP_THIS + +/// Returned functor passes member variable \p mvp reference of given object to equal\<VT\>. +/// \ingroup FunctorAccessors +template <class T, typename VT> +inline const_mem_var1_t<binder2nd<equal_to<VT> >, T, VT> +mem_var_equal_to (const VT T::*mvp, const VT& v) +{ + return (const_mem_var1_t<binder2nd<equal_to<VT> >,T,VT> (mvp, bind2nd(equal_to<VT>(), v))); +} + +/// Returned functor passes member variable \p mvp reference of given object to less\<VT\>. +/// \ingroup FunctorAccessors +template <class T, typename VT> +inline const_mem_var1_t<binder2nd<less<VT> >, T, VT> +mem_var_less (const VT T::*mvp, const VT& v) +{ + return (const_mem_var1_t<binder2nd<less<VT> >,T,VT> (mvp, bind2nd(less<VT>(), v))); +} + +/// Returned functor passes member variable \p mvp reference of given object to equal\<VT\>. +/// \ingroup FunctorAccessors +template <class T, typename VT> +inline const_mem_var2_t<equal_to<VT>, T, VT> +mem_var_equal_to (const VT T::*mvp) +{ + return (const_mem_var2_t<equal_to<VT>,T,VT> (mvp, equal_to<VT>())); +} + +/// Returned functor passes member variable \p mvp reference of given object to less\<VT\>. +/// \ingroup FunctorAccessors +template <class T, typename VT> +inline const_mem_var2_t<less<VT>, T, VT> +mem_var_less (const VT T::*mvp) +{ + return (const_mem_var2_t<less<VT>,T,VT> (mvp, less<VT>())); +} + +//---------------------------------------------------------------------- +// Dereference adaptors (uSTL extension) +//---------------------------------------------------------------------- + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#define DEREFERENCER_T(ClassName, ArgType, BaseClass, CallImpl, FunctorKey) \ + template <typename T, typename Function> \ + class ClassName : public BaseClass { \ + public: \ + typedef ArgType* argument_type; \ + typedef typename Function::result_type result_type; \ + public: \ + inline ClassName (Function pfn) : m_pfn (pfn) {} \ + inline result_type operator() CallImpl \ + private: \ + Function m_pfn; \ + }; \ + \ + template <typename T, typename Function> \ + inline ClassName<T,Function> _dereference (Function pfn, FunctorKey) \ + { \ + return (ClassName<T,Function> (pfn)); \ + } + +#define DEREF_UNARY_ARGS (argument_type p) const \ + { return (m_pfn(*p)); } +#define DEREF_BINARY_ARGS (argument_type p1, argument_type p2) const \ + { return (m_pfn(*p1, *p2)); } + +DEREFERENCER_T(deref1_t, T, FUNCTOR_UNARY_BASE(T*), DEREF_UNARY_ARGS, FUNCTOR_UNARY_BASE(T)) +DEREFERENCER_T(const_deref1_t, const T, FUNCTOR_UNARY_BASE(const T*), DEREF_UNARY_ARGS, FUNCTOR_UNARY_BASE(const T)) +DEREFERENCER_T(deref2_t, T, FUNCTOR_BINARY_BASE(T*), DEREF_BINARY_ARGS, FUNCTOR_BINARY_BASE(T)) +DEREFERENCER_T(const_deref2_t, const T, FUNCTOR_BINARY_BASE(const T*), DEREF_BINARY_ARGS, FUNCTOR_BINARY_BASE(const T)) + +#define dereference(f) _dereference(f,f) + +#undef DEREF_UNARY_ARGS +#undef DEREF_BINARY_ARGS + +#endif + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/uheap.h @@ -0,0 +1,142 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UHEAP_H_574B9EAF271A1C107190B4D575A356C5 +#define UHEAP_H_574B9EAF271A1C107190B4D575A356C5 + +#include "ualgobase.h" + +namespace ustl { + +/// \brief Returns true if the given range is a heap under \p comp. +/// A heap is a sequentially encoded binary tree where for every node +/// comp(node,child1) is false and comp(node,child2) is false. +/// \ingroup HeapAlgorithms +/// \ingroup ConditionAlgorithms +/// +template <typename RandomAccessIterator, typename Compare> +bool is_heap (RandomAccessIterator first, RandomAccessIterator last, Compare comp) +{ + RandomAccessIterator iChild (first); + for (; ++iChild < last; ++first) + if (comp (*first, *iChild) || (++iChild < last && comp (*first, *iChild))) + return (false); + return (true); +} + +/// \brief make_heap turns the range [first, last) into a heap +/// At completion, is_heap (first, last, comp) is true. +/// The algorithm is adapted from "Classic Data Structures in C++" by Timothy Budd. +/// \ingroup HeapAlgorithms +/// \ingroup SortingAlgorithms +/// +template <typename RandomAccessIterator, typename Compare> +void make_heap (RandomAccessIterator first, RandomAccessIterator last, Compare comp) +{ + typedef typename iterator_traits<RandomAccessIterator>::value_type value_type; + const value_type v (*first); + uoff_t iChild, iHole = 0, iEnd (distance (first, last)); + while ((iChild = 2 * iHole + 1) < iEnd) { + if (iChild + 1 < iEnd) // Pick the greater child + iChild += comp (first[iChild], first[iChild + 1]); + if (comp (first[iChild], v)) + break; // Done when parent is greater than both children. + first[iHole] = first[iChild]; + iHole = iChild; + } + if (iHole < iEnd) + first[iHole] = v; +} + +/// \brief Inserts the *--last into the preceeding range assumed to be a heap. +/// \ingroup HeapAlgorithms +/// \ingroup MutatingAlgorithms +template <typename RandomAccessIterator, typename Compare> +void push_heap (RandomAccessIterator first, RandomAccessIterator last, Compare comp) +{ + if (last <= first) + return; + typedef typename iterator_traits<RandomAccessIterator>::value_type value_type; + const value_type v (*--last); + while (first < last) { + RandomAccessIterator iParent = first + (distance(first, last) - 1) / 2; + if (comp (v, *iParent)) + break; + *last = *iParent; + last = iParent; + } + *last = v; +} + +/// Removes the largest element from the heap (*first) and places it at *(last-1) +/// [first, last-1) is a heap after this operation. +/// \ingroup HeapAlgorithms +/// \ingroup MutatingAlgorithms +template <typename RandomAccessIterator, typename Compare> +void pop_heap (RandomAccessIterator first, RandomAccessIterator last, Compare comp) +{ + if (--last <= first) + return; + iter_swap (first, last); + make_heap (first, last, comp); +} + +/// Sorts heap [first, last) in descending order according to comp. +/// \ingroup HeapAlgorithms +/// \ingroup SortingAlgorithms +template <typename RandomAccessIterator, typename Compare> +void sort_heap (RandomAccessIterator first, RandomAccessIterator last, Compare comp) +{ + for (; first < last; --last) + pop_heap (first, last, comp); +} + +#define HEAP_FN_WITH_LESS(rtype, name) \ +template <typename RandomAccessIterator>\ +inline rtype name (RandomAccessIterator first, RandomAccessIterator last) \ +{ \ + typedef typename iterator_traits<RandomAccessIterator>::value_type value_type; \ + return (name (first, last, less<value_type>())); \ +} +HEAP_FN_WITH_LESS (bool, is_heap) +HEAP_FN_WITH_LESS (void, make_heap) +HEAP_FN_WITH_LESS (void, push_heap) +HEAP_FN_WITH_LESS (void, pop_heap) +HEAP_FN_WITH_LESS (void, sort_heap) +#undef HEAP_FN_WITH_LESS + +/// \class priority_queue uheap.h ustl.h +/// \ingroup Sequences +/// +/// \brief Sorted queue adapter to uSTL containers. +/// +/// Acts just like the queue adapter, but keeps the elements sorted by priority +/// specified by the given comparison operator. +/// +template <typename T, typename Ctr = vector<T>, typename Comp = less<typename Ctr::value_type> > +class priority_queue { +public: + typedef Ctr base_ctr; + typedef typename base_ctr::value_type value_type; + typedef typename base_ctr::size_type size_type; + typedef typename base_ctr::const_pointer const_pointer; + typedef typename base_ctr::const_reference reference; +public: + priority_queue (const Comp& c = Comp()) : m_v(), m_c (c) {} + priority_queue (const_pointer f, const_pointer l, const Comp& c = Comp()) + : m_v (f, l), m_c (c) { make_heap (m_v.begin(), m_v.end(), m_c); } + inline size_type size (void) const { return (m_v.size()); } + inline bool empty (void) const { return (m_v.empty()); } + inline reference top (void) const { return (m_v.at(0)); } + inline void push (reference v) { m_v.push_back (v); make_heap (m_v.begin(), m_v.end(), m_c); } + inline void pop (void) { pop_heap (m_v.begin(), m_v.end()); m_v.pop_back(); } +private: + base_ctr m_v; ///< Element container. + Comp m_c; ///< Comparison functor by value. +}; + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/uios.h @@ -0,0 +1,103 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UIOS_H_630C16E316F7650E3A02E1C6611B789A +#define UIOS_H_630C16E316F7650E3A02E1C6611B789A + +#include "utypes.h" + +namespace ustl { + +class file_exception; + +const char endl = '\n'; ///< End of line character. +const char ends = '\0'; ///< End of string character. + +/// Defines types and constants used by all stream classes. +class ios_base { +public: + /// Used to set parameters for stringstreams + enum fmtflags { + boolalpha = (1 << 0), ///< Boolean values printed as text. + dec = (1 << 1), ///< Decimal number output. + fixed = (1 << 2), ///< Fixed-point float output. + hex = (1 << 3), ///< Hexadecimal number output. + internal = (1 << 4), + left = (1 << 5), ///< Left alignment. + oct = (1 << 6), ///< Octal number output. + right = (1 << 7), ///< Right alignment. + scientific = (1 << 8), ///< Scientific float format. + showbase = (1 << 9), ///< Add 0x or 0 prefixes on hex and octal numbers. + showpoint = (1 << 10), ///< Print decimal point. + showpos = (1 << 11), + skipws = (1 << 12), ///< Skip whitespace when reading. + unitbuf = (1 << 13), + uppercase = (1 << 14), + adjustfield = (1 << 15), + basefield = (1 << 16), + floatfield = (1 << 17) + }; + /// For file-based streams, specifies fd mode. + enum openmode_bits { + in = (1 << 0), + out = (1 << 1), + app = (1 << 2), + ate = (1 << 3), + binary = (1 << 4), + trunc = (1 << 5), + #ifndef DOXYGEN_SHOULD_SKIP_THIS + nonblock= (1 << 6), + nocreate= (1 << 7), + noctty = (1 << 8), + nombits = 9 + #endif + }; + /// Seek directions, equivalent to SEEK_SET, SEEK_CUR, and SEEK_END. + enum seekdir { + beg, + cur, + end + }; + /// I/O state bitmasks. + enum iostate_bits { + goodbit = 0, + badbit = (1 << 0), + eofbit = (1 << 1), + failbit = (1 << 2), + #ifndef DOXYGEN_SHOULD_SKIP_THIS + nbadbits = 3, + allbadbits = 0x7 + #endif + }; + + typedef uint32_t openmode; ///< Holds openmode_bits. + typedef uint32_t iostate; ///< Holds iostate_bits for a file stream. + typedef file_exception failure; ///< Thrown by fstream on errors. + + static const char c_DefaultDelimiters [16]; ///< Default word delimiters for stringstreams. +public: + inline ios_base (void) : m_State (goodbit), m_Exceptions (allbadbits) {} + inline iostate rdstate (void) const { return (m_State); } + inline bool bad (void) const { return (rdstate() & badbit); } + inline bool good (void) const { return (rdstate() == goodbit); } + inline bool fail (void) const { return (rdstate() & (badbit | failbit)); } + inline bool eof (void) const { return (rdstate() & eofbit); } + inline bool operator! (void) const { return (fail()); } + inline operator void* (void) const { return (reinterpret_cast<void*>(!fail())); } + inline void clear (iostate v = goodbit) { m_State = v; } + inline void setstate (iostate v) { m_State |= v; } + inline iostate exceptions (void) const { return (m_Exceptions); } + inline iostate exceptions (iostate v) { return (m_Exceptions = v); } +protected: + inline bool set_and_throw (iostate v) { setstate(v); return (exceptions() & v); } + void overrun (const char* op, const char* type, uint32_t n, uint32_t p, uint32_t rem); +private: + uint16_t m_State; ///< Open state, using ios::iostate_bits. + uint16_t m_Exceptions; ///< Exception flags, using ios::iostate_bits. +}; + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/uiosfunc.h @@ -0,0 +1,96 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UIOSFUNC_H_730C16E316F7650E3A02E1C6611B789A +#define UIOSFUNC_H_730C16E316F7650E3A02E1C6611B789A + +#include "sostream.h" + +namespace ustl { + +class ios : public ios_base { +public: + /// \class align uiosfunc.h ustl.h + /// \ingroup StreamFunctors + /// \brief Stream functor to allow inline align() calls. + /// + /// Example: os << ios::align(sizeof(uint16_t)); + /// + class align { + public: + inline explicit align (size_t grain = c_DefaultAlignment) : m_Grain(grain) {} + inline istream& apply (istream& is) const { is.align (m_Grain); return (is); } + inline ostream& apply (ostream& os) const { os.align (m_Grain); return (os); } + inline void read (istream& is) const { apply (is); } + inline void write (ostream& os) const { apply (os); } + inline size_t stream_size (void) const { return (m_Grain - 1); } + private: + const size_t m_Grain; + }; + + /// \class talign uiosfunc.h ustl.h + /// \ingroup StreamFunctors + /// \brief Stream functor to allow type-based alignment. + template <typename T> + class talign : public align { + public: + inline explicit talign (void) : align (alignof (NullValue<T>())) {} + }; + + /// \class skip uiosfunc.h ustl.h + /// \ingroup StreamFunctors + /// \brief Stream functor to allow inline skip() calls. + /// + /// Example: os << ios::skip(sizeof(uint16_t)); + /// + class skip { + public: + inline explicit skip (size_t nBytes) : m_nBytes(nBytes) {} + inline istream& apply (istream& is) const { is.skip (m_nBytes); return (is); } + inline ostream& apply (ostream& os) const { os.skip (m_nBytes); return (os); } + inline void read (istream& is) const { apply (is); } + inline void write (ostream& os) const { apply (os); } + inline size_t stream_size (void) const { return (m_nBytes); } + private: + const size_t m_nBytes; + }; + + /// \class width uiosfunc.h ustl.h + /// \ingroup StreamFunctors + /// \brief Stream functor to allow inline set_width() calls. + /// + /// Example: os << ios::width(15); + /// + class width { + public: + inline explicit width (size_t nBytes) : m_nBytes(nBytes) {} + inline ostringstream& apply (ostringstream& os) const { os.set_width (m_nBytes); return (os); } + inline void text_write (ostringstream& os) const { apply (os); } + private: + const size_t m_nBytes; + }; + + /// \class base uiosfunc.h ustl.h + /// \ingroup StreamFunctors + /// \brief Stream functor to allow inline set_base() calls. + /// + /// Example: os << ios::base(15); + /// + class base { + public: + inline explicit base (size_t n) : m_Base(n) {} + inline ostringstream& apply (ostringstream& os) const { os.set_base (m_Base); return (os); } + inline void text_write (ostringstream& os) const { apply (os); } + private: + const size_t m_Base; + }; +}; + +} // namespace ustl + +CAST_STREAMABLE(ustl::ios::fmtflags, uint32_t) +NUMERIC_LIMITS(ustl::ios::fmtflags, ustl::ios::boolalpha, ustl::ios::floatfield, false, true, true) + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/uiterator.h @@ -0,0 +1,266 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. +// +/// \file uiterator.h +/// \brief Contains various iterator adapters. + +#ifndef UITERATOR_H_5BCA176C7214A30F2069E2614D2DC226 +#define UITERATOR_H_5BCA176C7214A30F2069E2614D2DC226 + +#include "utypes.h" + +namespace ustl { + +//---------------------------------------------------------------------- + +/// \struct iterator_traits uiterator.h ustl.h +/// \brief Contains the type traits of \p Iterator +/// +template <typename Iterator> +struct iterator_traits { + typedef typename Iterator::value_type value_type; + typedef typename Iterator::difference_type difference_type; + typedef typename Iterator::pointer pointer; + typedef typename Iterator::reference reference; +}; + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +template <typename T> +struct iterator_traits<T*> { + typedef T value_type; + typedef ptrdiff_t difference_type; + typedef const T* const_pointer; + typedef T* pointer; + typedef const T& const_reference; + typedef T& reference; +}; + +template <typename T> +struct iterator_traits<const T*> { + typedef T value_type; + typedef ptrdiff_t difference_type; + typedef const T* const_pointer; + typedef const T* pointer; + typedef const T& const_reference; + typedef const T& reference; +}; + +template <> +struct iterator_traits<void*> { + typedef uint8_t value_type; + typedef ptrdiff_t difference_type; + typedef const void* const_pointer; + typedef void* pointer; + typedef const value_type& const_reference; + typedef value_type& reference; +}; + +template <> +struct iterator_traits<const void*> { + typedef uint8_t value_type; + typedef ptrdiff_t difference_type; + typedef const void* const_pointer; + typedef const void* pointer; + typedef const value_type& const_reference; + typedef const value_type& reference; +}; + +#endif + +//---------------------------------------------------------------------- + +/// \class reverse_iterator uiterator.h ustl.h +/// \ingroup IteratorAdaptors +/// \brief Wraps \p Iterator to behave in an exactly opposite manner. +/// +template <class Iterator> +class reverse_iterator { +public: + typedef typename iterator_traits<Iterator>::value_type value_type; + typedef typename iterator_traits<Iterator>::difference_type difference_type; + typedef typename iterator_traits<Iterator>::pointer pointer; + typedef typename iterator_traits<Iterator>::reference reference; +public: + reverse_iterator (void) : m_i() {} + explicit reverse_iterator (Iterator iter) : m_i (iter) {} + inline bool operator== (const reverse_iterator& iter) const { return (m_i == iter.m_i); } + inline bool operator< (const reverse_iterator& iter) const { return (iter.m_i < m_i); } + inline Iterator base (void) const { return (m_i); } + inline reference operator* (void) const { Iterator prev (m_i); --prev; return (*prev); } + inline pointer operator-> (void) const { return (&(operator*())); } + inline reverse_iterator& operator++ (void) { -- m_i; return (*this); } + inline reverse_iterator& operator-- (void) { ++ m_i; return (*this); } + inline reverse_iterator operator++ (int) { reverse_iterator prev (*this); -- m_i; return (prev); } + inline reverse_iterator operator-- (int) { reverse_iterator prev (*this); ++ m_i; return (prev); } + inline reverse_iterator& operator+= (size_t n) { m_i -= n; return (*this); } + inline reverse_iterator& operator-= (size_t n) { m_i += n; return (*this); } + inline reverse_iterator operator+ (size_t n) const { return (reverse_iterator (m_i - n)); } + inline reverse_iterator operator- (size_t n) const { return (reverse_iterator (m_i + n)); } + inline reference operator[] (uoff_t n) const { return (*(*this + n)); } + inline difference_type operator- (const reverse_iterator& i) const { return (distance (m_i, i.m_i)); } +protected: + Iterator m_i; +}; + +//---------------------------------------------------------------------- + +/// \class insert_iterator uiterator.h ustl.h +/// \ingroup IteratorAdaptors +/// \brief Calls insert on bound container for each assignment. +/// +template <class Container> +class insert_iterator { +public: + typedef typename Container::value_type value_type; + typedef typename Container::difference_type difference_type; + typedef typename Container::pointer pointer; + typedef typename Container::reference reference; + typedef typename Container::iterator iterator; +public: + explicit insert_iterator (Container& ctr, iterator ip) : m_rCtr (ctr), m_ip (ip) {} + inline insert_iterator& operator= (typename Container::const_reference v) + { m_ip = m_rCtr.insert (m_ip, v); return (*this); } + inline insert_iterator& operator* (void) { return (*this); } + inline insert_iterator& operator++ (void) { ++ m_ip; return (*this); } + inline insert_iterator operator++ (int) { insert_iterator prev (*this); ++ m_ip; return (*this); } +protected: + Container& m_rCtr; + iterator m_ip; +}; + +/// Returns the insert_iterator for \p ctr. +template <class Container> +inline insert_iterator<Container> inserter (Container& ctr, typename Container::iterator ip) +{ + return (insert_iterator<Container> (ctr, ip)); +} + +//---------------------------------------------------------------------- + +/// \class back_insert_iterator uiterator.h ustl.h +/// \ingroup IteratorAdaptors +/// \brief Calls push_back on bound container for each assignment. +/// +template <class Container> +class back_insert_iterator { +public: + typedef typename Container::value_type value_type; + typedef typename Container::difference_type difference_type; + typedef typename Container::pointer pointer; + typedef typename Container::reference reference; +public: + explicit back_insert_iterator (Container& ctr) : m_rCtr (ctr) {} + inline back_insert_iterator& operator= (typename Container::const_reference v) + { m_rCtr.push_back (v); return (*this); } + inline back_insert_iterator& operator* (void) { return (*this); } + inline back_insert_iterator& operator++ (void) { return (*this); } + inline back_insert_iterator operator++ (int) { return (*this); } +protected: + Container& m_rCtr; +}; + +/// Returns the back_insert_iterator for \p ctr. +template <class Container> +inline back_insert_iterator<Container> back_inserter (Container& ctr) +{ + return (back_insert_iterator<Container> (ctr)); +} + +//---------------------------------------------------------------------- + +/// \class index_iterate uiterator.h ustl.h +/// \ingroup IteratorAdaptors +/// +/// \brief Allows iteration through an index container. +/// +/// Converts an iterator into a container of uoff_t indexes to an +/// iterator of iterators into another container. +/// +template <typename RandomAccessIterator, typename IndexIterator> +class index_iterate { +public: + typedef RandomAccessIterator value_type; + typedef ptrdiff_t difference_type; + typedef RandomAccessIterator* pointer; + typedef RandomAccessIterator reference; +public: + index_iterate (void) : m_Base(), m_i() {} + index_iterate (RandomAccessIterator ibase, IndexIterator iindex) : m_Base (ibase), m_i (iindex) {} + inline bool operator== (const index_iterate& i) const { return (m_i == i.m_i); } + inline bool operator< (const index_iterate& i) const { return (m_i < i.m_i); } + inline bool operator== (const RandomAccessIterator& i) const { return (m_Base == i); } + inline bool operator< (const RandomAccessIterator& i) const { return (m_Base < i); } + inline IndexIterator base (void) const { return (m_i); } + inline reference operator* (void) const { return (advance(m_Base, *m_i)); } + inline pointer operator-> (void) const { return (&(operator*())); } + inline index_iterate& operator++ (void) { ++ m_i; return (*this); } + inline index_iterate& operator-- (void) { -- m_i; return (*this); } + inline index_iterate operator++ (int) { index_iterate prev (*this); ++ m_i; return (prev); } + inline index_iterate operator-- (int) { index_iterate prev (*this); -- m_i; return (prev); } + inline index_iterate& operator+= (size_t n) { m_i += n; return (*this); } + inline index_iterate& operator-= (size_t n) { m_i -= n; return (*this); } + inline index_iterate operator+ (size_t n) const { return (index_iterate (m_Base, m_i + n)); } + inline index_iterate operator- (size_t n) const { return (index_iterate (m_Base, m_i - n)); } + inline reference operator[] (uoff_t n) const { return (*(*this + n)); } + inline difference_type operator- (const index_iterate& i) const { return (distance (m_i, i.m_i)); } +private: + RandomAccessIterator m_Base; + IndexIterator m_i; +}; + +/// Returns an index_iterate for \p ibase over \p iindex. +template <typename RandomAccessIterator, typename IndexIterator> +inline index_iterate<RandomAccessIterator, IndexIterator> index_iterator (RandomAccessIterator ibase, IndexIterator iindex) +{ + return (index_iterate<RandomAccessIterator, IndexIterator> (ibase, iindex)); +} + +/// Converts the indexes in \p xc to iterators in \p ic of base \p ibase. +template <typename IndexContainer, typename IteratorContainer> +inline void indexv_to_iteratorv (typename IteratorContainer::value_type ibase, const IndexContainer& xc, IteratorContainer& ic) +{ + ic.resize (xc.size()); + copy_n (index_iterator (ibase, xc.begin()), xc.size(), ic.begin()); +} + +//---------------------------------------------------------------------- + +/// Converts the given const_iterator into an iterator. +/// +template <typename Container> +inline typename Container::iterator unconst (typename Container::const_iterator i, Container&) + { return (const_cast<typename Container::iterator>(i)); } + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#define IBYI(Iter1, Iter2, Ctr1, Ctr2) \ +template <typename Container1, typename Container2> \ +inline typename Container2::Iter2 ibyi (typename Container1::Iter1 idx, Ctr1& ctr1, Ctr2& ctr2) \ +{ \ + assert (ctr1.size() == ctr2.size()); \ + return (ctr2.begin() + (idx - ctr1.begin())); \ +} + +IBYI(const_iterator, const_iterator, const Container1, const Container2) +IBYI(iterator, iterator, Container1, Container2) +IBYI(const_iterator, iterator, const Container1, Container2) +IBYI(iterator, const_iterator, Container1, const Container2) + +#else // DOXYGEN + +#error This declaration is for doxygen only; it is not compiled. + +/// Converts a const_iterator in one container into a const_iterator in another container. +template <typename Container1, typename Container2> +inline typename Container2::iterator ibyi (typename Container1::iterator idx, Container1& ctr1, Container2& ctr2) {} + +#endif // DOXYGEN + +//---------------------------------------------------------------------- + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/ulaalgo.h @@ -0,0 +1,221 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef ULAALGO_H_2E403D182E83FB596AFB800E68B255A1 +#define ULAALGO_H_2E403D182E83FB596AFB800E68B255A1 + +#include "umatrix.h" +#include "simd.h" + +namespace ustl { + +/// \brief Creates an identity matrix in \p m +/// \ingroup NumericAlgorithms +template <size_t NX, size_t NY, typename T> +void load_identity (matrix<NX,NY,T>& m) +{ + fill_n (m.begin(), NX * NY, 0); + for (typename matrix<NX,NY,T>::iterator i = m.begin(); i < m.end(); i += NX + 1) + *i = 1; +} + +/// \brief Multiplies two matrices +/// \ingroup NumericAlgorithms +template <size_t NX, size_t NY, typename T> +matrix<NY,NY,T> operator* (const matrix<NX,NY,T>& m1, const matrix<NY,NX,T>& m2) +{ + matrix<NY,NY,T> mr; + for (uoff_t ry = 0; ry < NY; ++ ry) { + for (uoff_t rx = 0; rx < NY; ++ rx) { + T dpv (0); + for (uoff_t x = 0; x < NX; ++ x) + dpv += m1[ry][x] * m2[x][rx]; + mr[ry][rx] = dpv; + } + } + return (mr); +} + +/// \brief Transforms vector \p t with matrix \p m +/// \ingroup NumericAlgorithms +template <size_t NX, size_t NY, typename T> +tuple<NX,T> operator* (const tuple<NY,T>& t, const matrix<NX,NY,T>& m) +{ + tuple<NX,T> tr; + for (uoff_t x = 0; x < NX; ++ x) { + T dpv (0); + for (uoff_t y = 0; y < NY; ++ y) + dpv += t[y] * m[y][x]; + tr[x] = dpv; + } + return (tr); +} + +/// \brief Transposes (exchanges rows and columns) matrix \p m. +/// \ingroup NumericAlgorithms +template <size_t N, typename T> +void transpose (matrix<N,N,T>& m) +{ + for (uoff_t x = 0; x < N; ++ x) + for (uoff_t y = x; y < N; ++ y) + swap (m[x][y], m[y][x]); +} + +#if WANT_UNROLLED_COPY + +#if CPU_HAS_SSE + +#if linux // Non-linux gcc versions (BSD, Solaris) can't handle "x" constraint and provide no alternative. +template <> +inline void load_identity (matrix<4,4,float>& m) +{ + asm ( + "movaps %4, %%xmm1 \n\t" // 1 0 0 0 + "movups %4, %0 \n\t" // 1 0 0 0 + "shufps $0xB1,%%xmm1,%%xmm1 \n\t" // 0 1 0 0 + "movups %%xmm1, %1 \n\t" // 0 1 0 0 + "shufps $0x4F,%4,%%xmm1 \n\t" // 0 0 1 0 + "shufps $0x1B,%4,%4 \n\t" // 0 0 0 1 + "movups %%xmm1, %2 \n\t" // 0 0 1 0 + "movups %4, %3" // 0 0 0 1 + : "=m"(m[0][0]), "=m"(m[1][0]), "=m"(m[2][0]), "=m"(m[3][0]) + : "x"(1.0f) + : "xmm1", "memory" + ); + asm ("":::"memory"); +} +#endif + +inline void _sse_load_matrix (const float* m) +{ + asm ( + "movups %0, %%xmm4 \n\t" // xmm4 = m[1 2 3 4] + "movups %1, %%xmm5 \n\t" // xmm5 = m[1 2 3 4] + "movups %2, %%xmm6 \n\t" // xmm6 = m[1 2 3 4] + "movups %3, %%xmm7" // xmm7 = m[1 2 3 4] + : : "m"(m[0]), "m"(m[4]), "m"(m[8]), "m"(m[12]) + : "xmm4", "xmm5", "xmm6", "xmm7", "memory" + ); +} + +inline void _sse_transform_to_vector (float* result) +{ + asm ( + "movaps %%xmm0, %%xmm1 \n\t" // xmm1 = t[0 1 2 3] + "movaps %%xmm0, %%xmm2 \n\t" // xmm1 = t[0 1 2 3] + "movaps %%xmm0, %%xmm3 \n\t" // xmm1 = t[0 1 2 3] + "shufps $0x00, %%xmm0, %%xmm0 \n\t" // xmm0 = t[0 0 0 0] + "shufps $0x66, %%xmm1, %%xmm1 \n\t" // xmm1 = t[1 1 1 1] + "shufps $0xAA, %%xmm2, %%xmm2 \n\t" // xmm2 = t[2 2 2 2] + "shufps $0xFF, %%xmm3, %%xmm3 \n\t" // xmm3 = t[3 3 3 3] + "mulps %%xmm4, %%xmm0 \n\t" // xmm0 = t[0 0 0 0] * m[0 1 2 3] + "mulps %%xmm5, %%xmm1 \n\t" // xmm1 = t[1 1 1 1] * m[0 1 2 3] + "addps %%xmm1, %%xmm0 \n\t" // xmm0 = xmm0 + xmm1 + "mulps %%xmm6, %%xmm2 \n\t" // xmm2 = t[2 2 2 2] * m[0 1 2 3] + "mulps %%xmm7, %%xmm3 \n\t" // xmm3 = t[3 3 3 3] * m[0 1 2 3] + "addps %%xmm3, %%xmm2 \n\t" // xmm2 = xmm2 + xmm3 + "addps %%xmm2, %%xmm0 \n\t" // xmm0 = result + "movups %%xmm0, %0" + : "=m"(result[0]), "=m"(result[1]), "=m"(result[2]), "=m"(result[3]) : + : "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "memory" + ); +} + +template <> +inline tuple<4,float> operator* (const tuple<4,float>& t, const matrix<4,4,float>& m) +{ + tuple<4,float> result; + _sse_load_matrix (m.begin()); + asm ("movups %0, %%xmm0" : : "m"(t[0]), "m"(t[1]), "m"(t[2]), "m"(t[3]) : "xmm0", "memory"); + _sse_transform_to_vector (result.begin()); + return (result); +} + +template <> +inline matrix<4,4,float> operator* (const matrix<4,4,float>& m1, const matrix<4,4,float>& m2) +{ + matrix<4,4,float> result; + _sse_load_matrix (m2.begin()); + for (uoff_t r = 0; r < 4; ++ r) { + asm ("movups %0, %%xmm0" : : "m"(m1[r][0]), "m"(m1[r][1]), "m"(m1[r][2]), "m"(m1[r][3]) : "xmm0", "memory"); + _sse_transform_to_vector (result[r]); + } + return (result); +} + +#elif CPU_HAS_3DNOW + +/// Specialization for 4-component vector transform, the slow part of 3D graphics. +template <> +static tuple<4,float> operator* (const tuple<4,float>& t, const matrix<4,4,float>& m) +{ + tuple<4,float> result; + // This is taken from "AMD Athlon Code Optimization Guide" from AMD. 18 cycles! + // If you are writing a 3D engine, you may want to copy it instead of calling it + // because of the femms instruction at the end, which takes 2 cycles. + asm ( + "movq %2, %%mm0 \n\t" // y | x + "movq %3, %%mm1 \n\t" // w | z + "movq %%mm0, %%mm2 \n\t" // y | x + "movq %4, %%mm3 \n\t" // m[0][1] | m[0][0] + "punpckldq %%mm0, %%mm0 \n\t" // x | x + "movq %6, %%mm4 \n\t" // m[1][1] | m[1][0] + "pfmul %%mm0, %%mm3 \n\t" // x*m[0][1] | x*m[0][0] + "punpckhdq %%mm2, %%mm2 \n\t" // y | y + "pfmul %%mm2, %%mm4 \n\t" // y*m[1][1] | y*m[1][0] + "movq %5, %%mm5 \n\t" // m[0][3] | m[0][2] + "movq %7, %%mm7 \n\t" // m[1][3] | m[1][2] + "movq %%mm1, %%mm6 \n\t" // w | z + "pfmul %%mm0, %%mm5 \n\t" // x*m[0][3] | v0>x*m[0][2] + "movq %8, %%mm0 \n\t" // m[2][1] | m[2][0] + "punpckldq %%mm1, %%mm1 \n\t" // z | z + "pfmul %%mm2, %%mm7 \n\t" // y*m[1][3] | y*m[1][2] + "movq %9, %%mm2 \n\t" // m[2][3] | m[2][2] + "pfmul %%mm1, %%mm0 \n\t" // z*m[2][1] | z*m[2][0] + "pfadd %%mm4, %%mm3 \n\t" // x*m[0][1]+y*m[1][1] | x*m[0][0]+y*m[1][0] + "movq %10, %%mm4 \n\t" // m[3][1] | m[3][0] + "pfmul %%mm1, %%mm2 \n\t" // z*m[2][3] | z*m[2][2] + "pfadd %%mm7, %%mm5 \n\t" // x*m[0][3]+y*m[1][3] | x*m[0][2]+y*m[1][2] + "movq %11, %%mm1 \n\t" // m[3][3] | m[3][2] + "punpckhdq %%mm6, %%mm6 \n\t" // w | w + "pfadd %%mm0, %%mm3 \n\t" // x*m[0][1]+y*m[1][1]+z*m[2][1] | x*m[0][0]+y*m[1][0]+z*m[2][0] + "pfmul %%mm6, %%mm4 \n\t" // w*m[3][1] | w*m[3][0] + "pfmul %%mm6, %%mm1 \n\t" // w*m[3][3] | w*m[3][2] + "pfadd %%mm2, %%mm5 \n\t" // x*m[0][3]+y*m[1][3]+z*m[2][3] | x*m[0][2]+y*m[1][2]+z*m[2][2] + "pfadd %%mm4, %%mm3 \n\t" // x*m[0][1]+y*m[1][1]+z*m[2][1]+w*m[3][1] | x*m[0][0]+y*m[1][0]+z*m[2][0]+w*m[3][0] + "movq %%mm3, %0 \n\t" // store result->y | result->x + "pfadd %%mm1, %%mm5 \n\t" // x*m[0][3]+y*m[1][3]+z*m[2][3]+w*m[3][3] | x*m[0][2]+y*m[1][2]+z*m[2][2]+w*m[3][2] + "movq %%mm5, %1" // store result->w | result->z + : "=m"(result[0]), "=m"(result[2]) + : "m"(t[0]), "m"(t[2]), + "m"(m[0][0]), "m"(m[0][2]), + "m"(m[1][0]), "m"(m[1][2]), + "m"(m[2][0]), "m"(m[2][2]), + "m"(m[3][0]), "m"(m[3][2]) + : ALL_MMX_REGS_CHANGELIST, "memory" + ); + asm ("":::"memory"); + simd::reset_mmx(); + return (result); +} + +#else // If no processor extensions, just unroll the multiplication + +/// Specialization for 4-component vector transform, the slow part of 3D graphics. +template <> +static tuple<4,float> operator* (const tuple<4,float>& t, const matrix<4,4,float>& m) +{ + tuple<4,float> tr; + for (uoff_t i = 0; i < 4; ++ i) + tr[i] = t[0] * m[0][i] + t[1] * m[1][i] + t[2] * m[2][i] + t[3] * m[3][i]; + return (tr); +} + +#endif // CPU_HAS_3DNOW +#endif // WANT_UNROLLED_COPY + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/ulimits.h @@ -0,0 +1,104 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef ULIMITS_H_1C2192EA3821E0811BBAF86B0F048364 +#define ULIMITS_H_1C2192EA3821E0811BBAF86B0F048364 + +#include "utypes.h" + +namespace ustl { + +#define __limits_digits(T) (sizeof(T)*8) +#define __limits_digits10(T) (sizeof(T)*8*643/2136+1) + +/// \class numeric_limits ulimits.h ustl.h +/// \brief Defines numeric limits for a type. +/// +template <typename T> +struct numeric_limits { + /// Returns the minimum value for type T. + static inline T min (void) { return (T(0)); } + /// Returns the minimum value for type T. + static inline T max (void) { return (T(0)); } + static const bool is_signed = false; ///< True if the type is signed. + static const bool is_integer = false; ///< True if stores an exact value. + static const bool is_integral = false; ///< True if fixed size and cast-copyable. + static const unsigned digits = __limits_digits(T); ///< Number of bits in T + static const unsigned digits10 = __limits_digits10(T); ///< Maximum number of decimal digits in printed version of T +}; + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +template <typename T> +struct numeric_limits<T*> { + static inline T* min (void) { return (NULL); } + static inline T* max (void) { return (reinterpret_cast<T*>(UINTPTR_MAX)); } + static const bool is_signed = false; + static const bool is_integer = true; + static const bool is_integral = true; + static const unsigned digits = __limits_digits(T*); + static const unsigned digits10 = __limits_digits10(T*); +}; + +#define _NUMERIC_LIMITS(type, minVal, maxVal, bSigned, bInteger, bIntegral) \ +template <> \ +struct numeric_limits<type> { \ + static inline type min (void) { return (minVal); } \ + static inline type max (void) { return (maxVal); } \ + static const bool is_signed = bSigned; \ + static const bool is_integer = bInteger; \ + static const bool is_integral = bIntegral; \ + static const unsigned digits = __limits_digits(type); \ + static const unsigned digits10 = __limits_digits10(type); \ +} + +//-------------------------------------------------------------------------------------- +// type min max signed integer integral +//-------------------------------------------------------------------------------------- +_NUMERIC_LIMITS (bool, false, true, false, true, true); +_NUMERIC_LIMITS (char, CHAR_MIN, CHAR_MAX, true, true, true); +_NUMERIC_LIMITS (int, INT_MIN, INT_MAX, true, true, true); +_NUMERIC_LIMITS (short, SHRT_MIN, SHRT_MAX, true, true, true); +_NUMERIC_LIMITS (long, LONG_MIN, LONG_MAX, true, true, true); +#if HAVE_THREE_CHAR_TYPES +_NUMERIC_LIMITS (signed char, SCHAR_MIN, SCHAR_MAX, true, true, true); +#endif +_NUMERIC_LIMITS (unsigned char, 0, UCHAR_MAX, false, true, true); +_NUMERIC_LIMITS (unsigned int, 0, UINT_MAX, false, true, true); +_NUMERIC_LIMITS (unsigned short,0, USHRT_MAX, false, true, true); +_NUMERIC_LIMITS (unsigned long, 0, ULONG_MAX, false, true, true); +_NUMERIC_LIMITS (wchar_t, 0, WCHAR_MAX, false, true, true); +_NUMERIC_LIMITS (float, FLT_MIN, FLT_MAX, true, false, true); +_NUMERIC_LIMITS (double, DBL_MIN, DBL_MAX, true, false, true); +_NUMERIC_LIMITS (long double, LDBL_MIN, LDBL_MAX, true, false, true); +#if HAVE_LONG_LONG +_NUMERIC_LIMITS (long long, LLONG_MIN, LLONG_MAX, true, true, true); +_NUMERIC_LIMITS (unsigned long long, 0, ULLONG_MAX, false, true, true); +#endif +//-------------------------------------------------------------------------------------- + +#endif // DOXYGEN_SHOULD_SKIP_THIS + +/// Macro for defining numeric_limits specializations +#define NUMERIC_LIMITS(type, minVal, maxVal, bSigned, bInteger, bIntegral) \ +namespace ustl { _NUMERIC_LIMITS (type, minVal, maxVal, bSigned, bInteger, bIntegral); } + +/// \brief Returns the recommended stream alignment for type \p T. Override with ALIGNOF. +/// Because this is occasionally called with a null value, do not access the argument! +template <typename T> +inline size_t alignof (const T&) +{ + if (numeric_limits<T>::is_integral) + return (__alignof__(T)); + return (4); +} + +#define ALIGNOF(type,grain) \ +namespace ustl { \ + template <> inline size_t alignof (const type&) { return (grain); } } + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/ulist.h @@ -0,0 +1,74 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef ULIST_H_54E3B510498982C87A0A1E1932E6729D +#define ULIST_H_54E3B510498982C87A0A1E1932E6729D + +#include "uvector.h" +#include "uctralgo.h" + +namespace ustl { + +/// \class list ulist.h ustl.h +/// \ingroup Sequences +/// +/// \brief Linked list, defined as an alias to vector. +/// +template <typename T> +class list : public vector<T> { +public: + typedef typename vector<T>::size_type size_type; + typedef typename vector<T>::iterator iterator; + typedef typename vector<T>::const_iterator const_iterator; + typedef typename vector<T>::reference reference; + typedef typename vector<T>::const_reference const_reference; +public: + inline list (void) : vector<T> () {} + inline explicit list (size_type n) : vector<T> (n) {} + inline list (size_type n, const T& v) : vector<T> (n, v) {} + inline list (const list<T>& v) : vector<T> (v) {} + inline list (const_iterator i1, const_iterator i2) : vector<T> (i1, i2) {} + inline size_type size (void) const { return (vector<T>::size()); } + inline iterator begin (void) { return (vector<T>::begin()); } + inline const_iterator begin (void) const { return (vector<T>::begin()); } + inline iterator end (void) { return (vector<T>::end()); } + inline const_iterator end (void) const { return (vector<T>::end()); } + inline void push_front (const T& v) { insert (begin(), v); } + inline void pop_front (void) { erase (begin()); } + inline const_reference front (void) const { return (*begin()); } + inline reference front (void) { return (*begin()); } + inline void remove (const T& v) { ::ustl::remove (*this, v); } + inline void unique (void) { ::ustl::unique (*this); } + inline void sort (void) { ::ustl::sort (*this); } + void merge (list<T>& l); + void splice (iterator ip, list<T>& l, iterator first = NULL, iterator last = NULL); +}; + +/// Merges the contents with \p l. Assumes both lists are sorted. +template <typename T> +void list<T>::merge (list& l) +{ + list<T>::resize (size() + l.size()); + iterator me = merge (begin(), end(), l.begin(), l.end(), begin()); + list<T>::resize (distance (begin(), me)); +} + +/// Moves the range [first, last) from \p l to this list at \p ip. +template <typename T> +void list<T>::splice (iterator ip, list<T>& l, iterator first, iterator last) +{ + if (!first) + first = l.begin(); + if (!last) + last = l.end(); + insert (ip, first, last); + l.erase (first, last); +} + +#define deque list ///< list has all the functionality provided by deque + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/umap.h @@ -0,0 +1,160 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UMAP_H_45643F516E02A87A3DCEA5024052A6F5 +#define UMAP_H_45643F516E02A87A3DCEA5024052A6F5 + +#include "uvector.h" +#include "ufunction.h" + +namespace ustl { + +/// \class map umap.h ustl.h +/// \ingroup AssociativeContainers +/// +/// \brief A sorted associative container of pair<K,V> +/// +template <typename K, typename V> +class map : public vector<pair<K,V> > { +public: + typedef K key_type; + typedef V data_type; + typedef const K& const_key_ref; + typedef const V& const_data_ref; + typedef const map<K,V>& rcself_t; + typedef vector<pair<K,V> > base_class; + typedef typename base_class::value_type value_type; + typedef typename base_class::size_type size_type; + typedef typename base_class::pointer pointer; + typedef typename base_class::const_pointer const_pointer; + typedef typename base_class::reference reference; + typedef typename base_class::const_reference const_reference; + typedef typename base_class::const_iterator const_iterator; + typedef typename base_class::iterator iterator; + typedef typename base_class::reverse_iterator reverse_iterator; + typedef typename base_class::const_reverse_iterator const_reverse_iterator; + typedef pair<const_iterator,const_iterator> const_range_t; + typedef pair<iterator,iterator> range_t; + typedef pair<iterator,bool> insertrv_t; +public: + inline map (void) : vector<pair<K,V> > () {} + explicit inline map (size_type n) : vector<pair<K,V> > (n) {} + inline map (rcself_t v) : vector<pair<K,V> > (v) {} + inline map (const_iterator i1, const_iterator i2) : vector<pair<K,V> >() { insert (i1, i2); } + inline rcself_t operator= (rcself_t v) { base_class::operator= (v); return (*this); } + inline const_data_ref operator[] (const_key_ref i) const; + data_type& operator[] (const_key_ref i); + inline size_type size (void) const { return (base_class::size()); } + inline iterator begin (void) { return (base_class::begin()); } + inline const_iterator begin (void) const { return (base_class::begin()); } + inline iterator end (void) { return (base_class::end()); } + inline const_iterator end (void) const { return (base_class::end()); } + inline void assign (const_iterator i1, const_iterator i2) { clear(); insert (i1, i2); } + inline void push_back (const_reference v) { insert (v); } + inline const_iterator find (const_key_ref k) const; + inline iterator find (const_key_ref k) { return (const_cast<iterator> (const_cast<rcself_t>(*this).find (k))); } + inline const_iterator find_data (const_data_ref v, const_iterator first = NULL, const_iterator last = NULL) const; + inline iterator find_data (const_data_ref v, iterator first = NULL, iterator last = NULL); + insertrv_t insert (const_reference v); + void insert (const_iterator i1, const_iterator i2); + inline void erase (const_key_ref k); + inline iterator erase (iterator ep) { return (base_class::erase (ep)); } + inline iterator erase (iterator ep1, iterator ep2) { return (base_class::erase (ep1, ep2)); } + inline void clear (void) { base_class::clear(); } +private: + const_iterator lower_bound (const_key_ref k) const; + inline iterator lower_bound (const_key_ref k) { return (const_cast<iterator>(const_cast<rcself_t>(*this).lower_bound (k))); } +}; + +template <typename K, typename V> +typename map<K,V>::const_iterator map<K,V>::lower_bound (const_key_ref k) const +{ + const_iterator first (begin()), last (end()); + while (first != last) { + const_iterator mid = advance (first, distance (first,last) / 2); + if (mid->first < k) + first = advance (mid, 1); + else + last = mid; + } + return (first); +} + +/// Returns the pair<K,V> where K = \p k. +template <typename K, typename V> +inline typename map<K,V>::const_iterator map<K,V>::find (const_key_ref k) const +{ + const_iterator i = lower_bound (k); + return ((i < end() && k < i->first) ? end() : i); +} + +/// Returns the pair<K,V> where V = \p v, occuring in range [first,last). +template <typename K, typename V> +inline typename map<K,V>::const_iterator map<K,V>::find_data (const_data_ref v, const_iterator first, const_iterator last) const +{ + if (!first) first = begin(); + if (!last) last = end(); + for (; first != last && first->second != v; ++first) ; + return (first); +} + +/// Returns the pair<K,V> where V = \p v, occuring in range [first,last). +template <typename K, typename V> +inline typename map<K,V>::iterator map<K,V>::find_data (const_data_ref v, iterator first, iterator last) +{ + return (const_cast<iterator> (find_data (v, const_cast<const_iterator>(first), const_cast<const_iterator>(last)))); +} + +/// Returns data associated with key \p k. +template <typename K, typename V> +inline const typename map<K,V>::data_type& map<K,V>::operator[] (const_key_ref k) const +{ + assert (find(k) != end() && "operator[] const can not insert non-existent keys"); + return (find(k)->second); +} + +/// Returns data associated with key \p k. +template <typename K, typename V> +typename map<K,V>::data_type& map<K,V>::operator[] (const_key_ref k) +{ + iterator ip = lower_bound (k); + if (ip == end() || k < ip->first) + ip = base_class::insert (ip, make_pair (k, V())); + return (ip->second); +} + +/// Inserts the pair into the container. +template <typename K, typename V> +typename map<K,V>::insertrv_t map<K,V>::insert (const_reference v) +{ + iterator ip = lower_bound (v.first); + bool bInserted = ip == end() || v.first < ip->first; + if (bInserted) + ip = base_class::insert (ip, v); + return (make_pair (ip, bInserted)); +} + +/// Inserts elements from range [i1,i2) into the container. +template <typename K, typename V> +void map<K,V>::insert (const_iterator i1, const_iterator i2) +{ + assert (i1 <= i2); + reserve (size() + distance (i1, i2)); + for (; i1 != i2; ++i1) + insert (*i1); +} + +/// Erases the element with key value \p k. +template <typename K, typename V> +inline void map<K,V>::erase (const_key_ref k) +{ + iterator ip = find (k); + if (ip != end()) + erase (ip); +} + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/umatrix.h @@ -0,0 +1,121 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UMATRIX_H_740EBFEF554E833645E0FD72419A8185 +#define UMATRIX_H_740EBFEF554E833645E0FD72419A8185 + +#include "utuple.h" + +namespace ustl { + +/// \class matrix umatrix.h ustl.h +/// \ingroup Sequences +/// +/// \brief A two-dimensional array of NX*NY elements of type T. +/// +template <size_t NX, size_t NY, typename T> +class matrix : public tuple<NX*NY,T> { +public: + typedef tuple<NX,T> row_type; + typedef tuple<NY,T> column_type; + typedef tuple<NX*NY,T> tuple_type; + typedef typename tuple_type::value_type value_type; + typedef typename tuple_type::size_type size_type; + typedef typename tuple_type::pointer pointer; + typedef typename tuple_type::const_pointer const_pointer; + typedef typename tuple_type::reference reference; + typedef typename tuple_type::const_reference const_reference; + typedef typename tuple_type::iterator iterator; + typedef typename tuple_type::const_iterator const_iterator; + typedef typename tuple_type::range_t range_t; + typedef typename tuple_type::const_range_t const_range_t; + typedef typename tuple_type::reverse_iterator reverse_iterator; + typedef typename tuple_type::const_reverse_iterator const_reverse_iterator; +public: + inline matrix (void) { } + inline size_type columns (void) const { return (NX); } + inline size_type rows (void) const { return (NY); } + inline const_iterator at (size_type i) const { return (matrix::begin() + i * NX); } + inline iterator at (size_type i) { return (matrix::begin() + i * NX); } + inline const_iterator operator[] (size_type i) const { return (at (i)); } + inline iterator operator[] (size_type i) { return (at (i)); } + inline row_type row (size_type r) const { return (row_type (at (r))); } + inline column_type column (size_type c) const; + template <typename T2> + inline const matrix& operator= (const matrix<NX,NY,T2>& src) { tuple_type::operator= (src); return (*this); } + inline const matrix& operator= (const matrix<NX,NY,T>& src) { tuple_type::operator= (src); return (*this); } + inline const matrix& operator+= (const_reference v) { tuple_type::operator+= (v); return (*this); } + inline const matrix& operator-= (const_reference v) { tuple_type::operator-= (v); return (*this); } + inline const matrix& operator*= (const_reference v) { tuple_type::operator*= (v); return (*this); } + inline const matrix& operator/= (const_reference v) { tuple_type::operator/= (v); return (*this); } + inline const matrix operator+ (const_reference v) const + { matrix result (*this); result += v; return (result); } + inline const matrix operator- (const_reference v) const + { matrix result (*this); result -= v; return (result); } + inline const matrix operator* (const_reference v) const + { matrix result (*this); result *= v; return (result); } + inline const matrix operator/ (const_reference v) const + { matrix result (*this); result /= v; return (result); } +}; + +template <size_t NX, size_t NY, typename T> +inline typename matrix<NX,NY,T>::column_type matrix<NX,NY,T>::column (size_type c) const +{ + column_type result; + const_iterator src (matrix::begin() + c); + iterator dest (result.begin()); + for (uoff_t i = 0; i < NY; ++ i, ++ dest, src += NX) + *dest = *src; + return (result); +} + +//---------------------------------------------------------------------- +// Define SIMD specializations for member functions. + +#if CPU_HAS_SSE +#define MATRIX_R(v) "m"(v[0]),"m"(v[4]),"m"(v[8]),"m"(v[12]) +#define MATRIX_W(v) "=m"(v[0]),"=m"(v[4]),"=m"(v[8]),"=m"(v[12]) +#define SSE_TUPLE_SPECS(n,type) \ +template <> inline tuple<n,type>::tuple (void) \ +{ asm volatile ("xorps %%xmm0, %%xmm0\n\t" \ + "movups %%xmm0, %0\n\t" \ + "movups %%xmm0, %1\n\t" \ + "movups %%xmm0, %2\n\t" \ + "movups %%xmm0, %3" \ + : "=m"(m_v[0]),"=m"(m_v[4]),"=m"(m_v[8]),"=m"(m_v[12]) \ + ::"xmm0","memory"); \ +} \ +namespace simd { \ +SIMD_PASSIGN_SPEC(n,type) \ +{ \ + asm volatile ("movups %2, %%xmm0\n\t" \ + "movups %3, %%xmm1\n\t" \ + "movups %%xmm0, %0\n\t" \ + "movups %%xmm1, %1" \ + : "=m"(oout[0]),"=m"(oout[4]) \ + : "m"(oin[0]),"m"(oin[4]) \ + : "xmm0", "xmm1", "memory"); \ + asm volatile ("movups %2, %%xmm0\n\t" \ + "movups %3, %%xmm1\n\t" \ + "movups %%xmm0, %0\n\t" \ + "movups %%xmm1, %1" \ + : "=m"(oout[8]),"=m"(oout[12]) \ + : "m"(oin[8]),"m"(oin[12]) \ + : "xmm0", "xmm1", "memory"); \ +} \ +} +SSE_TUPLE_SPECS(16,float) +SSE_TUPLE_SPECS(16,int32_t) +SSE_TUPLE_SPECS(16,uint32_t) +#undef SSE_TUPLE_SPECS +#undef TOUCH_MATRIX_R +#undef TOUCH_MATRIX_W +#undef MATRIX_R +#undef MATRIX_W +#endif + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/umemory.h @@ -0,0 +1,193 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UMEMORY_H_4AB5B0DB5BF09140541409CC47BCD17A +#define UMEMORY_H_4AB5B0DB5BF09140541409CC47BCD17A + +#include "unew.h" +#if HAVE_ALLOCA_H + #include <alloca.h> +#else + #include <stdlib.h> +#endif +#include "upair.h" +#include "uiterator.h" +#include "ulimits.h" + +namespace ustl { + +/// \class auto_ptr umemory.h ustl.h +/// \ingroup MemoryManagement +/// +/// \brief A smart pointer. +/// +/// Calls delete in the destructor; assignment transfers ownership. +/// This class does not work with void pointers due to the absence +/// of the required dereference operator. +/// +template <typename T> +class auto_ptr { +public: + typedef T value_type; + typedef T* pointer; + typedef T& reference; +public: + /// Takes ownership of \p p. + inline explicit auto_ptr (pointer p = NULL) : m_p (p) {} + /// Takes ownership of pointer in \p p. \p p relinquishes ownership. + inline auto_ptr (auto_ptr<T>& p) : m_p (p.release()) {} + /// Deletes the owned pointer. + inline ~auto_ptr (void) { delete m_p; } + /// Returns the pointer without relinquishing ownership. + inline pointer get (void) const { return (m_p); } + /// Returns the pointer and gives up ownership. + inline pointer release (void) { pointer rv (m_p); m_p = NULL; return (rv); } + /// Deletes the pointer and sets it equal to \p p. + inline void reset (pointer p) { if (p != m_p) { delete m_p; m_p = p; } } + /// Takes ownership of \p p. + inline auto_ptr<T>& operator= (pointer p) { reset (p); return (*this); } + /// Takes ownership of pointer in \p p. \p p relinquishes ownership. + inline auto_ptr<T>& operator= (auto_ptr<T>& p) { reset (p.release()); return (*this); } + inline reference operator* (void) const { return (*m_p); } + inline pointer operator-> (void) const { return (m_p); } + inline bool operator== (const pointer p) const { return (m_p == p); } + inline bool operator== (const auto_ptr<T>& p) const { return (m_p == p.m_p); } + inline bool operator< (const auto_ptr<T>& p) const { return (p.m_p < m_p); } +private: + pointer m_p; +}; + +/// Calls the placement new on \p p. +/// \ingroup RawStorageAlgorithms +/// +template <typename T> +inline void construct (T* p) +{ + new (p) T; +} + +/// Calls the placement new on \p p. +/// \ingroup RawStorageAlgorithms +/// +template <typename ForwardIterator> +inline void construct (ForwardIterator first, ForwardIterator last) +{ + typedef typename iterator_traits<ForwardIterator>::value_type value_type; + if (!numeric_limits<value_type>::is_integral && first) + for (--last; first <= last; ++first) + construct (&*first); +} + +/// Calls the placement new on \p p. +/// \ingroup RawStorageAlgorithms +/// +template <typename T> +inline void construct (T* p, const T& value) +{ + new (p) T (value); +} + +/// Calls the destructor of \p p without calling delete. +/// \ingroup RawStorageAlgorithms +/// +template <typename T> +inline void destroy (T* p) throw() +{ + p->~T(); +} + +// Helper templates to not instantiate anything for integral types. +template <typename T> +void dtors (T first, T last) throw() + { for (--last; first <= last; ++first) destroy (&*first); } +template <typename T, bool bIntegral> +struct Sdtorsr { + inline void operator()(T first, T last) throw() { dtors (first, last); } +}; +template <typename T> +struct Sdtorsr<T,true> { + inline void operator()(T, T) throw() {} +}; + +/// Calls the destructor on elements in range [first, last) without calling delete. +/// \ingroup RawStorageAlgorithms +/// +template <typename ForwardIterator> +inline void destroy (ForwardIterator first, ForwardIterator last) throw() +{ + typedef typename iterator_traits<ForwardIterator>::value_type value_type; + Sdtorsr<ForwardIterator,numeric_limits<value_type>::is_integral>()(first, last); +} + +/// Casts \p p to the type of the second pointer argument. +template <typename T> inline T* cast_to_type (void* p, const T*) { return ((T*) p); } + +/// \brief Creates a temporary buffer pair from \p p and \p n +/// This is intended to be used with alloca to create temporary buffers. +/// The size in the returned pair is set to 0 if the allocation is unsuccessful. +/// \ingroup RawStorageAlgorithms +/// +template <typename T> +inline pair<T*, ptrdiff_t> make_temporary_buffer (void* p, size_t n, const T* ptype) +{ + return (make_pair (cast_to_type(p,ptype), ptrdiff_t(p ? n : 0))); +} + +#if HAVE_ALLOCA_H + /// \brief Allocates a temporary buffer, if possible. + /// \ingroup RawStorageAlgorithms + #define get_temporary_buffer(size, ptype) make_temporary_buffer (alloca(size_of_elements(size, ptype)), size, ptype) + #define return_temporary_buffer(p) +#else + #define get_temporary_buffer(size, ptype) make_temporary_buffer (malloc(size_of_elements(size, ptype)), size, ptype) + #define return_temporary_buffer(p) if (p) free (p), p = NULL +#endif + +/// Copies [first, last) into result by calling copy constructors in result. +/// \ingroup RawStorageAlgorithms +/// +template <typename InputIterator, typename ForwardIterator> +ForwardIterator uninitialized_copy (InputIterator first, InputIterator last, ForwardIterator result) +{ + for (; first < last; ++result, ++first) + construct (&*result, *first); + return (result); +} + +/// Copies [first, first + n) into result by calling copy constructors in result. +/// \ingroup RawStorageAlgorithms +/// +template <typename InputIterator, typename ForwardIterator> +ForwardIterator uninitialized_copy_n (InputIterator first, size_t n, ForwardIterator result) +{ + for (++n; --n; ++result, ++first) + construct (&*result, *first); + return (result); +} + +/// Calls construct on all elements in [first, last) with value \p v. +/// \ingroup RawStorageAlgorithms +/// +template <typename ForwardIterator, typename T> +void uninitialized_fill (ForwardIterator first, ForwardIterator last, const T& v) +{ + for (; first < last; ++first) + construct (&*first, v); +} + +/// Calls construct on all elements in [first, first + n) with value \p v. +/// \ingroup RawStorageAlgorithms +/// +template <typename ForwardIterator, typename T> +ForwardIterator uninitialized_fill_n (ForwardIterator first, size_t n, const T& v) +{ + for (++n; --n; ++first) + construct (&*first, v); + return (first); +} + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/umultimap.h @@ -0,0 +1,116 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UMULTIMAP_H_45743F516E02A87A3FCEA5024052A6F5 +#define UMULTIMAP_H_45743F516E02A87A3FCEA5024052A6F5 + +#include "uvector.h" +#include "ufunction.h" + +namespace ustl { + +/// \class multimap umultimap.h ustl.h +/// \ingroup AssociativeContainers +/// +/// \brief A sorted associative container that may container multiple entries for each key. +/// +template <typename K, typename V> +class multimap : public vector<pair<K,V> > { +public: + typedef K key_type; + typedef V data_type; + typedef const K& const_key_ref; + typedef const V& const_data_ref; + typedef const multimap<K,V>& rcself_t; + typedef vector<pair<K,V> > base_class; + typedef typename base_class::value_type value_type; + typedef typename base_class::size_type size_type; + typedef typename base_class::pointer pointer; + typedef typename base_class::const_pointer const_pointer; + typedef typename base_class::reference reference; + typedef typename base_class::const_reference const_reference; + typedef typename base_class::const_iterator const_iterator; + typedef typename base_class::iterator iterator; + typedef typename base_class::reverse_iterator reverse_iterator; + typedef typename base_class::const_reverse_iterator const_reverse_iterator; + typedef pair<const_iterator,const_iterator> const_range_t; + typedef pair<iterator,iterator> range_t; +public: + inline multimap (void) : vector<pair<K,V> > () {} + explicit inline multimap (size_type n) : vector<pair<K,V> > (n) {} + inline multimap (rcself_t v) : vector<pair<K,V> > (v) {} + inline multimap (const_iterator i1, const_iterator i2) : vector<pair<K,V> > () { insert (i1, i2); } + inline rcself_t operator= (rcself_t v) { base_class::operator= (v); return (*this); } + inline size_type size (void) const { return (base_class::size()); } + inline iterator begin (void) { return (base_class::begin()); } + inline const_iterator begin (void) const { return (base_class::begin()); } + inline iterator end (void) { return (base_class::end()); } + inline const_iterator end (void) const { return (base_class::end()); } + inline void assign (const_iterator i1, const_iterator i2) { clear(); insert (i1, i2); } + inline size_type count (const_key_ref k) const { return (upper_bound(k) - lower_bound(k)); } + inline void push_back (const_reference v) { insert (v); } + inline const_range_t equal_range (const_key_ref k) const { return (make_pair (lower_bound(k), upper_bound(k))); } + inline range_t equal_range (const_key_ref k) { return (make_pair (const_cast<iterator>(lower_bound(k)), const_cast<iterator>(upper_bound(k)))); } + const_iterator lower_bound (const_key_ref k) const; + const_iterator upper_bound (const_key_ref k) const; + inline iterator insert (const_reference v); + void insert (const_iterator i1, const_iterator i2); + inline void erase (const_key_ref k) { erase (const_cast<iterator>(lower_bound(k)), const_cast<iterator>(upper_bound(k))); } + inline iterator erase (iterator ep) { return (base_class::erase (ep)); } + inline iterator erase (iterator ep1, iterator ep2) { return (base_class::erase (ep1, ep2)); } + inline void clear (void) { base_class::clear(); } +}; + +/// Returns an iterator to the first element with key value \p k. +template <typename K, typename V> +typename multimap<K,V>::const_iterator multimap<K,V>::lower_bound (const_key_ref k) const +{ + const_iterator first (begin()), last (end()); + while (first != last) { + const_iterator mid = advance (first, distance (first,last) / 2); + if (mid->first < k) + first = advance (mid, 1); + else + last = mid; + } + return (first); +} + +/// Returns an iterator to the first element with key value \p k. +template <typename K, typename V> +typename multimap<K,V>::const_iterator multimap<K,V>::upper_bound (const_key_ref k) const +{ + const_iterator first (begin()), last (end()); + while (first != last) { + const_iterator mid = advance (first, distance (first,last) / 2); + if (k < mid->first) + last = mid; + else + first = advance (mid, 1); + } + return (last); +} + +/// Inserts the pair into the container. +template <typename K, typename V> +inline typename multimap<K,V>::iterator multimap<K,V>::insert (const_reference v) +{ + iterator ip = const_cast<iterator> (upper_bound (v.first)); + return (base_class::insert (ip, v)); +} + +/// Inserts elements from range [i1,i2) into the container. +template <typename K, typename V> +void multimap<K,V>::insert (const_iterator i1, const_iterator i2) +{ + assert (i1 <= i2); + reserve (size() + distance (i1, i2)); + for (; i1 != i2; ++i1) + insert (*i1); +} + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/umultiset.h @@ -0,0 +1,101 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UMULTISET_H_446AEDBB7F61C6994DC228C25D5FA3A1 +#define UMULTISET_H_446AEDBB7F61C6994DC228C25D5FA3A1 + +#include "uvector.h" +#include "ualgo.h" + +namespace ustl { + +/// \class multiset umultiset.h ustl.h +/// \ingroup AssociativeContainers +/// +/// \brief Multiple sorted container. +/// Unlike set, it may contain multiple copies of each element. +/// +template <typename T> +class multiset : public vector<T> { +public: + typedef const multiset<T>& rcself_t; + typedef vector<T> base_class; + typedef typename base_class::value_type value_type; + typedef typename base_class::size_type size_type; + typedef typename base_class::pointer pointer; + typedef typename base_class::const_pointer const_pointer; + typedef typename base_class::reference reference; + typedef typename base_class::const_reference const_reference; + typedef typename base_class::const_iterator const_iterator; + typedef typename base_class::iterator iterator; + typedef typename base_class::reverse_iterator reverse_iterator; + typedef typename base_class::const_reverse_iterator const_reverse_iterator; +public: + inline multiset (void) : vector<T> () {} + explicit inline multiset (size_type n) : vector<T> (n) {} + inline multiset (rcself_t v) : vector<T> (v) {} + inline multiset (const_iterator i1, const_iterator i2) : vector<T> () { insert (i1, i2); } + inline rcself_t operator= (rcself_t v) { base_class::operator= (v); return (*this); } + inline size_type size (void) const { return (base_class::size()); } + inline iterator begin (void) { return (base_class::begin()); } + inline const_iterator begin (void) const { return (base_class::begin()); } + inline iterator end (void) { return (base_class::end()); } + inline const_iterator end (void) const { return (base_class::end()); } + inline void assign (const_iterator i1, const_iterator i2); + size_type count (const_reference v) const; + inline void push_back (const_reference v) { insert (v); } + inline iterator insert (const_reference v); + void insert (const_iterator i1, const_iterator i2); + void erase (const_reference v); + inline iterator erase (iterator ep) { return (base_class::erase (ep)); } + inline iterator erase (iterator ep1, iterator ep2) { return (base_class::erase (ep1, ep2)); } + inline void clear (void) { base_class::clear(); } +}; + +/// Copies contents of range [i1,i2) +template <typename T> +inline void multiset<T>::assign (const_iterator i1, const_iterator i2) +{ + base_class::clear(); + insert (i1, i2); +} + +/// Returns the number of elements of value \p v. +template <typename T> +typename multiset<T>::size_type multiset<T>::count (const_reference v) const +{ + const pair<const_iterator,const_iterator> fr = equal_range (begin(), end(), v); + return (distance (fr.first, fr.second)); +} + +/// Inserts \p v. +template <typename T> +inline typename multiset<T>::iterator multiset<T>::insert (const_reference v) +{ + iterator ip = upper_bound (begin(), end(), v); + return (base_class::insert (ip, v)); +} + +/// Inserts all elements from range [i1,i2). +template <typename T> +void multiset<T>::insert (const_iterator i1, const_iterator i2) +{ + assert (i1 <= i2); + reserve (size() + distance (i1, i2)); + for (; i1 < i2; ++i1) + push_back (*i1); +} + +/// Erases all elements with value \p v. +template <typename T> +void multiset<T>::erase (const_reference v) +{ + pair<iterator,iterator> epr = equal_range (begin(), end(), v); + erase (epr.first, epr.second); +} + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/unew.h @@ -0,0 +1,47 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UNEW_H_11D237512B324C9C05A55DAF1BF086F1 +#define UNEW_H_11D237512B324C9C05A55DAF1BF086F1 + +#include "uexception.h" +#include <stdlib.h> + +/// Just like malloc, but throws on failure. +void* tmalloc (size_t n) throw (ustl::bad_alloc) __attribute__((malloc)); +/// Just like free, but doesn't crash when given a NULL. +inline void nfree (void* p) throw() { if (p) free (p); } + +#if WITHOUT_LIBSTDCPP + +// +// These are replaceable signatures: +// - normal single new and delete (no arguments, throw @c bad_alloc on error) +// - normal array new and delete (same) +// - @c nothrow single new and delete (take a @c nothrow argument, return +// @c NULL on error) +// - @c nothrow array new and delete (same) +// +// Placement new and delete signatures (take a memory address argument, +// does nothing) may not be replaced by a user's program. +// +inline void* operator new (size_t n) throw (ustl::bad_alloc) { return (tmalloc (n)); } +inline void* operator new[] (size_t n) throw (ustl::bad_alloc) { return (tmalloc (n)); } +inline void operator delete (void* p) throw() { nfree (p); } +inline void operator delete[] (void* p) throw() { nfree (p); } + +// Default placement versions of operator new. +inline void* operator new (size_t, void* p) throw() { return (p); } +inline void* operator new[] (size_t, void* p) throw() { return (p); } + +// Default placement versions of operator delete. +inline void operator delete (void*, void*) throw() { } +inline void operator delete[](void*, void*) throw() { } + +#else +#include <new> +#endif // WITHOUT_LIBSTDCPP + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/unumeric.h @@ -0,0 +1,154 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UNUMERIC_H_6C99D6F6363832C644A6FFF336E84E18 +#define UNUMERIC_H_6C99D6F6363832C644A6FFF336E84E18 + +namespace ustl { + +/// Returns the sum of all elements in [first, last) added to \p init. +/// \ingroup NumericAlgorithms +/// +template <typename InputIterator, typename T> +inline T accumulate (InputIterator first, InputIterator last, T init) +{ + while (first < last) + init += *first++; + return (init); +} + +/// Returns the sum of all elements in [first, last) via \p op, added to \p init. +/// \ingroup NumericAlgorithms +/// +template <typename InputIterator, typename T, typename BinaryFunction> +inline T accumulate (InputIterator first, InputIterator last, T init, BinaryFunction binary_op) +{ + while (first < last) + init = binary_op (init, *first++); + return (init); +} + +/// Assigns range [value, value + (last - first)) to [first, last) +/// \ingroup NumericAlgorithms +/// +template <typename ForwardIterator, typename T> +inline void iota (ForwardIterator first, ForwardIterator last, T value) +{ + while (first < last) + *first++ = value++; +} + +/// Returns the sum of products of respective elements in the given ranges. +/// \ingroup NumericAlgorithms +/// +template <typename InputIterator1, typename InputIterator2, typename T> +inline T inner_product (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init) +{ + while (first1 < last1) + init += *first1++ * *first2++; + return (init); +} + +/// Returns the sum of products of respective elements in the given ranges. +/// \ingroup NumericAlgorithms +/// +template <typename InputIterator1, typename InputIterator2, typename T, + typename BinaryOperation1, typename BinaryOperation2> +inline T inner_product +(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init, + BinaryOperation1 sumOp, BinaryOperation2 productOp) +{ + while (first1 < last1) + init = sumOp (init, productOp (*first1++, *first2++)); + return (init); +} + +/// Writes result such that result[i] = sum (first...first+i) +/// \ingroup NumericAlgorithms +/// +template <typename InputIterator, typename OutputIterator> +inline OutputIterator partial_sum (InputIterator first, InputIterator last, OutputIterator result) +{ + if (first < last) + *result = *first++; + while (first < last) + *++result = *first++ + *result; + return (result); +} + +/// Writes result such that result[i] = sumOp (first...first+i) +/// \ingroup NumericAlgorithms +/// +template <typename InputIterator, typename OutputIterator, typename BinaryOperation> +inline OutputIterator partial_sum (InputIterator first, InputIterator last, OutputIterator result, BinaryOperation sumOp) +{ + if (first < last) + *result = *first++; + while (first < last) + *++result = sumOp (*first++, *result); + return (result); +} + +/// Writes result such that result[i] = first[i] - first[i - 1] +/// \ingroup NumericAlgorithms +/// +template <typename InputIterator, typename OutputIterator> +inline OutputIterator adjacent_difference (InputIterator first, InputIterator last, OutputIterator result) +{ + if (first < last) + *result++ = *first++; + while (first < last) + *result++ = *first - *(first - 1); + return (result); +} + +/// Writes result such that result[i] = differenceOp (first[i], first[i - 1]) +/// \ingroup NumericAlgorithms +/// +template <typename InputIterator, typename OutputIterator, typename BinaryOperation> +inline OutputIterator adjacent_difference (InputIterator first, InputIterator last, OutputIterator result, BinaryOperation differenceOp) +{ + if (first < last) + *result++ = *first++; + while (first < last) + *result++ = differenceOp (*first, *(first - 1)); + return (result); +} + +/// \brief Returns x^n. +/// Donald Knuth's Russian Peasant algorithm. +/// \ingroup NumericAlgorithms +/// +template <typename T> +inline T power (T x, unsigned n) +{ + T result (n % 2 ? x : 1); + while (n /= 2) { + x *= x; + if (n % 2) + result *= x; + } + return (result); +} + +/// \brief Returns x^n, using \p op instead of multiplication. +/// Donald Knuth's Russian Peasant algorithm. +/// \ingroup NumericAlgorithms +/// +template <typename T, typename BinaryOperation> +inline T power (T x, unsigned n, BinaryOperation op) +{ + T result (n % 2 ? x : 1); + while (n /= 2) { + x = op (x, x); + if (n % 2) + result = op (result, x); + } + return (result); +} + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/upair.h @@ -0,0 +1,59 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UPAIR_H_7DC08F1B7FECF8AE6856D84C3B617A75 +#define UPAIR_H_7DC08F1B7FECF8AE6856D84C3B617A75 + +#include "utypes.h" + +namespace ustl { + +/// \class pair upair.h ustl.h +/// \ingroup AssociativeContainers +/// +/// \brief Container for two values. +/// +template <typename T1, typename T2> +class pair { +public: + typedef T1 first_type; + typedef T2 second_type; +public: + /// Default constructor. + inline pair (void) : first (T1()), second (T2()) {} + /// Initializes members with \p a, and \p b. + inline pair (const T1& a, const T2& b) : first (a), second (b) {} + inline pair& operator= (const pair<T1, T2>& p2) { first = p2.first; second = p2.second; return (*this); } + template <typename T3, typename T4> + inline pair& operator= (const pair<T3, T4>& p2) { first = p2.first; second = p2.second; return (*this); } +public: + first_type first; + second_type second; +}; + +/// Compares both values of \p p1 to those of \p p2. +template <typename T1, typename T2> +inline bool operator== (const pair<T1,T2>& p1, const pair<T1,T2>& p2) +{ + return (p1.first == p2.first && p1.second == p2.second); +} + +/// Compares both values of \p p1 to those of \p p2. +template <typename T1, typename T2> +bool operator< (const pair<T1,T2>& p1, const pair<T1,T2>& p2) +{ + return (p1.first < p2.first || (p1.first == p2.first && p1.second < p2.second)); +} + +/// Returns a pair object with (a,b) +template <typename T1, typename T2> +inline pair<T1,T2> make_pair (const T1& a, const T2& b) +{ + return (pair<T1,T2> (a, b)); +} + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/upredalgo.h @@ -0,0 +1,587 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UPREDALGO_H_2CB058AE0807A01A2F6A51BA5D5820A5 +#define UPREDALGO_H_2CB058AE0807A01A2F6A51BA5D5820A5 + +namespace ustl { + +/// Copy_if copies elements from the range [first, last) to the range +/// [result, result + (last - first)) if pred(*i) returns true. +/// \ingroup MutatingAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename InputIterator, typename OutputIterator, typename Predicate> +inline OutputIterator copy_if (InputIterator first, InputIterator last, OutputIterator result, Predicate pred) +{ + for (; first != last; ++first) { + if (pred(*first)) { + *result = *first; + ++ result; + } + } + return (result); +} + +/// Returns the first iterator i in the range [first, last) such that +/// pred(*i) is true. Returns last if no such iterator exists. +/// \ingroup SearchingAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename InputIterator, typename Predicate> +inline InputIterator find_if (InputIterator first, InputIterator last, Predicate pred) +{ + while (first != last && !pred (*first)) + ++ first; + return (first); +} + +/// Returns the first iterator such that p(*i, *(i + 1)) == true. +/// \ingroup SearchingAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename ForwardIterator, typename BinaryPredicate> +inline ForwardIterator adjacent_find (ForwardIterator first, ForwardIterator last, BinaryPredicate p) +{ + if (first != last) + for (ForwardIterator prev = first; ++first != last; ++ prev) + if (p (*prev, *first)) + return (prev); + return (last); +} + +/// Returns the pointer to the first pair of unequal elements. +/// \ingroup SearchingAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename InputIterator, typename BinaryPredicate> +inline pair<InputIterator,InputIterator> +mismatch (InputIterator first1, InputIterator last1, InputIterator first2, BinaryPredicate comp) +{ + while (first1 != last1 && comp(*first1, *first2)) + ++ first1, ++ first2; + return (make_pair (first1, first2)); +} + +/// Returns true if two ranges are equal. +/// This is an extension, present in uSTL and SGI STL. +/// \ingroup ConditionAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename InputIterator, typename BinaryPredicate> +inline bool equal (InputIterator first1, InputIterator last1, InputIterator first2, BinaryPredicate comp) +{ + return (mismatch (first1, last1, first2, comp).first == last1); +} + +/// Count_if finds the number of elements in [first, last) that satisfy the +/// predicate pred. More precisely, the first version of count_if returns the +/// number of iterators i in [first, last) such that pred(*i) is true. +/// \ingroup ConditionAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename InputIterator, typename Predicate> +inline size_t count_if (InputIterator first, InputIterator last, Predicate pred) +{ + size_t total = 0; + for (; first != last; ++first) + if (pred (*first)) + ++ total; + return (total); +} + +/// Replace_if replaces every element in the range [first, last) for which +/// pred returns true with new_value. That is: for every iterator i, if +/// pred(*i) is true then it performs the assignment *i = new_value. +/// \ingroup MutatingAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename ForwardIterator, typename Predicate, typename T> +inline void replace_if (ForwardIterator first, ForwardIterator last, Predicate pred, const T& new_value) +{ + for (; first != last; ++first) + if (pred (*first)) + *first = new_value; +} + +/// Replace_copy_if copies elements from the range [first, last) to the range +/// [result, result + (last-first)), except that any element for which pred is +/// true is not copied; new_value is copied instead. More precisely, for every +/// integer n such that 0 <= n < last-first, replace_copy_if performs the +/// assignment *(result+n) = new_value if pred(*(first+n)), +/// and *(result+n) = *(first+n) otherwise. +/// \ingroup MutatingAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename InputIterator, typename OutputIterator, typename Predicate, typename T> +inline OutputIterator replace_copy_if (InputIterator first, InputIterator last, OutputIterator result, Predicate pred, const T& new_value) +{ + for (; first != last; ++result, ++first) + *result = pred(*first) ? new_value : *first; +} + +/// Remove_copy_if copies elements from the range [first, last) to a range +/// beginning at result, except that elements for which pred is true are not +/// copied. The return value is the end of the resulting range. This operation +/// is stable, meaning that the relative order of the elements that are copied +/// is the same as in the range [first, last). +/// \ingroup MutatingAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename InputIterator, typename OutputIterator, typename Predicate> +inline OutputIterator remove_copy_if (InputIterator first, InputIterator last, OutputIterator result, Predicate pred) +{ + for (; first != last; ++first) + if (pred (*first)) + *result++ = *first; + return (result); +} + +/// Remove_if removes from the range [first, last) every element x such that +/// pred(x) is true. That is, remove_if returns an iterator new_last such that +/// the range [first, new_last) contains no elements for which pred is true. +/// The iterators in the range [new_last, last) are all still dereferenceable, +/// but the elements that they point to are unspecified. Remove_if is stable, +/// meaning that the relative order of elements that are not removed is +/// unchanged. +/// \ingroup MutatingAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename ForwardIterator, typename Predicate> +inline ForwardIterator remove_if (ForwardIterator first, ForwardIterator last, Predicate pred) +{ + return (remove_copy_if (first, last, first, pred)); +} + +/// The reason there are two different versions of unique_copy is that there +/// are two different definitions of what it means for a consecutive group of +/// elements to be duplicates. In the first version, the test is simple +/// equality: the elements in a range [f, l) are duplicates if, for every +/// iterator i in the range, either i == f or else *i == *(i-1). In the second, +/// the test is an arbitrary Binary Predicate binary_pred: the elements in +/// [f, l) are duplicates if, for every iterator i in the range, either +/// i == f or else binary_pred(*i, *(i-1)) is true. +/// \ingroup MutatingAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename InputIterator, typename OutputIterator, typename BinaryPredicate> +OutputIterator unique_copy (InputIterator first, InputIterator last, OutputIterator result, BinaryPredicate binary_pred) +{ + if (first != last) { + *result = *first; + while (++first != last) + if (!binary_pred (*first, *result)) + *++result = *first; + ++ result; + } + return (result); +} + +/// Every time a consecutive group of duplicate elements appears in the range +/// [first, last), the algorithm unique removes all but the first element. +/// That is, unique returns an iterator new_last such that the range [first, +/// new_last) contains no two consecutive elements that are duplicates. +/// The iterators in the range [new_last, last) are all still dereferenceable, +/// but the elements that they point to are unspecified. Unique is stable, +/// meaning that the relative order of elements that are not removed is +/// unchanged. +/// \ingroup MutatingAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename ForwardIterator, typename BinaryPredicate> +inline ForwardIterator unique (ForwardIterator first, ForwardIterator last, BinaryPredicate binary_pred) +{ + return (unique_copy (first, last, first, binary_pred)); +} + +/// Returns the furthermost iterator i in [first, last) such that, +/// for every iterator j in [first, i), comp(*j, value) is true. +/// Assumes the range is sorted. +/// \ingroup SearchingAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename ForwardIterator, typename T, typename StrictWeakOrdering> +ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& value, StrictWeakOrdering comp) +{ + ForwardIterator mid; + while (first != last) { + mid = advance (first, distance (first,last) / 2); + if (comp (*mid, value)) + first = mid + 1; + else + last = mid; + } + return (first); +} + +/// Performs a binary search inside the sorted range. +/// \ingroup SearchingAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename ForwardIterator, typename T, typename StrictWeakOrdering> +inline bool binary_search (ForwardIterator first, ForwardIterator last, const T& value, StrictWeakOrdering comp) +{ + ForwardIterator found = lower_bound (first, last, value, comp); + return (found != last && !comp(*found, value)); +} + +/// Returns the furthermost iterator i in [first,last) such that for +/// every iterator j in [first,i), comp(value,*j) is false. +/// \ingroup SearchingAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename ForwardIterator, typename T, typename StrictWeakOrdering> +ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& value, StrictWeakOrdering comp) +{ + ForwardIterator mid; + while (first != last) { + mid = advance (first, distance (first,last) / 2); + if (comp (value, *mid)) + last = mid; + else + first = mid + 1; + } + return (last); +} + +/// Returns pair<lower_bound,upper_bound> +/// \ingroup SearchingAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename ForwardIterator, typename T, typename StrictWeakOrdering> +inline pair<ForwardIterator,ForwardIterator> equal_range (ForwardIterator first, ForwardIterator last, const T& value, StrictWeakOrdering comp) +{ + pair<ForwardIterator,ForwardIterator> rv; + rv.second = rv.first = lower_bound (first, last, value, comp); + while (rv.second != last && !comp(value, *(rv.second))) + ++ rv.second; + return (rv); +} + +/// \brief Puts \p nth element into its sorted position. +/// In this implementation, the entire array is sorted. The performance difference is +/// so small and the function use is so rare, there is no need to have code for it. +/// \ingroup SortingAlgorithms +/// \ingroup SearchingAlgorithms +/// \ingroup PredicateAlgorithms +/// +template <typename RandomAccessIterator, typename Compare> +inline void nth_element (RandomAccessIterator first, RandomAccessIterator, RandomAccessIterator last, Compare comp) +{ + sort (first, last, comp); +} + +/// \brief Searches for the first subsequence [first2,last2) in [first1,last1) +/// \ingroup SearchingAlgorithms +/// \ingroup PredicateAlgorithms +template <typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate> +ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate comp) +{ + const ForwardIterator1 slast = last1 - distance(first2, last2) + 1; + for (; first1 < slast; ++first1) { + ForwardIterator2 i = first2; + ForwardIterator1 j = first1; + for (; i != last2 && comp(*j, *i); ++i, ++j) ; + if (i == last2) + return (first1); + } + return (last1); +} + +/// \brief Searches for the last subsequence [first2,last2) in [first1,last1) +/// \ingroup SearchingAlgorithms +/// \ingroup PredicateAlgorithms +template <typename ForwardIterator1, typename ForwardIterator2, typename BinaryPredicate> +ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate comp) +{ + ForwardIterator1 s = last1 - distance(first2, last2); + for (; first1 < s; --s) { + ForwardIterator2 i = first2, j = s; + for (; i != last2 && comp(*j, *i); ++i, ++j) ; + if (i == last2) + return (s); + } + return (last1); +} + +/// \brief Searches for the first occurence of \p count \p values in [first, last) +/// \ingroup SearchingAlgorithms +/// \ingroup PredicateAlgorithms +template <typename Iterator, typename T, typename BinaryPredicate> +Iterator search_n (Iterator first, Iterator last, size_t count, const T& value, BinaryPredicate comp) +{ + size_t n = 0; + for (; first != last; ++first) { + if (!comp (*first, value)) + n = 0; + else if (++n == count) + return (first - --n); + } + return (last); +} + +/// \brief Searches [first1,last1) for the first occurrence of an element from [first2,last2) +/// \ingroup SearchingAlgorithms +/// \ingroup PredicateAlgorithms +template <typename InputIterator, typename ForwardIterator, typename BinaryPredicate> +InputIterator find_first_of (InputIterator first1, InputIterator last1, ForwardIterator first2, ForwardIterator last2, BinaryPredicate comp) +{ + for (; first1 != last1; ++first1) + for (ForwardIterator i = first2; i != last2; ++i) + if (comp (*first1, *i)) + return (first1); + return (first1); +} + +/// \brief Returns true if [first2,last2) is a subset of [first1,last1) +/// \ingroup ConditionAlgorithms +/// \ingroup SetAlgorithms +/// \ingroup PredicateAlgorithms +template <typename InputIterator1, typename InputIterator2, typename StrictWeakOrdering> +bool includes (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, StrictWeakOrdering comp) +{ + for (; (first1 != last1) & (first2 != last2); ++first1) { + if (comp (*first2, *first1)) + return (false); + first2 += !comp (*first1, *first2); + } + return (first2 == last2); +} + +/// \brief Merges [first1,last1) with [first2,last2) +/// +/// Result will contain every element that is in either set. If duplicate +/// elements are present, max(n,m) is placed in the result. +/// +/// \ingroup SetAlgorithms +/// \ingroup PredicateAlgorithms +template <typename InputIterator1, typename InputIterator2, typename OutputIterator, typename StrictWeakOrdering> +OutputIterator set_union (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, StrictWeakOrdering comp) +{ + for (; (first1 != last1) & (first2 != last2); ++result) { + if (comp (*first2, *first1)) + *result = *first2++; + else { + first2 += !comp (*first1, *first2); + *result = *first1++; + } + } + return (copy (first2, last2, copy (first1, last1, result))); +} + +/// \brief Creates a set containing elements shared by the given ranges. +/// \ingroup SetAlgorithms +/// \ingroup PredicateAlgorithms +template <typename InputIterator1, typename InputIterator2, typename OutputIterator, typename StrictWeakOrdering> +OutputIterator set_intersection (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, StrictWeakOrdering comp) +{ + while ((first1 != last1) & (first2 != last2)) { + bool b1ge2 = !comp (*first1, *first2), b2ge1 = !comp (*first2, *first1); + if (b1ge2 & b2ge1) + *result++ = *first1; + first1 += b2ge1; + first2 += b1ge2; + } + return (result); +} + +/// \brief Removes from [first1,last1) elements present in [first2,last2) +/// \ingroup SetAlgorithms +/// \ingroup PredicateAlgorithms +template <typename InputIterator1, typename InputIterator2, typename OutputIterator, typename StrictWeakOrdering> +OutputIterator set_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, StrictWeakOrdering comp) +{ + while ((first1 != last1) & (first2 != last2)) { + bool b1ge2 = !comp (*first1, *first2), b2ge1 = !comp (*first2, *first1); + if (!b1ge2) + *result++ = *first1; + first1 += b2ge1; + first2 += b1ge2; + } + return (copy (first1, last1, result)); +} + +/// \brief Performs union of sets A-B and B-A. +/// \ingroup SetAlgorithms +/// \ingroup PredicateAlgorithms +template <typename InputIterator1, typename InputIterator2, typename OutputIterator, typename StrictWeakOrdering> +OutputIterator set_symmetric_difference (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, StrictWeakOrdering comp) +{ + while ((first1 != last1) & (first2 != last2)) { + bool b1l2 = comp (*first1, *first2), b2l1 = comp (*first2, *first1); + if (b1l2) + *result++ = *first1; + else if (b2l1) + *result++ = *first2; + first1 += !b2l1; + first2 += !b1l2; + } + return (copy (first2, last2, copy (first1, last1, result))); +} + +/// \brief Returns true if the given range is sorted. +/// \ingroup ConditionAlgorithms +/// \ingroup PredicateAlgorithms +template <typename ForwardIterator, typename StrictWeakOrdering> +bool is_sorted (ForwardIterator first, ForwardIterator last, StrictWeakOrdering comp) +{ + for (ForwardIterator i = first; ++i < last; ++first) + if (comp (*i, *first)) + return (false); + return (true); +} + +/// \brief Compares two given containers like strcmp compares strings. +/// \ingroup ConditionAlgorithms +/// \ingroup PredicateAlgorithms +template <typename InputIterator1, typename InputIterator2, typename BinaryPredicate> +bool lexicographical_compare (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate comp) +{ + for (; (first1 != last1) & (first2 != last2); ++first1, ++first2) { + if (comp (*first1, *first2)) + return (true); + if (comp (*first2, *first1)) + return (false); + } + return ((first1 == last1) & (first2 != last2)); +} + +/// \brief Creates the next lexicographical permutation of [first,last). +/// Returns false if no further permutations can be created. +/// \ingroup GeneratorAlgorithms +/// \ingroup PredicateAlgorithms +template <typename BidirectionalIterator, typename StrictWeakOrdering> +bool next_permutation (BidirectionalIterator first, BidirectionalIterator last, StrictWeakOrdering comp) +{ + if (distance (first, last) < 2) + return (false); + BidirectionalIterator i = last; + for (--i; i != first; ) { + --i; + if (comp (i[0], i[1])) { + BidirectionalIterator j = last; + while (!comp (*i, *--j)) ; + iter_swap (i, j); + reverse (i + 1, last); + return (true); + } + } + reverse (first, last); + return (false); +} + +/// \brief Creates the previous lexicographical permutation of [first,last). +/// Returns false if no further permutations can be created. +/// \ingroup GeneratorAlgorithms +/// \ingroup PredicateAlgorithms +template <typename BidirectionalIterator, typename StrictWeakOrdering> +bool prev_permutation (BidirectionalIterator first, BidirectionalIterator last, StrictWeakOrdering comp) +{ + if (distance (first, last) < 2) + return (false); + BidirectionalIterator i = last; + for (--i; i != first; ) { + --i; + if (comp(i[1], i[0])) { + BidirectionalIterator j = last; + while (!comp (*--j, *i)) ; + iter_swap (i, j); + reverse (i + 1, last); + return (true); + } + } + reverse (first, last); + return (false); +} + +/// \brief Returns iterator to the max element in [first,last) +/// \ingroup SearchingAlgorithms +/// \ingroup PredicateAlgorithms +template <typename ForwardIterator, typename BinaryPredicate> +inline ForwardIterator max_element (ForwardIterator first, ForwardIterator last, BinaryPredicate comp) +{ + ForwardIterator result = first; + for (; first != last; ++first) + if (comp (*result, *first)) + result = first; + return (result); +} + +/// \brief Returns iterator to the min element in [first,last) +/// \ingroup SearchingAlgorithms +/// \ingroup PredicateAlgorithms +template <typename ForwardIterator, typename BinaryPredicate> +inline ForwardIterator min_element (ForwardIterator first, ForwardIterator last, BinaryPredicate comp) +{ + ForwardIterator result = first; + for (; first != last; ++first) + if (comp (*first, *result)) + result = first; + return (result); +} + +/// \brief Makes [first,middle) a part of the sorted array. +/// Contents of [middle,last) is undefined. This implementation just calls stable_sort. +/// \ingroup SortingAlgorithms +/// \ingroup PredicateAlgorithms +template <typename RandomAccessIterator, typename StrictWeakOrdering> +inline void partial_sort (RandomAccessIterator first, RandomAccessIterator, RandomAccessIterator last, StrictWeakOrdering comp) +{ + stable_sort (first, last, comp); +} + +/// \brief Like partial_sort, but outputs to [result_first,result_last) +/// \ingroup SortingAlgorithms +/// \ingroup PredicateAlgorithms +template <typename InputIterator, typename RandomAccessIterator, typename StrictWeakOrdering> +RandomAccessIterator partial_sort_copy (InputIterator first, InputIterator last, RandomAccessIterator result_first, RandomAccessIterator result_last, StrictWeakOrdering comp) +{ + RandomAccessIterator rend = result_first; + for (; first != last; ++first) { + RandomAccessIterator i = result_first; + for (; i != rend && comp (*i, *first); ++i) ; + if (i == result_last) + continue; + rend += (rend < result_last); + copy_backward (i, rend - 1, rend); + *i = *first; + } + return (rend); +} + +/// \brief Like partition, but preserves equal element order. +/// \ingroup SortingAlgorithms +/// \ingroup PredicateAlgorithms +template <typename ForwardIterator, typename Predicate> +ForwardIterator stable_partition (ForwardIterator first, ForwardIterator last, Predicate pred) +{ + if (first == last) + return (first); + ForwardIterator l, r, m = advance (first, distance (first, last) / 2); + if (first == m) + return (pred(*first) ? last : first); + l = stable_partition (first, m, pred); + r = stable_partition (m, last, pred); + rotate (l, m, r); + return (advance (l, distance (m, r))); +} + +/// \brief Splits [first,last) in two by \p pred. +/// +/// Creates two ranges [first,middle) and [middle,last), where every element +/// in the former is less than every element in the latter. +/// The return value is middle. +/// +/// \ingroup SortingAlgorithms +/// \ingroup PredicateAlgorithms +template <typename ForwardIterator, typename Predicate> +inline ForwardIterator partition (ForwardIterator first, ForwardIterator last, Predicate pred) +{ + return (stable_partition (first, last, pred)); +} + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/uqueue.h @@ -0,0 +1,69 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UQUEUE_H_27F01FDB0D59B75277E0E5C41ABC6B5B +#define UQUEUE_H_27F01FDB0D59B75277E0E5C41ABC6B5B + +namespace ustl { + +/// \class queue uqueue.h ustl.h +/// \ingroup Sequences +/// +/// \brief Queue adapter to uSTL containers. +/// +/// The most efficient way to use this implementation is to fill the queue +/// and the completely empty it before filling again. +/// +template <typename T> +class queue { +public: + typedef T value_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T& reference; + typedef const T& const_reference; + typedef T* pointer; + typedef const T* const_pointer; +public: + inline queue (void) : m_Storage (), m_Front (0) { } + explicit inline queue (const vector<T>& s) : m_Storage (s), m_Front (0) { } + explicit inline queue (const queue& s) : m_Storage (s.m_Storage), m_Front (0) { } + inline size_type size (void) const { return (m_Storage.size() - m_Front); } + inline bool empty (void) const { return (!size()); } + inline reference front (void) { return (m_Storage [m_Front]); } + inline const_reference front (void) const { return (m_Storage [m_Front]); } + inline reference back (void) { return (m_Storage.back()); } + inline const_reference back (void) const { return (m_Storage.back()); } + inline void push (const value_type& v); + inline void pop (void); + inline bool operator== (const queue& s) const { return (m_Storage == s.m_Storage && m_Front == s.m_Front); } + inline bool operator< (const queue& s) const { return (size() < s.size()); } +private: + vector<T> m_Storage; ///< Where the data actually is. + size_type m_Front; ///< Index of the element returned by next pop. +}; + +/// Pushes \p v on the queue. +template <typename T> +inline void queue<T>::push (const value_type& v) +{ + if (m_Front) { + m_Storage.erase (m_Storage.begin(), m_Front); + m_Front = 0; + } + m_Storage.push_back (v); +} + +/// Pops the topmost element from the queue. +template <typename T> +inline void queue<T>::pop (void) +{ + if (++m_Front >= m_Storage.size()) + m_Storage.resize (m_Front = 0); +} + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/uset.h @@ -0,0 +1,91 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef USET_H_45543F516E02A87A3FCEA5024052A6F5 +#define USET_H_45543F516E02A87A3FCEA5024052A6F5 + +#include "uvector.h" + +namespace ustl { + +/// \class set uset.h ustl.h +/// \ingroup Sequences +/// +/// \brief Unique sorted container. Sorted vector with all values unique. +/// +template <typename T> +class set : public vector<T> { +public: + typedef const set<T>& rcself_t; + typedef vector<T> base_class; + typedef typename base_class::value_type key_type; + typedef typename base_class::value_type data_type; + typedef typename base_class::value_type value_type; + typedef typename base_class::size_type size_type; + typedef typename base_class::pointer pointer; + typedef typename base_class::const_pointer const_pointer; + typedef typename base_class::reference reference; + typedef typename base_class::const_reference const_reference; + typedef typename base_class::const_iterator const_iterator; + typedef typename base_class::iterator iterator; + typedef typename base_class::reverse_iterator reverse_iterator; + typedef typename base_class::const_reverse_iterator const_reverse_iterator; + typedef pair<iterator,bool> insertrv_t; +public: + inline set (void) : vector<T> () { } + explicit inline set (size_type n) : vector<T> (n) { } + inline set (rcself_t v) : vector<T> (v) { } + inline set (const_iterator i1, const_iterator i2) : vector<T> () { insert (i1, i2); } + inline rcself_t operator= (rcself_t v) { base_class::operator= (v); return (*this); } + inline size_type size (void) const { return (base_class::size()); } + inline iterator begin (void) { return (base_class::begin()); } + inline const_iterator begin (void) const { return (base_class::begin()); } + inline iterator end (void) { return (base_class::end()); } + inline const_iterator end (void) const { return (base_class::end()); } + inline void assign (const_iterator i1, const_iterator i2) { clear(); insert (i1, i2); } + inline void push_back (const_reference v) { insert (v); } + inline const_iterator find (const_reference v) const { const_iterator i = lower_bound (begin(), end(), v); return ((i != end() && *i == v) ? i : end()); } + inline iterator find (const_reference v) { return (const_cast<iterator>(const_cast<rcself_t>(*this).find (v))); } + insertrv_t insert (const_reference v); + inline void insert (const_iterator i1, const_iterator i2); + inline void erase (const_reference v); + inline iterator erase (iterator ep) { return (base_class::erase (ep)); } + inline iterator erase (iterator ep1, iterator ep2) { return (base_class::erase (ep1, ep2)); } + inline void clear (void) { base_class::clear(); } +}; + +/// Inserts \p v into the container, maintaining the sort order. +template <typename T> +typename set<T>::insertrv_t set<T>::insert (const_reference v) +{ + iterator ip = lower_bound (begin(), end(), v); + bool bInserted = (ip == end() || v < *ip); + if (bInserted) + ip = base_class::insert (ip, v); + return (make_pair (ip, bInserted)); +} + +/// Inserts the contents of range [i1,i2) +template <typename T> +void set<T>::insert (const_iterator i1, const_iterator i2) +{ + assert (i1 <= i2); + reserve (size() + distance (i1, i2)); + for (; i1 < i2; ++i1) + push_back (*i1); +} + +/// Erases the element with value \p v. +template <typename T> +inline void set<T>::erase (const_reference v) +{ + iterator ip = find (v); + if (ip != end()) + erase (ip); +} + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/uspecial.h @@ -0,0 +1,260 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef USPECIAL_H_947ADYOU0ARE3YOU2REALLY8ARE44CE0 +#define USPECIAL_H_947ADYOU0ARE3YOU2REALLY8ARE44CE0 + +#include "uvector.h" +#include "ustring.h" +#include "uset.h" +#include "umultiset.h" +#include "ubitset.h" +#include "ulaalgo.h" +#include "uctralgo.h" +#include "ufunction.h" +#include "uctrstrm.h" +#include "sistream.h" +#include <ctype.h> + +namespace ustl { + +//---------------------------------------------------------------------- +// Alogrithm specializations not in use by the library code. +//---------------------------------------------------------------------- + +template <> inline void swap (cmemlink& a, cmemlink& b) { a.swap (b); } +template <> inline void swap (memlink& a, memlink& b) { a.swap (b); } +template <> inline void swap (memblock& a, memblock& b) { a.swap (b); } +template <> inline void swap (string& a, string& b) { a.swap (b); } +#define TEMPLATE_SWAP_PSPEC(type, template_decl) \ +template_decl inline void swap (type& a, type& b) { a.swap (b); } +TEMPLATE_SWAP_PSPEC (TEMPLATE_TYPE1 (vector,T), TEMPLATE_DECL1 (T)) +TEMPLATE_SWAP_PSPEC (TEMPLATE_TYPE1 (set,T), TEMPLATE_DECL1 (T)) +TEMPLATE_SWAP_PSPEC (TEMPLATE_TYPE1 (multiset,T), TEMPLATE_DECL1 (T)) +TEMPLATE_SWAP_PSPEC (TEMPLATE_TYPE2 (tuple,N,T), TEMPLATE_FULL_DECL2 (size_t,N,typename,T)) + +//---------------------------------------------------------------------- +// Streamable definitions. Not used in the library and require streams. +//---------------------------------------------------------------------- + +//----{ pair }---------------------------------------------------------- + +/// \brief Reads pair \p p from stream \p is. +template <typename T1, typename T2> +istream& operator>> (istream& is, pair<T1,T2>& p) +{ + is >> p.first; + is.align (alignof(p.second)); + is >> p.second; + is.align (alignof(p.first)); + return (is); +} + +/// Writes pair \p p to stream \p os. +template <typename T1, typename T2> +ostream& operator<< (ostream& os, const pair<T1,T2>& p) +{ + os << p.first; + os.align (alignof(p.second)); + os << p.second; + os.align (alignof(p.first)); + return (os); +} + +/// Writes pair \p p to stream \p os. +template <typename T1, typename T2> +ostringstream& operator<< (ostringstream& os, const pair<T1,T2>& p) +{ + os << '(' << p.first << ',' << p.second << ')'; + return (os); +} + +/// Returns the written size of the object. +template <typename T1, typename T2> +struct object_stream_size<pair<T1,T2> > { + inline size_t operator()(const pair<T1,T2>& v) const + { + return (Align (stream_size_of(v.first), alignof(v.second)) + + Align (stream_size_of(v.second), alignof(v.first))); + } +}; + +/// \brief Takes a pair and returns pair.first +/// This is an extension, available in uSTL and the SGI STL. +template <typename Pair> struct select1st : public unary_function<Pair,typename Pair::first_type> { + typedef typename Pair::first_type result_type; + inline const result_type& operator()(const Pair& a) const { return (a.first); } + inline result_type& operator()(Pair& a) const { return (a.first); } +}; + +/// \brief Takes a pair and returns pair.second +/// This is an extension, available in uSTL and the SGI STL. +template <typename Pair> struct select2nd : public unary_function<Pair,typename Pair::second_type> { + typedef typename Pair::second_type result_type; + inline const result_type& operator()(const Pair& a) const { return (a.second); } + inline result_type& operator()(Pair& a) const { return (a.second); } +}; + +/// \brief Converts a const_iterator pair into an iterator pair +/// Useful for converting pair ranges returned by equal_range, for instance. +/// This is an extension, available in uSTL. +template <typename Container> +inline pair<typename Container::iterator, typename Container::iterator> +unconst (const pair<typename Container::const_iterator, typename Container::const_iterator>& i, Container&) +{ + typedef pair<typename Container::iterator, typename Container::iterator> unconst_pair_t; + return (*noalias_cast<unconst_pair_t*>(&i)); +} + +//----{ vector }-------------------------------------------------------- + +template <typename T> +inline size_t alignof (const vector<T>&) +{ + typedef typename vector<T>::written_size_type written_size_type; + return (alignof (written_size_type())); +} + +//----{ bitset }-------------------------------------------------------- + +/// Writes bitset \p v into stream \p os. +template <size_t Size> +istringstream& operator>> (istringstream& is, bitset<Size>& v) +{ + char c; + for (int i = Size; --i >= 0 && (is >> c).good();) + v.set (i, c == '1'); + return (is); +} + +//----{ tuple }--------------------------------------------------------- + +template <size_t N, typename T> +inline istream& operator>> (istream& is, tuple<N,T>& v) + { v.read (is); return (is); } +template <size_t N, typename T> +inline ostream& operator<< (ostream& os, const tuple<N,T>& v) + { v.write (os); return (os); } +template <size_t N, typename T> +inline ostringstream& operator<< (ostringstream& os, const tuple<N,T>& v) + { v.text_write (os); return (os); } + +template <size_t N, typename T> +struct numeric_limits<tuple<N,T> > { + typedef numeric_limits<T> value_limits; + static inline tuple<N,T> min (void) { tuple<N,T> v; fill (v, value_limits::min()); return (v); } + static inline tuple<N,T> max (void) { tuple<N,T> v; fill (v, value_limits::max()); return (v); } + static const bool is_signed = value_limits::is_signed; + static const bool is_integer = value_limits::is_integer; + static const bool is_integral = value_limits::is_integral; +}; + +template <size_t N, typename T> +inline size_t alignof (const tuple<N,T>&) { return (alignof (NullValue<T>())); } + +template <typename T, typename IntT> +inline ostringstream& chartype_text_write (ostringstream& os, const T& v) +{ + os.format (_FmtPrtChr[!isprint(v)], v); + return (os); +} + +template <> +inline ostringstream& container_element_text_write (ostringstream& os, const uint8_t& v) +{ return (chartype_text_write<uint8_t, unsigned int> (os, v)); } +template <> +inline ostringstream& container_element_text_write (ostringstream& os, const int8_t& v) +{ return (chartype_text_write<int8_t, int> (os, v)); } + +//----{ matrix }-------------------------------------------------------- + +/// Writes tuple \p v into stream \p os. +template <size_t NX, size_t NY, typename T> +ostringstream& operator<< (ostringstream& os, const matrix<NX,NY,T>& v) +{ + os << '('; + for (uoff_t row = 0; row < NY; ++ row) { + os << '('; + for (uoff_t column = 0; column < NX; ++column) + os << v[row][column] << ",)"[column == NX-1]; + } + os << ')'; + return (os); +} + +//----{ long4grain }---------------------------------------------------- + +#if SIZE_OF_LONG == 8 && HAVE_INT64_T +// Helper class for long4grain and ptr4grain wrappers. +class _long4grain { +public: + inline _long4grain (uint64_t v) : m_v (v) {} +#if __x86_64__ + inline void read (istream& is) + { + assert (is.aligned(4)); + #if WANT_STREAM_BOUNDS_CHECKING + if (!is.verify_remaining ("read", "long4grain", sizeof(m_v))) return; + #else + assert (is.remaining() >= sizeof(m_v)); + #endif + m_v = *reinterpret_cast<const uint64_t*>(is.ipos()); + is.skip (sizeof(m_v)); + } + inline void write (ostream& os) const + { + assert (os.aligned(4)); + #if WANT_STREAM_BOUNDS_CHECKING + if (!os.verify_remaining ("write", "long4grain", sizeof(m_v))) return; + #else + assert (os.remaining() >= sizeof(m_v)); + #endif + *reinterpret_cast<uint64_t*>(os.ipos()) = m_v; + os.skip (sizeof(m_v)); + } +#elif USTL_BYTE_ORDER == USTL_BIG_ENDIAN + inline void read (istream& is) { uint32_t vl, vh; is >> vh >> vl; m_v = (uint64_t(vh) << 32) | uint64_t(vl); } + inline void write (ostream& os) const { os << uint32_t(m_v >> 32) << uint32_t(m_v); } +#else + inline void read (istream& is) { uint32_t vl, vh; is >> vl >> vh; m_v = (uint64_t(vh) << 32) | uint64_t(vl); } + inline void write (ostream& os) const { os << uint32_t(m_v) << uint32_t(m_v >> 32); } +#endif + inline size_t stream_size (void) const { return (stream_size_of(m_v)); } +private: + uint64_t m_v; +}; + +/// Wrap long values to allow writing them on 4-grain even on 64bit platforms. +inline _long4grain& long4grain (unsigned long& v) { asm("":"+m"(v)); return (*noalias_cast<_long4grain*>(&v)); } +/// Wrap long values to allow writing them on 4-grain even on 64bit platforms. +inline const _long4grain long4grain (const unsigned long& v) { return (_long4grain(v)); } +/// Wrap pointer values to allow writing them on 4-grain even on 64bit platforms. +template <typename T> +inline _long4grain& ptr4grain (T*& p) { asm("":"+m"(p)); return (*noalias_cast<_long4grain*>(&p)); } +/// Wrap pointer values to allow writing them on 4-grain even on 64bit platforms. +template <typename T> +inline const _long4grain ptr4grain (const T* const& p) { return (_long4grain(uintptr_t(p))); } +#else // if not SIZE_OF_LONG == 8 && HAVE_INT64_T +inline unsigned long& long4grain (unsigned long& v) { return (v); } +inline const unsigned long& long4grain (const unsigned long& v) { return (v); } +template <typename T> inline T*& ptr4grain (T*& p) { return (p); } +template <typename T> inline const T* const& ptr4grain (const T* const& p) { return (p); } +#endif // SIZE_OF_LONG == 8 + +//---------------------------------------------------------------------- + +} // namespace ustl + +// This is here because there really is no other place to put it. +#if SIZE_OF_BOOL != SIZE_OF_CHAR +// bool is a big type on some machines (like DEC Alpha), so it's written as a byte. +ALIGNOF(bool, sizeof(uint8_t)) +CAST_STREAMABLE(bool, uint8_t) +#endif +#if SIZE_OF_LONG == 8 && HAVE_INT64_T +ALIGNOF (_long4grain, 4) +#endif + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/ustack.h @@ -0,0 +1,44 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef USTACK_H_5242F5635322B2EC44A9AEE73022C6E9 +#define USTACK_H_5242F5635322B2EC44A9AEE73022C6E9 + +namespace ustl { + +/// \class stack ustack.h ustl.h +/// \ingroup Sequences +/// +/// \brief Stack adapter to uSTL containers. +/// +template <typename T> +class stack { +public: + typedef T value_type; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T& reference; + typedef const T& const_reference; + typedef T* pointer; + typedef const T* const_pointer; +public: + inline stack (void) : m_Storage () { } + explicit inline stack (const vector<T>& s) : m_Storage (s) { } + explicit inline stack (const stack& s) : m_Storage (s.m_Storage) { } + inline bool empty (void) const { return (m_Storage.empty()); } + inline size_type size (void) const { return (m_Storage.size()); } + inline reference top (void) { return (m_Storage.back()); } + inline const_reference top (void) const { return (m_Storage.back()); } + inline void push (const value_type& v) { m_Storage.push_back (v); } + inline void pop (void) { m_Storage.pop_back(); } + inline bool operator== (const stack& s) const { return (m_Storage == s.m_Storage); } + inline bool operator< (const stack& s) const { return (m_Storage.size() < s.m_Storage.size()); } +private: + vector<T> m_Storage; ///< Where the data actually is. +}; + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/ustdxept.h @@ -0,0 +1,140 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef USTDXEPT_H_46F7AE967738B588038F95E41158D7FF +#define USTDXEPT_H_46F7AE967738B588038F95E41158D7FF + +#include "uexception.h" +#include "ustring.h" + +namespace ustl { + +enum { + xfmt_ErrorMessage = 2, + xfmt_LogicError = xfmt_ErrorMessage, + xfmt_RuntimeError = xfmt_ErrorMessage +}; + +/// \class logic_error ustdxept.h ustl.h +/// \ingroup Exceptions +/// +/// \brief Logic errors represent problems in the internal logic of the program. +/// +class error_message : public exception { +public: + explicit error_message (const char* arg) throw(); + virtual ~error_message (void) throw(); + inline virtual const char* what (void) const throw() { return (m_Arg.c_str()); } + inline virtual const char* name (void) const throw() { return ("error"); } + virtual void info (string& msgbuf, const char* fmt = NULL) const throw(); + virtual void read (istream& is); + virtual void write (ostream& os) const; + virtual size_t stream_size (void) const; +protected: + string m_Arg; +}; + +/// \class logic_error ustdxept.h ustl.h +/// \ingroup Exceptions +/// +/// \brief Logic errors represent problems in the internal logic of the program. +/// +class logic_error : public error_message { +public: + inline explicit logic_error (const char* arg) throw() : error_message (arg) {} + inline virtual const char* name (void) const throw() { return ("logic error"); } +}; + +/// \class domain_error ustdxept.h ustl.h +/// \ingroup Exceptions +/// +/// \brief Reports domain errors ("domain" is in the mathematical sense) +/// +class domain_error : public logic_error { +public: + inline explicit domain_error (const char* arg) throw() : logic_error (arg) {} + inline virtual const char* name (void) const throw() { return ("domain error"); } +}; + +/// \class invalid_argument ustdxept.h ustl.h +/// \ingroup Exceptions +/// +/// \brief Reports an invalid argument to a function. +/// +class invalid_argument : public logic_error { +public: + inline explicit invalid_argument (const char* arg) throw() : logic_error (arg) {} + inline virtual const char* name (void) const throw() { return ("invalid argument"); } +}; + +/// \class length_error ustdxept.h ustl.h +/// \ingroup Exceptions +/// +/// \brief Reports when an object exceeds its allowed size. +/// +class length_error : public logic_error { +public: + inline explicit length_error (const char* arg) throw() : logic_error (arg) {} + inline virtual const char* name (void) const throw() { return ("length error"); } +}; + +/// \class out_of_range ustdxept.h ustl.h +/// \ingroup Exceptions +/// +/// \brief Reports arguments with values out of allowed range. +/// +class out_of_range : public logic_error { +public: + inline explicit out_of_range (const char* arg) throw() : logic_error (arg) {} + inline virtual const char* name (void) const throw() { return ("out of range"); } +}; + +/// \class runtime_error ustdxept.h ustl.h +/// \ingroup Exceptions +/// +/// \brief Reports errors that are dependent on the data being processed. +/// +class runtime_error : public error_message { +public: + inline explicit runtime_error (const char* arg) throw() : error_message (arg) {} + inline virtual const char* name (void) const throw() { return ("runtime error"); } +}; + +/// \class range_error ustdxept.h ustl.h +/// \ingroup Exceptions +/// +/// \brief Reports data that does not fall within the permitted range. +/// +class range_error : public runtime_error { +public: + inline explicit range_error (const char* arg) throw() : runtime_error (arg) {} + inline virtual const char* name (void) const throw() { return ("range error"); } +}; + +/// \class overflow_error ustdxept.h ustl.h +/// \ingroup Exceptions +/// +/// \brief Reports arithmetic overflow. +/// +class overflow_error : public runtime_error { +public: + inline explicit overflow_error (const char* arg) throw() : runtime_error (arg) {} + inline virtual const char* name (void) const throw() { return ("overflow error"); } +}; + +/// \class underflow_error ustdxept.h ustl.h +/// \ingroup Exceptions +/// +/// \brief Reports arithmetic underflow. +/// +class underflow_error : public runtime_error { +public: + inline explicit underflow_error (const char* arg) throw() : runtime_error (arg) {} + inline virtual const char* name (void) const throw() { return ("underflow error"); } +}; + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/ustlecos.h @@ -0,0 +1,78 @@ +#ifndef CYGONCE_USTLECOS_H +#define CYGONCE_USTLECOS_H +// ========================================================================== +// +// ustlecos.h +// +// eCos specific implementations and additions to uSTL library +// +// =========================================================================== +// ####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2009 Free Software Foundation, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later +// version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License +// along with eCos; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// As a special exception, if other files instantiate templates or use +// macros or inline functions from this file, or you compile this file +// and link it with other works to produce a work based on this file, +// this file does not by itself cause the resulting work to be covered by +// the GNU General Public License. However the source code for this file +// must still be made available in accordance with section (3) of the GNU +// General Public License v2. +// +// This exception does not invalidate any other reasons why a work based +// on this file might be covered by the GNU General Public License. +// ------------------------------------------- +// ####ECOSGPLCOPYRIGHTEND#### +// =========================================================================== +// =========================================================================== +// #####DESCRIPTIONBEGIN#### +// +// Author(s): Uwe Kindler +// Contributors: +// Date: 2009-07-28 +// Purpose: eCos specific additions to uSTL library +// Description: +// Usage: Do not include directly #include <ustl.h> +// +// ####DESCRIPTIONEND#### +// +// ========================================================================*/ + + +// +// If exception handling is disabled then we provide a low level and +// lightwight "exeption handler" +// +#ifndef __EXCEPTIONS +namespace ustl +{ + +typedef void (*app_exception_handler_t)(const exception& ex); + + +// allow an application to register its own ustl exception handler +void set_app_exception_handler(app_exception_handler_t func); + +// an application exception handler may use this function to print the +// exception to diagnostic output +void diag_print_exception(const exception& ex); +} // namespace ustl +#endif + +// --------------------------------------------------------------------------- +#endif // CYGONCE_USTLECOS_H
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/ustring.h @@ -0,0 +1,268 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef USTRING_H_1249CB7A098A9010763AAC6D37B133CF +#define USTRING_H_1249CB7A098A9010763AAC6D37B133CF + +#include "memblock.h" +#include "utf8.h" +#include <stdarg.h> // for va_list, va_start, and va_end (in string::format) + +namespace ustl { + +/// \class string ustring.h ustl.h +/// \ingroup Sequences +/// +/// \brief STL basic_string<char> equivalent. +/// +/// An STL container for text string manipulation. +/// Differences from C++ standard: +/// - string is a class, not a template. Wide characters are assumed to be +/// encoded with utf8 at all times except when rendering or editing, +/// where you would use a utf8 iterator. +/// - format member function - you can, of course use an \ref ostringstream, +/// which also have format functions, but most of the time this way +/// is more convenient. Because uSTL does not implement locales, +/// format is the only way to create localized strings. +/// - const char* cast operator. It is much clearer to use this than having +/// to type .c_str() every time. +/// - length returns the number of _characters_, not bytes. +/// This function is O(N), so use wisely. +/// +/// An additional note is in order regarding the use of indexes. All indexes +/// passed in as arguments or returned by find are byte offsets, not character +/// offsets. Likewise, sizes are specified in bytes, not characters. The +/// rationale is that there is no way for you to know what is in the string. +/// There is no way for you to know how many characters are needed to express +/// one thing or another. The only thing you can do to a localized string is +/// search for delimiters and modify text between them as opaque blocks. If you +/// do anything else, you are hardcoding yourself into a locale! So stop it! +/// +class string : public memblock { +public: + typedef char value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef wchar_t wvalue_type; + typedef wvalue_type* wpointer; + typedef const wvalue_type* const_wpointer; + typedef pointer iterator; + typedef const_pointer const_iterator; + typedef value_type& reference; + typedef value_type const_reference; + typedef ::ustl::reverse_iterator<iterator> reverse_iterator; + typedef ::ustl::reverse_iterator<const_iterator> const_reverse_iterator; + typedef utf8in_iterator<const_iterator> utf8_iterator; + static const uoff_t npos = static_cast<uoff_t>(-1); ///< Value that means the end of string. +public: + inline string (void) : memblock () { relink ("",0); } + string (const string& s); + inline string (const string& s, uoff_t o, size_type n); + inline explicit string (const cmemlink& l); + string (const_pointer s); + inline string (const_pointer s, size_type len); + inline string (const_pointer s1, const_pointer s2); + explicit string (size_type n, value_type c = 0); + inline pointer data (void) { return (string::pointer (memblock::data())); } + inline const_pointer c_str (void) const { return (string::const_pointer (memblock::cdata())); } + inline size_type max_size (void) const { size_type s (memblock::max_size()); return (s - !!s); } + inline size_type capacity (void) const { size_type c (memblock::capacity()); return (c - !!c); } + void resize (size_type n); + inline void resize (size_type n, value_type c); + inline void clear (void) { resize (0); } + inline const_iterator begin (void) const { return (const_iterator (memblock::begin())); } + inline iterator begin (void) { return (iterator (memblock::begin())); } + inline const_iterator end (void) const { return (const_iterator (memblock::end())); } + inline iterator end (void) { return (iterator (memblock::end())); } + inline const_reverse_iterator rbegin (void) const { return (const_reverse_iterator (end())); } + inline reverse_iterator rbegin (void) { return (reverse_iterator (end())); } + inline const_reverse_iterator rend (void) const { return (const_reverse_iterator (begin())); } + inline reverse_iterator rend (void) { return (reverse_iterator (begin())); } + inline utf8_iterator utf8_begin (void) const { return (utf8_iterator (begin())); } + inline utf8_iterator utf8_end (void) const { return (utf8_iterator (end())); } + inline const_reference at (uoff_t pos) const { assert (pos <= size() && begin()); return (begin()[pos]); } + inline reference at (uoff_t pos) { assert (pos <= size() && begin()); return (begin()[pos]); } + inline const_iterator iat (uoff_t pos) const { return (begin() + min (pos, size())); } + inline iterator iat (uoff_t pos) { return (begin() + min (pos, size())); } + const_iterator wiat (uoff_t i) const; + inline iterator wiat (uoff_t i) { return (const_cast<iterator>(const_cast<const string*>(this)->wiat(i))); } + inline const_reference back (void) const { return (at(size()-1)); } + inline reference back (void) { return (at(size()-1)); } + inline size_type length (void) const { return (distance (utf8_begin(), utf8_end())); } + inline void append (const_iterator i1, const_iterator i2) { append (i1, distance (i1, i2)); } + void append (const_pointer s, size_type len); + void append (const_pointer s); + void append (size_type n, const_reference c); + inline void append (size_type n, wvalue_type c) { insert (size(), c, n); } + inline void append (const_wpointer s1, const_wpointer s2) { insert (size(), s1, s2); } + inline void append (const_wpointer s) { const_wpointer se (s); for (;se&&*se;++se) ; append (s, se); } + inline void append (const string& s) { append (s.begin(), s.end()); } + inline void append (const string& s, uoff_t o, size_type n) { append (s.iat(o), s.iat(o+n)); } + inline void assign (const_iterator i1, const_iterator i2) { assign (i1, distance (i1, i2)); } + void assign (const_pointer s, size_type len); + void assign (const_pointer s); + inline void assign (const_wpointer s1, const_wpointer s2) { clear(); append (s1, s2); } + inline void assign (const_wpointer s1) { clear(); append (s1); } + inline void assign (const string& s) { assign (s.begin(), s.end()); } + inline void assign (const string& s, uoff_t o, size_type n) { assign (s.iat(o), s.iat(o+n)); } + size_type copyto (pointer p, size_type n, const_iterator start = NULL) const; + inline int compare (const string& s) const { return (compare (begin(), end(), s.begin(), s.end())); } + inline int compare (const_pointer s) const { return (compare (begin(), end(), s, s + strlen(s))); } + static int compare (const_iterator first1, const_iterator last1, const_iterator first2, const_iterator last2); + inline operator const value_type* (void) const; + inline operator value_type* (void); + inline const string& operator= (const string& s) { assign (s.begin(), s.end()); return (*this); } + inline const string& operator= (const_reference c) { assign (&c, 1); return (*this); } + inline const string& operator= (const_pointer s) { assign (s); return (*this); } + inline const string& operator= (const_wpointer s) { assign (s); return (*this); } + inline const string& operator+= (const string& s) { append (s.begin(), s.size()); return (*this); } + inline const string& operator+= (const_reference c) { append (1, c); return (*this); } + inline const string& operator+= (const_pointer s) { append (s); return (*this); } + inline const string& operator+= (wvalue_type c) { append (1, c); return (*this); } + inline const string& operator+= (const_wpointer s) { append (s); return (*this); } + inline string operator+ (const string& s) const; + inline bool operator== (const string& s) const { return (memblock::operator== (s)); } + bool operator== (const_pointer s) const; + inline bool operator== (const_reference c) const { return (size() == 1 && c == at(0)); } + inline bool operator!= (const string& s) const { return (!operator== (s)); } + inline bool operator!= (const_pointer s) const { return (!operator== (s)); } + inline bool operator!= (const_reference c) const { return (!operator== (c)); } + inline bool operator< (const string& s) const { return (0 > compare (s)); } + inline bool operator< (const_pointer s) const { return (0 > compare (s)); } + inline bool operator< (const_reference c) const { return (0 > compare (begin(), end(), &c, &c + 1)); } + inline bool operator> (const_pointer s) const { return (0 < compare (s)); } + void insert (const uoff_t ip, wvalue_type c, size_type n = 1); + void insert (const uoff_t ip, const_wpointer first, const_wpointer last, const size_type n = 1); + iterator insert (iterator start, const_reference c, size_type n = 1); + iterator insert (iterator start, const_pointer s, size_type n = 1); + iterator insert (iterator start, const_pointer first, const_iterator last, size_type n = 1); + inline void insert (uoff_t ip, const_pointer s, size_type nlen) { insert (iat(ip), s, s + nlen); } + inline void insert (uoff_t ip, size_type n, value_type c) { insert (iat(ip), c, n); } + inline void insert (uoff_t ip, const string& s, uoff_t sp, size_type slen) { insert (iat(ip), s.iat(sp), s.iat(sp + slen)); } + iterator erase (iterator epo, size_type n = 1); + void erase (uoff_t epo, size_type n = 1); + inline iterator erase (iterator first, const_iterator last) { return (erase (first, size_type(distance(first,last)))); } + inline void eraser (uoff_t first, uoff_t last) { erase (iat(first), iat(last)); } + inline void push_back (const_reference c) { append (1, c); } + inline void push_back (wvalue_type c) { append (1, c); } + inline void pop_back (void) { resize (size() - 1); } + void replace (iterator first, iterator last, const_pointer s); + void replace (iterator first, iterator last, const_pointer i1, const_pointer i2, size_type n = 1); + inline void replace (iterator first, iterator last, const string& s) { replace (first, last, s.begin(), s.end()); } + inline void replace (iterator first, iterator last, const_pointer s, size_type slen) { replace (first, last, s, s + slen); } + inline void replace (iterator first, iterator last, size_type n, value_type c) { replace (first, last, &c, &c + 1, n); } + inline void replace (uoff_t rp, size_type n, const string& s) { replace (iat(rp), iat(rp + n), s); } + inline void replace (uoff_t rp, size_type n, const string& s, uoff_t sp, size_type slen) { replace (iat(rp), iat(rp + n), s.iat(sp), s.iat(sp + slen)); } + inline void replace (uoff_t rp, size_type n, const_pointer s, size_type slen) { replace (iat(rp), iat(rp + n), s, s + slen); } + inline void replace (uoff_t rp, size_type n, const_pointer s) { replace (iat(rp), iat(rp + n), string(s)); } + inline void replace (uoff_t rp, size_type n, size_type count, value_type c) { replace (iat(rp), iat(rp + n), count, c); } + inline string substr (uoff_t o, size_type n = npos) const { return (string (*this, o, n)); } + uoff_t find (const_reference c, uoff_t pos = 0) const; + uoff_t find (const string& s, uoff_t pos = 0) const; + uoff_t rfind (const_reference c, uoff_t pos = npos) const; + uoff_t rfind (const string& s, uoff_t pos = npos) const; + uoff_t find_first_of (const string& s, uoff_t pos = 0) const; + uoff_t find_first_not_of (const string& s, uoff_t pos = 0) const; + uoff_t find_last_of (const string& s, uoff_t pos = npos) const; + uoff_t find_last_not_of (const string& s, uoff_t pos = npos) const; + int vformat (const char* fmt, va_list args); + int format (const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))); + void read (istream&); + void write (ostream& os) const; + size_t stream_size (void) const; + static hashvalue_t hash (const char* f1, const char* l1); +protected: + virtual size_type minimumFreeCapacity (void) const throw() __attribute__((const)); +}; + +//---------------------------------------------------------------------- + +/// Assigns itself the value of string \p s +inline string::string (const cmemlink& s) +: memblock () +{ + assign (const_iterator (s.begin()), s.size()); +} + +/// Assigns itself a [o,o+n) substring of \p s. +inline string::string (const string& s, uoff_t o, size_type n) +: memblock() +{ + assign (s, o, n); +} + +/// Copies the value of \p s of length \p len into itself. +inline string::string (const_pointer s, size_type len) +: memblock () +{ + assign (s, len); +} + +/// Copies into itself the string data between \p s1 and \p s2 +inline string::string (const_pointer s1, const_pointer s2) +: memblock () +{ + assert (s1 <= s2 && "Negative ranges result in memory allocation errors."); + assign (s1, s2); +} + +/// Returns the pointer to the first character. +inline string::operator const string::value_type* (void) const +{ + assert ((!end() || !*end()) && "This string is linked to data that is not 0-terminated. This may cause serious security problems. Please assign the data instead of linking."); + return (begin()); +} + +/// Returns the pointer to the first character. +inline string::operator string::value_type* (void) +{ + assert ((end() && !*end()) && "This string is linked to data that is not 0-terminated. This may cause serious security problems. Please assign the data instead of linking."); + return (begin()); +} + +/// Concatenates itself with \p s +inline string string::operator+ (const string& s) const +{ + string result (*this); + result += s; + return (result); +} + +/// Resize to \p n and fill new entries with \p c +inline void string::resize (size_type n, value_type c) +{ + const size_type oldn = size(); + resize (n); + fill_n (iat(oldn), max(ssize_t(n-oldn),0), c); +} + +//---------------------------------------------------------------------- +// Operators needed to avoid comparing pointer to pointer + +#define PTR_STRING_CMP(op, impl) \ +inline bool op (const char* s1, const string& s2) { return impl; } +PTR_STRING_CMP (operator==, (s2 == s1)) +PTR_STRING_CMP (operator!=, (s2 != s1)) +PTR_STRING_CMP (operator<, (s2 > s1)) +PTR_STRING_CMP (operator<=, (s2 >= s1)) +PTR_STRING_CMP (operator>, (s2 < s1)) +PTR_STRING_CMP (operator>=, (s2 <= s1)) +#undef PTR_STRING_CMP + +//---------------------------------------------------------------------- + +inline hashvalue_t hash_value (const char* first, const char* last) +{ return (string::hash (first, last)); } +inline hashvalue_t hash_value (const char* v) +{ return (hash_value (v, v + strlen(v))); } + +//---------------------------------------------------------------------- + +} // namespace ustl + +// Specialization for stream alignment +ALIGNOF (ustl::string, alignof (string::value_type())) + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/utf8.h @@ -0,0 +1,215 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. +// +// This file contains stream iterators that read and write UTF-8 encoded +// characters. The encoding is defined as follows: +// +// U-00000000 - U-0000007F: 0xxxxxxx +// U-00000080 - U-000007FF: 110xxxxx 10xxxxxx +// U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx +// U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx +// U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx +// U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx +// U-80000000 - U-FFFFFFFF: 11111110 100000xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + +#ifndef UTF8_H_3D7AEEEB3A88928D4D280B785F78B6F4 +#define UTF8_H_3D7AEEEB3A88928D4D280B785F78B6F4 + +#include "uiterator.h" + +namespace ustl { + +//---------------------------------------------------------------------- + +typedef uint8_t utf8subchar_t; ///< Type for the encoding subcharacters. + +//---------------------------------------------------------------------- + +inline size_t Utf8Bytes (wchar_t v) __attribute__((const)); +inline size_t Utf8Bytes (const wchar_t* first, const wchar_t* last) __attribute__((pure)); +inline size_t Utf8SequenceBytes (wchar_t c) __attribute__((const)); + +//---------------------------------------------------------------------- + +/// Returns the number of bytes required to UTF-8 encode \p v. +inline size_t Utf8Bytes (wchar_t v) +{ + if ((uint32_t) v < 128) + return (1); + size_t n; + #if __i386__ || __x86_64__ + uint32_t r = 0; + asm ("bsr\t%2, %%eax\n\t" + "add\t$4, %0\n\t" + "div\t%3":"=a"(n),"+d"(r):"r"(v),"c"(5)); + #else + static const uint32_t c_Bounds[7] = { 0x0000007F, 0x000007FF, 0x0000FFFF, 0x001FFFFF, 0x03FFFFFF, 0x7FFFFFFF, 0xFFFFFFFF }; + for (n = 0; c_Bounds[n++] < uint32_t(v);); + #endif + return (n); +} + +/// Measures the size of a wchar_t array in UTF-8 encoding. +inline size_t Utf8Bytes (const wchar_t* first, const wchar_t* last) +{ + size_t bc = 0; + for (; first < last; ++first) + bc += Utf8Bytes(*first); + return (bc); +} + +/// Returns the number of bytes in a UTF-8 sequence that starts with \p c. +inline size_t Utf8SequenceBytes (wchar_t c) // a wchar_t to keep c in a full register +{ + // Count the leading bits. Header bits are 1 * nBytes followed by a 0. + // 0 - single byte character. Take 7 bits (0xFF >> 1) + // 1 - error, in the middle of the character. Take 6 bits (0xFF >> 2) + // so you will keep reading invalid entries until you hit the next character. + // >2 - multibyte character. Take remaining bits, and get the next bytes. + // All errors are ignored, since the user can not correct them. + // + wchar_t mask = 0x80; + size_t nBytes = 0; + for (; c & mask; ++nBytes) + mask >>= 1; + return (nBytes ? nBytes : 1); // A sequence is always at least 1 byte. +} + +//---------------------------------------------------------------------- + +/// \class utf8in_iterator utf8.h ustl.h +/// \ingroup IteratorAdaptors +/// +/// \brief An iterator adaptor to character containers for reading UTF-8 encoded text. +/// +/// For example, you can copy from ustl::string to ustl::vector<wchar_t> with +/// copy (utf8in (str.begin()), utf8in (str.end()), back_inserter(wvect)); +/// There is no error handling; if the reading frame slips you'll get extra +/// characters, one for every misaligned byte. Although it is possible to skip +/// to the start of the next character, that would result in omitting the +/// misformatted character and the one after it, making it very difficult to +/// detect by the user. It is better to write some strange characters and let +/// the user know his file is corrupted. Another problem is overflow on bad +/// encodings (like a 0xFF on the end of a string). This is checked through +/// the end-of-string nul character, which will always be there as long as +/// you are using the string class. +/// +template <typename Iterator, typename WChar = wchar_t> +class utf8in_iterator { +public: + typedef typename iterator_traits<Iterator>::value_type value_type; + typedef typename iterator_traits<Iterator>::difference_type difference_type; + typedef typename iterator_traits<Iterator>::pointer pointer; + typedef typename iterator_traits<Iterator>::reference reference; +public: + explicit utf8in_iterator (const Iterator& is) : m_i (is), m_v (0) { Read(); } + utf8in_iterator (const utf8in_iterator& i) : m_i (i.m_i), m_v (i.m_v) {} + inline const utf8in_iterator& operator= (const utf8in_iterator& i) { m_i = i.m_i; m_v = i.m_v; return (*this); } + inline Iterator base (void) const { return (m_i - (Utf8Bytes(m_v) - 1)); } + /// Reads and returns the next value. + inline WChar operator* (void) const { return (m_v); } + inline utf8in_iterator& operator++ (void) { ++m_i; Read(); return (*this); } + inline utf8in_iterator operator++ (int) { utf8in_iterator old (*this); operator++(); return (old); } + inline utf8in_iterator& operator+= (uoff_t n) { while (n--) operator++(); return (*this); } + inline utf8in_iterator operator+ (uoff_t n) { utf8in_iterator v (*this); return (v += n); } + inline bool operator== (const utf8in_iterator& i) const { return (m_i == i.m_i); } + inline bool operator< (const utf8in_iterator& i) const { return (m_i < i.m_i); } + difference_type operator- (const utf8in_iterator& i) const; +private: + void Read (void); +private: + Iterator m_i; + WChar m_v; +}; + +/// Steps to the next character and updates current returnable value. +template <typename Iterator, typename WChar> +void utf8in_iterator<Iterator,WChar>::Read (void) +{ + const utf8subchar_t c = *m_i; + size_t nBytes = Utf8SequenceBytes (c); + m_v = c & (0xFF >> nBytes); // First byte contains bits after the header. + while (--nBytes && *++m_i) // Each subsequent byte has 6 bits. + m_v = (m_v << 6) | (*m_i & 0x3F); +} + +/// Returns the distance in characters (as opposed to the distance in bytes). +template <typename Iterator, typename WChar> +typename utf8in_iterator<Iterator,WChar>::difference_type +utf8in_iterator<Iterator,WChar>::operator- (const utf8in_iterator<Iterator,WChar>& last) const +{ + difference_type dist = 0; + for (Iterator first (last.m_i); first < m_i; ++dist) + first = advance (first, Utf8SequenceBytes (*first)); + return (dist); +} + +//---------------------------------------------------------------------- + +/// \class utf8out_iterator utf8.h ustl.h +/// \ingroup IteratorAdaptors +/// +/// \brief An iterator adaptor to character containers for writing UTF-8 encoded text. +/// +template <typename Iterator, typename WChar = wchar_t> +class utf8out_iterator { +public: + typedef typename iterator_traits<Iterator>::value_type value_type; + typedef typename iterator_traits<Iterator>::difference_type difference_type; + typedef typename iterator_traits<Iterator>::pointer pointer; + typedef typename iterator_traits<Iterator>::reference reference; +public: + explicit utf8out_iterator (const Iterator& os) : m_i (os) {} + utf8out_iterator (const utf8out_iterator& i) : m_i (i.m_i) {} + inline const Iterator& base (void) const { return (m_i); } + /// Writes \p v into the stream. + utf8out_iterator& operator= (WChar v); + inline utf8out_iterator& operator* (void) { return (*this); } + inline utf8out_iterator& operator++ (void) { return (*this); } + inline utf8out_iterator operator++ (int) { return (*this); } + inline bool operator== (const utf8out_iterator& i) const { return (m_i == i.m_i); } + inline bool operator< (const utf8out_iterator& i) const { return (m_i < i.m_i); } +private: + Iterator m_i; +}; + +/// Writes \p v into the stream. +template <typename Iterator, typename WChar> +utf8out_iterator<Iterator,WChar>& utf8out_iterator<Iterator,WChar>::operator= (WChar v) +{ + const size_t nBytes = Utf8Bytes (v); + if (nBytes > 1) { + // Write the bits 6 bits at a time, except for the first one, + // which may be less than 6 bits. + register wchar_t shift = nBytes * 6; + *m_i++ = ((v >> (shift -= 6)) & 0x3F) | (0xFF << (8 - nBytes)); + while (shift) + *m_i++ = ((v >> (shift -= 6)) & 0x3F) | 0x80; + } else // If only one byte, there is no header. + *m_i++ = v; + return (*this); +} + +//---------------------------------------------------------------------- + +/// Returns a UTF-8 adaptor writing to \p i. Useful in conjuction with back_insert_iterator. +template <typename Iterator> +inline utf8out_iterator<Iterator> utf8out (Iterator i) +{ + return (utf8out_iterator<Iterator> (i)); +} + +/// Returns a UTF-8 adaptor reading from \p i. +template <typename Iterator> +inline utf8in_iterator<Iterator> utf8in (Iterator i) +{ + return (utf8in_iterator<Iterator> (i)); +} + +//---------------------------------------------------------------------- + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/utuple.h @@ -0,0 +1,332 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UTUPLE_H_7324ADEC49B397CA74A56F6050FD5A6B +#define UTUPLE_H_7324ADEC49B397CA74A56F6050FD5A6B + +#include "ualgo.h" +#include "metamac.h" + +namespace ustl { + +/// \class tuple utuple.h ustl.h +/// \ingroup Sequences +/// +/// \brief A fixed-size array of \p N \p Ts. +/// +template <size_t N, typename T> +class tuple { +public: + typedef T value_type; + typedef size_t size_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef pointer iterator; + typedef const_pointer const_iterator; + typedef ::ustl::reverse_iterator<iterator> reverse_iterator; + typedef ::ustl::reverse_iterator<const_iterator> const_reverse_iterator; + typedef pair<iterator,iterator> range_t; + typedef pair<const_iterator,const_iterator> const_range_t; +public: + template <typename T2> + inline tuple (const tuple<N,T2>& t); + inline tuple (const tuple<N,T>& t); + inline tuple (const_pointer v); + inline tuple (void); + explicit inline tuple (const_reference v0, const_reference v1 = T(), const_reference v2 = T(), const_reference v3 = T()); + inline iterator begin (void) { return (m_v); } + inline const_iterator begin (void) const { return (m_v); } + inline iterator end (void) { return (begin() + N); } + inline const_iterator end (void) const { return (begin() + N); } + inline size_type size (void) const { return (N); } + inline size_type max_size (void) const { return (N); } + inline bool empty (void) const { return (N == 0); } + inline const_reference at (size_type i) const { return (m_v[i]); } + inline reference at (size_type i) { return (m_v[i]); } + inline const_reference operator[] (size_type i) const { return (m_v[i]); } + inline reference operator[] (size_type i) { return (m_v[i]); } + template <typename T2> + inline const tuple& operator= (const tuple<N,T2>& src); + inline const tuple& operator= (const tuple<N,T>& src); + inline const tuple& operator+= (const_reference v) + { for (uoff_t i = 0; i < N; ++ i) m_v[i] += v; return (*this); } + inline const tuple& operator-= (const_reference v) + { for (uoff_t i = 0; i < N; ++ i) m_v[i] -= v; return (*this); } + inline const tuple& operator*= (const_reference v) + { for (uoff_t i = 0; i < N; ++ i) m_v[i] *= v; return (*this); } + inline const tuple& operator/= (const_reference v) + { for (uoff_t i = 0; i < N; ++ i) m_v[i] /= v; return (*this); } + inline const tuple operator+ (const_reference v) const + { tuple result; for (uoff_t i = 0; i < N; ++ i) result[i] = m_v[i] + v; return (result); } + inline const tuple operator- (const_reference v) const + { tuple result; for (uoff_t i = 0; i < N; ++ i) result[i] = m_v[i] - v; return (result); } + inline const tuple operator* (const_reference v) const + { tuple result; for (uoff_t i = 0; i < N; ++ i) result[i] = m_v[i] * v; return (result); } + inline const tuple operator/ (const_reference v) const + { tuple result; for (uoff_t i = 0; i < N; ++ i) result[i] = m_v[i] / v; return (result); } + inline void swap (tuple<N,T>& v) + { for (uoff_t i = 0; i < N; ++ i) ::ustl::swap (m_v[i], v.m_v[i]); } + inline void read (istream& is) { nr_container_read (is, *this); } + inline void write (ostream& os) const { nr_container_write (os, *this); } + inline void text_write (ostringstream& os) const { container_text_write (os, *this); } + inline size_t stream_size (void) const { return (nr_container_stream_size (*this)); } +private: + T m_v [N]; +}; + +} // namespace ustl + +#include "simd.h" + +namespace ustl { + +template <size_t N, typename T> +template <typename T2> +inline tuple<N,T>::tuple (const tuple<N,T2>& t) +{ simd::pconvert (t, *this, simd::fcast<T2,T>()); } + +template <size_t N, typename T> +inline tuple<N,T>::tuple (const tuple<N,T>& t) +{ simd::passign (t, *this); } + +template <size_t N, typename T> +inline tuple<N,T>::tuple (const_pointer v) +{ simd::ipassign (v, *this); } + +template <size_t N, typename T> +inline tuple<N,T>::tuple (void) +{ + const T v = T(); + if (N > 4 || !numeric_limits<T>::is_integral) + fill_n (m_v, N, v); + else { + m_v[0] = v; + if (N > 1) m_v[1] = v; + if (N > 2) m_v[2] = v; + if (N > 3) m_v[3] = v; + } +} + +template <size_t N, typename T> +inline tuple<N,T>::tuple (const_reference v0, const_reference v1, const_reference v2, const_reference v3) +{ + m_v[0] = v0; + if (N > 1) m_v[1] = v1; + if (N > 2) m_v[2] = v2; + if (N > 3) m_v[3] = v3; + if (N > 4) fill_n (m_v + 4, N - 4, T()); +} + +template <size_t N, typename T> +template <typename T2> +inline const tuple<N,T>& tuple<N,T>::operator= (const tuple<N,T2>& src) +{ simd::pconvert (src, *this, simd::fcast<T2,T>()); return (*this); } + +template <size_t N, typename T> +inline const tuple<N,T>& tuple<N,T>::operator= (const tuple<N,T>& src) +{ simd::passign (src, *this); return (*this); } + +template <size_t N, typename T1, typename T2> +inline bool operator== (const tuple<N,T1>& t1, const tuple<N,T2>& t2) +{ + for (uoff_t i = 0; i < N; ++ i) + if (t1[i] != t2[i]) + return (false); + return (true); +} + +template <size_t N, typename T1, typename T2> +inline bool operator< (const tuple<N,T1>& t1, const tuple<N,T2>& t2) +{ + for (uoff_t i = 0; i < N && t1[i] <= t2[i]; ++ i) + if (t1[i] < t2[i]) + return (true); + return (false); +} + +template <size_t N, typename T1, typename T2> +inline const tuple<N,T1>& operator+= (tuple<N,T1>& t1, const tuple<N,T2>& t2) + { for (uoff_t i = 0; i < N; ++ i) t1[i] = T1(t1[i] + t2[i]); return (t1); } + +template <size_t N, typename T1, typename T2> +inline const tuple<N,T1>& operator-= (tuple<N,T1>& t1, const tuple<N,T2>& t2) + { for (uoff_t i = 0; i < N; ++ i) t1[i] = T1(t1[i] - t2[i]); return (t1); } + +template <size_t N, typename T1, typename T2> +inline const tuple<N,T1>& operator*= (tuple<N,T1>& t1, const tuple<N,T2>& t2) + { for (uoff_t i = 0; i < N; ++ i) t1[i] = T1(t1[i] * t2[i]); return (t1); } + +template <size_t N, typename T1, typename T2> +inline const tuple<N,T1>& operator/= (tuple<N,T1>& t1, const tuple<N,T2>& t2) + { for (uoff_t i = 0; i < N; ++ i) t1[i] = T1(t1[i] / t2[i]); return (t1); } + +template <size_t N, typename T1, typename T2> +inline const tuple<N,T1> operator+ (const tuple<N,T1>& t1, const tuple<N,T2>& t2) +{ + tuple<N,T1> result; + for (uoff_t i = 0; i < N; ++ i) result[i] = T1(t1[i] + t2[i]); + return (result); +} + +template <size_t N, typename T1, typename T2> +inline const tuple<N,T1> operator- (const tuple<N,T1>& t1, const tuple<N,T2>& t2) +{ + tuple<N,T1> result; + for (uoff_t i = 0; i < N; ++ i) result[i] = T1(t1[i] - t2[i]); + return (result); +} + +template <size_t N, typename T1, typename T2> +inline const tuple<N,T1> operator* (const tuple<N,T1>& t1, const tuple<N,T2>& t2) +{ + tuple<N,T1> result; + for (uoff_t i = 0; i < N; ++ i) result[i] = T1(t1[i] * t2[i]); + return (result); +} + +template <size_t N, typename T1, typename T2> +inline const tuple<N,T1> operator/ (const tuple<N,T1>& t1, const tuple<N,T2>& t2) +{ + tuple<N,T1> result; + for (uoff_t i = 0; i < N; ++ i) result[i] = T1(t1[i] / t2[i]); + return (result); +} + +//---------------------------------------------------------------------- +// Define SIMD specializations for member functions. + +#if CPU_HAS_SSE +#define SSE_TUPLE_SPECS(n,type) \ +template <> inline tuple<n,type>::tuple (void) \ +{ asm("xorps %%xmm0, %%xmm0\n\tmovups %%xmm0, %0":"+m"(m_v[0])::"xmm0","memory"); } \ +template<> inline void tuple<n,type>::swap (tuple<n,type>& v) \ +{ \ + asm ("movups %0,%%xmm0\n\tmovups %1,%%xmm1\n\t" \ + "movups %%xmm0,%1\n\tmovups %%xmm1,%0" \ + : "+m"(m_v[0]), "+m"(v.m_v[0]) :: "xmm0","xmm1","memory"); \ +} +SSE_TUPLE_SPECS(4,float) +SSE_TUPLE_SPECS(4,int32_t) +SSE_TUPLE_SPECS(4,uint32_t) +#undef SSE_TUPLE_SPECS +#endif +#if SIZE_OF_LONG == 8 && __GNUC__ +#define LONG_TUPLE_SPECS(n,type) \ +template <> inline tuple<n,type>::tuple (void) \ +{ asm("":"+m"(m_v[0])::"memory"); \ + *noalias_cast<long*>(m_v) = 0; } \ +template<> inline void tuple<n,type>::swap (tuple<n,type>& v) \ +{ asm("":"+m"(m_v[0]),"+m"(v.m_v[0])::"memory"); \ + iter_swap (noalias_cast<long*>(m_v), noalias_cast<long*>(v.m_v)); \ + asm("":"+m"(m_v[0]),"+m"(v.m_v[0])::"memory"); \ +} +LONG_TUPLE_SPECS(2,float) +LONG_TUPLE_SPECS(4,int16_t) +LONG_TUPLE_SPECS(4,uint16_t) +LONG_TUPLE_SPECS(2,int32_t) +LONG_TUPLE_SPECS(2,uint32_t) +LONG_TUPLE_SPECS(8,int8_t) +LONG_TUPLE_SPECS(8,uint8_t) +#undef LONG_TUPLE_SPECS +#elif CPU_HAS_MMX +#define MMX_TUPLE_SPECS(n,type) \ +template <> inline tuple<n,type>::tuple (void) \ +{ asm ("pxor %%mm0, %%mm0\n\tmovq %%mm0, %0" \ + :"=m"(m_v[0])::"mm0","st","memory"); simd::reset_mmx(); } \ +template<> inline void tuple<n,type>::swap (tuple<n,type>& v) \ +{ asm ("movq %2,%%mm0\n\tmovq %3,%%mm1\n\t" \ + "movq %%mm0,%1\n\tmovq %%mm1,%0" \ + :"=m"(m_v[0]),"=m"(v.m_v[0]):"m"(m_v[0]),"m"(v.m_v[0]):"mm0","mm1","st","st(1)","memory"); \ + simd::reset_mmx(); \ +} +MMX_TUPLE_SPECS(2,float) +MMX_TUPLE_SPECS(4,int16_t) +MMX_TUPLE_SPECS(4,uint16_t) +MMX_TUPLE_SPECS(2,int32_t) +MMX_TUPLE_SPECS(2,uint32_t) +MMX_TUPLE_SPECS(8,int8_t) +MMX_TUPLE_SPECS(8,uint8_t) +#undef MMX_TUPLE_SPECS +#endif + +#if __i386__ || __x86_64__ +#define UINT32_TUPLE_SPECS(type,otype) \ +template <> inline tuple<2,type>::tuple (void) \ +{ asm("":"+m"(m_v[0]),"+m"(m_v[1])::"memory"); \ + *noalias_cast<uint32_t*>(m_v) = 0; \ + asm("":"+m"(m_v[0]),"+m"(m_v[1])::"memory"); }\ +template <> inline const tuple<2,type>& tuple<2,type>::operator= (const tuple<2,type>& v)\ +{ asm ("mov %3, %0" \ + :"=m"(*noalias_cast<uint32_t*>(m_v)),"=m"(m_v[0]),"=m"(m_v[1]) \ + :"r"(*noalias_cast<const uint32_t*>(v.begin())),"m"(v[0]),"m"(v[1]):"memory"); \ + return (*this); } \ +template <> template <> \ +inline const tuple<2,type>& tuple<2,type>::operator= (const tuple<2,otype>& v)\ +{ asm ("mov %3, %0" \ + :"=m"(*noalias_cast<uint32_t*>(m_v)),"=m"(m_v[0]),"=m"(m_v[1]) \ + :"r"(*noalias_cast<const uint32_t*>(v.begin())),"m"(v[0]),"m"(v[1]):"memory"); \ + return (*this); } \ +template <> inline tuple<2,type>::tuple (const tuple<2,type>& v) \ +{ operator= (v); } \ +template <> template <> \ +inline tuple<2,type>::tuple (const tuple<2,otype>& v) \ +{ operator= (v); } \ +template<> inline void tuple<2,type>::swap (tuple<2,type>& v) \ +{ asm(""::"m"(m_v[0]),"m"(m_v[1]),"m"(v.m_v[0]),"m"(v.m_v[1]):"memory");\ + iter_swap (noalias_cast<uint32_t*>(m_v), noalias_cast<uint32_t*>(v.m_v)); \ + asm("":"=m"(m_v[0]),"=m"(m_v[1]),"=m"(v.m_v[0]),"=m"(v.m_v[1])::"memory"); } \ +template <> inline const tuple<2,type>& operator+= (tuple<2,type>& t1, const tuple<2,type>& t2) \ + { t1[0] += t2[0]; t1[1] += t2[1]; return (t1); } \ +template <> inline const tuple<2,type>& operator-= (tuple<2,type>& t1, const tuple<2,type>& t2) \ + { t1[0] -= t2[0]; t1[1] -= t2[1]; return (t1); } \ +template <> inline const tuple<2,type> operator+ (const tuple<2,type>& t1, const tuple<2,type>& t2) \ + { return (tuple<2,type> (t1[0] + t2[0], t1[1] + t2[1])); } \ +template <> inline const tuple<2,type> operator- (const tuple<2,type>& t1, const tuple<2,type>& t2) \ + { return (tuple<2,type> (t1[0] - t2[0], t1[1] - t2[1])); } +UINT32_TUPLE_SPECS(int16_t,uint16_t) +UINT32_TUPLE_SPECS(uint16_t,int16_t) +#undef UINT32_TUPLE_SPECS +#endif + +#undef TUPLEV_R1 +#undef TUPLEV_R2 +#undef TUPLEV_W1 +#undef TUPLEV_W2 + +#define SIMD_TUPLE_PACKOP(N,T) \ +template <> inline const tuple<N,T>& operator+= (tuple<N,T>& t1, const tuple<N,T>& t2) \ + { simd::padd (t2, t1); return (t1); } \ +template <> inline const tuple<N,T>& operator-= (tuple<N,T>& t1, const tuple<N,T>& t2) \ + { simd::psub (t2, t1); return (t1); } \ +template <> inline const tuple<N,T>& operator*= (tuple<N,T>& t1, const tuple<N,T>& t2) \ + { simd::pmul (t2, t1); return (t1); } \ +template <> inline const tuple<N,T>& operator/= (tuple<N,T>& t1, const tuple<N,T>& t2) \ + { simd::pdiv (t2, t1); return (t1); } \ +template <> inline const tuple<N,T> operator+ (const tuple<N,T>& t1, const tuple<N,T>& t2) \ + { tuple<N,T> result (t1); simd::padd (t2, result); return (result); } \ +template <> inline const tuple<N,T> operator- (const tuple<N,T>& t1, const tuple<N,T>& t2) \ + { tuple<N,T> result (t1); simd::psub (t2, result); return (result); } \ +template <> inline const tuple<N,T> operator* (const tuple<N,T>& t1, const tuple<N,T>& t2) \ + { tuple<N,T> result (t1); simd::pmul (t2, result); return (result); } \ +template <> inline const tuple<N,T> operator/ (const tuple<N,T>& t1, const tuple<N,T>& t2) \ + { tuple<N,T> result (t1); simd::pdiv (t2, result); return (result); } +SIMD_TUPLE_PACKOP(4,float) +SIMD_TUPLE_PACKOP(2,float) +SIMD_TUPLE_PACKOP(2,double) +SIMD_TUPLE_PACKOP(4,int32_t) +SIMD_TUPLE_PACKOP(4,uint32_t) +SIMD_TUPLE_PACKOP(4,int16_t) +SIMD_TUPLE_PACKOP(4,uint16_t) +SIMD_TUPLE_PACKOP(2,int32_t) +SIMD_TUPLE_PACKOP(2,uint32_t) +SIMD_TUPLE_PACKOP(8,int8_t) +SIMD_TUPLE_PACKOP(8,uint8_t) +#undef SIMD_TUPLE_PACKOP + +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/utypes.h @@ -0,0 +1,67 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UTYPES_H_118BBB3B50B7DBF22F5460C52E515C83 +#define UTYPES_H_118BBB3B50B7DBF22F5460C52E515C83 + +#include "config.h" +#ifndef STDC_HEADERS + #error "This library requires standard C and C++ headers to compile." +#endif +#ifndef STDUNIX_HEADERS + #error "This library compiles only on UNIX systems." +#endif +#define __STDC_LIMIT_MACROS // For WCHAR_MIN and WCHAR_MAX in stdint. +#define __STDC_CONSTANT_MACROS // For UINT??_C macros to avoid using L and UL suffixes on constants. +#if HAVE_STDINT_H + #include <stdint.h> +#elif HAVE_INTTYPES_H + #include <inttypes.h> +#else + #error "Need standard integer types definitions, usually in stdint.h" +#endif +#include <stddef.h> // For ptrdiff_t, size_t +#include <limits.h> +#include <float.h> +#if HAVE_SYS_TYPES_H + #include <sys/types.h> +#endif +#ifndef SIZE_MAX + #define SIZE_MAX UINT_MAX +#endif +#if sun || __sun // Solaris defines UINTPTR_MAX as empty. + #undef UINTPTR_MAX + #define UINTPTR_MAX ULONG_MAX +#endif +#ifndef WCHAR_MAX + #ifdef __WCHAR_MAX__ + #define WCHAR_MAX __WCHAR_MAX__ + #else + #define WCHAR_MAX CHAR_MAX + #endif +#endif +#if HAVE_LONG_LONG + #ifndef LLONG_MAX + #define ULLONG_MAX UINT64_C(0xFFFFFFFFFFFFFFFF) + #define LLONG_MAX INT64_C(0x7FFFFFFFFFFFFFFF) + #define LLONG_MIN ULLONG_MAX + #endif +#endif +#ifndef BYTE_ORDER + #define LITTLE_ENDIAN USTL_LITTLE_ENDIAN + #define BIG_ENDIAN USTL_BIG_ENDIAN + #define BYTE_ORDER USTL_BYTE_ORDER +#endif + +typedef size_t uoff_t; ///< A type for storing offsets into blocks measured by size_t. +typedef uint32_t hashvalue_t; ///< Value type returned by the hash functions. +typedef size_t streamsize; ///< Size of stream data +typedef uoff_t streamoff; ///< Offset into a stream + + +#if !defined(UINTPTR_MAX) || !defined(UINT32_C) + #error "If you include stdint.h before ustl.h, define __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS first" +#endif +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/uutility.h @@ -0,0 +1,383 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. +// +/// \file uutility.h +/// \brief Utility templates. + +#ifndef UUTILITY_H_6A58BD296269A82A4AAAA4FD19FDB3AC +#define UUTILITY_H_6A58BD296269A82A4AAAA4FD19FDB3AC + +#include "utypes.h" +#include "traits.h" +#include "ulimits.h" +#include <assert.h> + +namespace ustl { + +#ifdef __GNUC__ + /// Returns the number of elements in a static vector + #define VectorSize(v) (sizeof(v) / sizeof(*v)) +#else + // Old compilers will not be able to evaluate *v on an empty vector. + // The tradeoff here is that VectorSize will not be able to measure arrays of local structs. + #define VectorSize(v) (sizeof(v) / ustl::size_of_elements(1, v)) +#endif + +/// Expands into a ptr,size expression for the given static vector; useful as link arguments. +#define VectorBlock(v) (v)+0, VectorSize(v) // +0 makes it work under gcc 2.95 +/// Expands into a begin,end expression for the given static vector; useful for algorithm arguments. +#define VectorRange(v) VectorBlock(v)+(v) + +/// Indexes into a static array with bounds limit +#define VectorElement(v,i) v[min(uoff_t(i),uoff_t(VectorSize(v)-1))] + +/// Returns the number of bits in the given type +#define BitsInType(t) (sizeof(t) * CHAR_BIT) + +/// Returns the mask of type \p t with the lowest \p n bits set. +#define BitMask(t,n) (t(~t(0)) >> ((sizeof(t) * CHAR_BIT) - (n))) + +/// Argument that is used only in debug builds (as in an assert) +#ifndef NDEBUG + #define DebugArg(x) x +#else + #define DebugArg(x) +#endif + +/// Shorthand for container iteration. +#define foreach(type,i,ctr) for (type i = (ctr).begin(); i != (ctr).end(); ++ i) +/// Shorthand for container reverse iteration. +#define eachfor(type,i,ctr) for (type i = (ctr).rbegin(); i != (ctr).rend(); ++ i) + +#ifndef DOXYGEN_SHOULD_SKIP_THIS +// Macro for passing template types as macro arguments. +// These are deprecated. Use metamac macros instead. Will remove by next release. +#define TEMPLATE_FULL_DECL1(d1,t1) template <d1 t1> +#define TEMPLATE_FULL_DECL2(d1,t1,d2,t2) template <d1 t1, d2 t2> +#define TEMPLATE_FULL_DECL3(d1,t1,d2,t2,d3,t3) template <d1 t1, d2 t2, d3 t3> +#define TEMPLATE_DECL1(t1) TEMPLATE_FULL_DECL1(typename,t1) +#define TEMPLATE_DECL2(t1,t2) TEMPLATE_FULL_DECL2(typename,t1,typename,t2) +#define TEMPLATE_DECL3(t1,t2,t3) TEMPLATE_FULL_DECL3(typename,t1,typename,t2,typename,t3) +#define TEMPLATE_TYPE1(type,a1) type<a1> +#define TEMPLATE_TYPE2(type,a1,a2) type<a1,a2> +#define TEMPLATE_TYPE3(type,a1,a2,a3) type<a1,a2,a3> +#endif + +/// Returns the minimum of \p a and \p b +template <typename T1, typename T2> +inline T1 min (const T1& a, const T2& b) +{ + return (a < b ? a : b); +} + +/// Returns the maximum of \p a and \p b +template <typename T1, typename T2> +inline T1 max (const T1& a, const T2& b) +{ + return (b < a ? a : b); +} + +/// The alignment performed by default. +const size_t c_DefaultAlignment = __alignof__(void*); + +/// \brief Rounds \p n up to be divisible by \p grain +template <typename T> +inline T Align (T n, size_t grain = c_DefaultAlignment) +{ + n += grain - 1; + return (n - n % grain); +} + +/// Returns a NULL pointer cast to T. +template <typename T> +inline T* NullPointer (void) + { return ((T*) NULL); } + +/// \brief Returns a non-dereferentiable value reference. +/// This is useful for passing to alignof or the like which need a value but +/// don't need to actually use it. +template <typename T> +inline T& NullValue (void) + { return (*NullPointer<T>()); } + +/// Offsets an iterator +template <typename T> +inline T advance (T i, ssize_t offset) +{ + return (i + offset); +} + +#ifndef DOXYGEN_SHOULD_SKIP_THIS +/// Offsets a void pointer +template <> +inline const void* advance (const void* p, ssize_t offset) +{ + assert (p || !offset); + return (reinterpret_cast<const uint8_t*>(p) + offset); +} + +/// Offsets a void pointer +template <> +inline void* advance (void* p, ssize_t offset) +{ + assert (p || !offset); + return (reinterpret_cast<uint8_t*>(p) + offset); +} +#endif + +/// Returns the difference \p p1 - \p p2 +template <typename T1, typename T2> +inline ptrdiff_t distance (T1 i1, T2 i2) +{ + return (i2 - i1); +} + +#ifndef DOXYGEN_SHOULD_SKIP_THIS +#define UNVOID_DISTANCE(T1const,T2const) \ +template <> inline ptrdiff_t distance (T1const void* p1, T2const void* p2) \ +{ return ((T2const uint8_t*)(p2) - (T1const uint8_t*)(p1)); } +UNVOID_DISTANCE(,) +UNVOID_DISTANCE(const,const) +UNVOID_DISTANCE(,const) +UNVOID_DISTANCE(const,) +#undef UNVOID_DISTANCE +#endif + +// The compiler issues a warning if an unsigned type is compared to 0. +template <typename T, bool IsSigned> struct __is_negative { inline bool operator()(const T& v) { return (v < 0); } }; +template <typename T> struct __is_negative<T,false> { inline bool operator()(const T&) { return (false); } }; +/// Warning-free way to check if \p v is negative, even if for unsigned types. +template <typename T> inline bool is_negative (const T& v) { return (__is_negative<T,numeric_limits<T>::is_signed>()(v)); } + +/// \brief Returns the absolute value of \p v +/// Unlike the stdlib functions, this is inline and works with all types. +template <typename T> +inline T absv (T v) +{ + return (is_negative(v) ? -v : v); +} + +/// \brief Returns -1 for negative values, 1 for positive, and 0 for 0 +template <typename T> +inline T sign (T v) +{ + return ((0 < v) - is_negative(v)); +} + +/// Returns the absolute value of the distance i1 and i2 +template <typename T1, typename T2> +inline size_t abs_distance (T1 i1, T2 i2) +{ + return (absv (distance(i1, i2))); +} + +/// Returns the size of \p n elements of size \p T +template <typename T> +inline size_t size_of_elements (size_t n, const T*) +{ + return (n * sizeof(T)); +} + +// Defined in byteswap.h, which is usually unusable. +#undef bswap_16 +#undef bswap_32 +#undef bswap_64 + +inline uint16_t bswap_16 (uint16_t v) +{ +#if CPU_HAS_CMPXCHG8 // If it has that, it has bswap. + if (!__builtin_constant_p(v)) asm ("rorw $8, %0":"+r"(v)); else +#endif + v = v << 8 | v >> 8; + return (v); +} +inline uint32_t bswap_32 (uint32_t v) +{ +#if CPU_HAS_CMPXCHG8 + if (!__builtin_constant_p(v)) asm ("bswap %0":"+r"(v)); else +#endif + v = v << 24 | (v & 0xFF00) << 8 | ((v >> 8) & 0xFF00) | v >> 24; + return (v); +} +#if HAVE_INT64_T +inline uint64_t bswap_64 (uint64_t v) +{ +#if x86_64 + if (!__builtin_constant_p(v)) asm ("bswap %0":"+r"(v)); else +#endif + v = (uint64_t(bswap_32(v)) << 32) | bswap_32(v >> 32); + return (v); +} +#endif + +/// \brief Swaps the byteorder of \p v. +template <typename T> +inline T bswap (const T& v) +{ + switch (BitsInType(T)) { + default: return (v); + case 16: return (T (bswap_16 (uint16_t (v)))); + case 32: return (T (bswap_32 (uint32_t (v)))); +#if HAVE_INT64_T + case 64: return (T (bswap_64 (uint64_t (v)))); +#endif + } +} + +#if BYTE_ORDER == BIG_ENDIAN +template <typename T> inline T le_to_native (const T& v) { return (bswap (v)); } +template <typename T> inline T be_to_native (const T& v) { return (v); } +template <typename T> inline T native_to_le (const T& v) { return (bswap (v)); } +template <typename T> inline T native_to_be (const T& v) { return (v); } +#elif BYTE_ORDER == LITTLE_ENDIAN +template <typename T> inline T le_to_native (const T& v) { return (v); } +template <typename T> inline T be_to_native (const T& v) { return (bswap (v)); } +template <typename T> inline T native_to_le (const T& v) { return (v); } +template <typename T> inline T native_to_be (const T& v) { return (bswap (v)); } +#endif // BYTE_ORDER + +/// Deletes \p p and sets it to NULL +template <typename T> +inline void Delete (T*& p) +{ + delete p; + p = NULL; +} + +/// Deletes \p p as an array and sets it to NULL +template <typename T> +inline void DeleteVector (T*& p) +{ + delete [] p; + p = NULL; +} + +/// Template of making != from ! and == +template <typename T> +inline bool operator!= (const T& x, const T& y) +{ + return (!(x == y)); +} + +/// Template of making > from < +template <typename T> +inline bool operator> (const T& x, const T& y) +{ + return (y < x); +} + +/// Template of making <= from < and == +template <typename T> +inline bool operator<= (const T& x, const T& y) +{ + return (!(y < x)); +} + +/// Template of making >= from < and == +template <typename T> +inline bool operator>= (const T& x, const T& y) +{ + return (!(x < y)); +} + +/// Packs \p s multiple times into \p b. Useful for loop unrolling. +template <typename TSmall, typename TBig> +inline void pack_type (TSmall s, TBig& b) +{ + const size_t n = sizeof(TBig) / sizeof(TSmall); + b = s; + // Calls to min are here to avoid warnings for shifts bigger than the type. min will be gone when optimized. + if (n < 2) return; + b = (b << min (BitsInType(TSmall), BitsInType(TBig))) | b; + if (n < 4) return; + b = (b << min (BitsInType(TSmall) * 2, BitsInType(TBig))) | b; + if (n < 8) return; + b = (b << min (BitsInType(TSmall) * 4, BitsInType(TBig))) | b; +} + +/// \brief Divides \p n1 by \p n2 and rounds the result up. +/// This is in contrast to regular division, which rounds down. +template <typename T1, typename T2> +inline T1 DivRU (T1 n1, T2 n2) +{ + T2 adj = n2 - 1; + if (is_negative (n1)) + adj = -adj; + return ((n1 + adj) / n2); +} + +#if __GNUC__ >= 3 +inline bool TestAndSet (int* pm) INLINE; +#endif +/// Sets the contents of \p pm to 1 and returns true if the previous value was 0. +inline bool TestAndSet (int* pm) +{ +#if CPU_HAS_CMPXCHG8 + bool rv; + int oldVal (1); + asm volatile ( // cmpxchg compares to %eax and swaps if equal + "cmpxchgl %3, %1\n\t" + "sete %0" + : "=a" (rv), "=m" (*pm), "=r" (oldVal) + : "2" (oldVal), "a" (0) + : "memory"); + return (rv); +#elif __i386__ || __x86_64__ + int oldVal (1); + asm volatile ("xchgl %0, %1" : "=r"(oldVal), "=m"(*pm) : "0"(oldVal), "m"(*pm) : "memory"); + return (!oldVal); +#elif __sparc32__ // This has not been tested + int rv; + asm volatile ("ldstub %1, %0" : "=r"(rv), "=m"(*pm) : "m"(pm)); + return (!rv); +#else + const int oldVal (*pm); + *pm = 1; + return (!oldVal); +#endif +} + +/// \brief This template is to be used for dereferencing a type-punned pointer without a warning. +/// +/// When casting a local variable to an unrelated type through a pointer (for +/// example, casting a float to a uint32_t without conversion), the resulting +/// memory location can be accessed through either pointer, which violates the +/// strict aliasing rule. While -fno-strict-aliasing option can be given to +/// the compiler, eliminating this warning, inefficient code may result in +/// some instances, because aliasing inhibits some optimizations. By using +/// this template, and by ensuring the memory is accessed in one way only, +/// efficient code can be produced without the warning. For gcc 4.1.0+. +/// +template <typename DEST, typename SRC> +inline DEST noalias (const DEST&, SRC* s) +{ + asm("":"+g"(s)::"memory"); + union UPun { SRC s; DEST d; }; + return (((UPun*)(s))->d); +} + +template <typename DEST, typename SRC> +inline DEST noalias_cast (SRC s) +{ + asm("":"+g"(s)::"memory"); + union { SRC s; DEST d; } u = {s}; + return (u.d); +} + +namespace simd { + /// Call after you are done using SIMD algorithms for 64 bit tuples. + inline void reset_mmx (void) INLINE; + #define ALL_MMX_REGS_CHANGELIST "mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7","st","st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)" +#if CPU_HAS_3DNOW + inline void reset_mmx (void) { asm ("femms":::ALL_MMX_REGS_CHANGELIST); } +#elif CPU_HAS_MMX + inline void reset_mmx (void) { asm ("emms":::ALL_MMX_REGS_CHANGELIST); } +#else + inline void reset_mmx (void) {} +#endif +} // namespace simd +} // namespace ustl + +#endif
new file mode 100644 --- /dev/null +++ b/packages/language/cxx/ustl/current/include/ustl/uvector.h @@ -0,0 +1,272 @@ +// This file is part of the uSTL library, an STL implementation. +// +// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> +// This file is free software, distributed under the MIT License. + +#ifndef UVECTOR_H_00BB13AF082BEB7829C031B265518169 +#define UVECTOR_H_00BB13AF082BEB7829C031B265518169 + +#include "memblock.h" +#include "umemory.h" + +namespace ustl { + +/// \class vector uvector.h ustl.h +/// \ingroup Sequences +/// +/// \brief STL vector equivalent. +/// +/// Provides a typed array-like interface to a managed memory block, including +/// element access, iteration, modification, resizing, and serialization. In +/// this design elements frequently undergo bitwise move, so don't put it in +/// here if it doesn't support it. This mostly means having no self-pointers. +/// +template <typename T> +class vector { +public: + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef pointer iterator; + typedef const_pointer const_iterator; + typedef memblock::size_type size_type; + typedef memblock::written_size_type written_size_type; + typedef memblock::difference_type difference_type; + typedef ::ustl::reverse_iterator<iterator> reverse_iterator; + typedef ::ustl::reverse_iterator<const_iterator> const_reverse_iterator; +public: + inline vector (void); + inline explicit vector (size_type n); + vector (size_type n, const T& v); + vector (const vector<T>& v); + vector (const_iterator i1, const_iterator i2); + inline ~vector (void) throw(); + inline const vector<T>& operator= (const vector<T>& v); + inline bool operator== (const vector<T>& v) const { return (m_Data == v.m_Data); } + inline operator cmemlink (void) const { return (cmemlink (m_Data)); } + inline operator cmemlink (void) { return (cmemlink (m_Data)); } + inline operator memlink (void) { return (memlink (m_Data)); } + inline void reserve (size_type n, bool bExact = true); + inline void resize (size_type n, bool bExact = true); + inline size_type capacity (void) const { return (m_Data.capacity() / sizeof(T)); } + inline size_type size (void) const { return (m_Data.size() / sizeof(T)); } + inline size_type max_size (void) const { return (m_Data.max_size() / sizeof(T)); } + inline bool empty (void) const { return (m_Data.empty()); } + inline iterator begin (void) { return (iterator (m_Data.begin())); } + inline const_iterator begin (void) const { return (const_iterator (m_Data.begin())); } + inline iterator end (void) { return (iterator (m_Data.end())); } + inline const_iterator end (void) const { return (const_iterator (m_Data.end())); } + inline reverse_iterator rbegin (void) { return (reverse_iterator (end())); } + inline const_reverse_iterator rbegin (void) const { return (const_reverse_iterator (end())); } + inline reverse_iterator rend (void) { return (reverse_iterator (begin())); } + inline const_reverse_iterator rend (void) const { return (const_reverse_iterator (begin())); } + inline iterator iat (size_type i) { assert (i <= size()); return (begin() + i); } + inline const_iterator iat (size_type i) const { assert (i <= size()); return (begin() + i); } + inline reference at (size_type i) { assert (i < size()); return (begin()[i]); } + inline const_reference at (size_type i) const { assert (i < size()); return (begin()[i]); } + inline reference operator[] (size_type i) { return (at (i)); } + inline const_reference operator[] (size_type i) const { return (at (i)); } + inline reference front (void) { return (at(0)); } + inline const_reference front (void) const { return (at(0)); } + inline reference back (void) { assert (!empty()); return (end()[-1]); } + inline const_reference back (void) const { assert (!empty()); return (end()[-1]); } + inline void push_back (const T& v = T()); + inline void pop_back (void) { m_Data.memlink::resize (m_Data.size() - sizeof(T)); } + inline void clear (void) { m_Data.clear(); } + inline void deallocate (void) throw(); + inline void assign (const_iterator i1, const_iterator i2); + inline void assign (size_type n, const T& v); + inline void swap (vector<T>& v) { m_Data.swap (v.m_Data); } + inline iterator insert (iterator ip, const T& v = T()); + inline iterator insert (iterator ip, size_type n, const T& v); + inline iterator insert (iterator ip, const_iterator i1, const_iterator i2); + inline iterator erase (iterator ep, size_type n = 1); + inline iterator erase (iterator ep1, iterator ep2); + inline void manage (pointer p, size_type n) { m_Data.manage (p, n * sizeof(T)); } + inline bool is_linked (void) const { return (m_Data.is_linked()); } + inline void unlink (void) { m_Data.unlink(); } + inline void copy_link (void) { m_Data.copy_link(); } + inline void link (const_pointer p, size_type n) { m_Data.link (p, n * sizeof(T)); } + inline void link (pointer p, size_type n) { m_Data.link (p, n * sizeof(T)); } + inline void link (const vector<T>& v) { m_Data.link (v); } + inline void link (vector<T>& v) { m_Data.link (v); } + inline void link (const_pointer first, const_pointer last) { m_Data.link (first, last); } + inline void link (pointer first, pointer last) { m_Data.link (first, last); } + inline void read (istream& is) { container_read (is, *this); } + inline void write (ostream& os) const { container_write (os, *this); } + inline void text_write (ostringstream& os) const { container_text_write (os, *this); } + inline size_t stream_size (void) const { return (container_stream_size (*this)); } +private: + inline iterator insert_space (iterator ip, size_type n); +private: + memblock m_Data; ///< Raw element data, consecutively stored. +}; + +/// Allocates space for at least \p n elements. +template <typename T> +inline void vector<T>::reserve (size_type n, bool bExact) +{ + const size_type oldCapacity = m_Data.capacity() - m_Data.capacity() % sizeof(T); + m_Data.reserve (n * sizeof(T), bExact); + construct (iterator (m_Data.begin() + oldCapacity), iterator (m_Data.begin() + m_Data.capacity())); +} + +/// Resizes the vector to contain \p n elements. +template <typename T> +inline void vector<T>::resize (size_type n, bool bExact) +{ + const size_type nb = n * sizeof(T); + if (m_Data.capacity() < nb) + reserve (n, bExact); + m_Data.memlink::resize (nb); +} + +/// Calls element destructors and frees storage. +template <typename T> +inline void vector<T>::deallocate (void) throw() +{ + destroy (begin(), iterator (m_Data.begin() + m_Data.capacity())); + m_Data.deallocate(); +} + +/// Initializes empty vector. +template <typename T> +inline vector<T>::vector (void) +: m_Data () +{ +} + +/// Initializes a vector of size \p n. +template <typename T> +inline vector<T>::vector (size_type n) +: m_Data () +{ + resize (n); +} + +/// Copies \p n elements from \p v. +template <typename T> +vector<T>::vector (size_type n, const T& v) +: m_Data () +{ + resize (n); + ::ustl::fill (begin(), end(), v); +} + +/// Copies \p v. +template <typename T> +vector<T>::vector (const vector<T>& v) +: m_Data () +{ + resize (v.size()); + ::ustl::copy (v.begin(), v.end(), begin()); +} + +/// Copies range [\p i1, \p i2] +template <typename T> +vector<T>::vector (const_iterator i1, const_iterator i2) +: m_Data () +{ + resize (distance (i1, i2)); + ::ustl::copy (i1, i2, begin()); +} + +/// Destructor +template <typename T> +inline vector<T>::~vector (void) throw() +{ + destroy (begin(), iterator (m_Data.begin() + m_Data.capacity())); +} + +/// Copies the range [\p i1, \p i2] +template <typename T> +inline void vector<T>::assign (const_iterator i1, const_iterator i2) +{ + assert (i1 <= i2); + resize (distance (i1, i2)); + ::ustl::copy (i1, i2, begin()); +} + +/// Copies \p n elements with value \p v. +template <typename T> +inline void vector<T>::assign (size_type n, const T& v) +{ + resize (n); + ::ustl::fill (begin(), end(), v); +} + +/// Copies contents of \p v. +template <typename T> +inline const vector<T>& vector<T>::operator= (const vector<T>& v) +{ + assign (v.begin(), v.end()); + return (*this); +} + +/// Inserts \p n uninitialized elements at \p ip. +template <typename T> +inline typename vector<T>::iterator vector<T>::insert_space (iterator ip, size_type n) +{ + const uoff_t ipmi = distance (m_Data.begin(), memblock::iterator(ip)); + reserve (size() + n, false); + return (iterator (m_Data.insert (m_Data.iat(ipmi), n * sizeof(T)))); +} + +/// Inserts \p n elements with value \p v at offsets \p ip. +template <typename T> +inline typename vector<T>::iterator vector<T>::insert (iterator ip, size_type n, const T& v) +{ + ip = insert_space (ip, n); + ::ustl::fill (ip, ip + n, v); + return (ip); +} + +/// Inserts value \p v at offset \p ip. +template <typename T> +inline typename vector<T>::iterator vector<T>::insert (iterator ip, const T& v) +{ + *(ip = insert_space (ip, 1)) = v; + return (ip); +} + +/// Inserts range [\p i1, \p i2] at offset \p ip. +template <typename T> +inline typename vector<T>::iterator vector<T>::insert (iterator ip, const_iterator i1, const_iterator i2) +{ + assert (i1 <= i2); + ip = insert_space (ip, distance (i1, i2)); + ::ustl::copy (i1, i2, ip); + return (ip); +} + +/// Removes \p count elements at offset \p ep. +template <typename T> +inline typename vector<T>::iterator vector<T>::erase (iterator ep, size_type n) +{ + return (iterator (m_Data.erase (memblock::iterator(ep), n * sizeof(T)))); +} + +/// Removes elements from \p ep1 to \p ep2. +template <typename T> +inline typename vector<T>::iterator vector<T>::erase (iterator ep1, iterator ep2) +{ + assert (ep1 <= ep2); + return (erase (ep1, distance(ep1, ep2))); +} + +/// Inserts value \p v at the end of the vector. +template <typename T> +inline void vector<T>::push_back (const T& v) +{ + resize (size() + 1, false); + back() = v; +} + +/// Use with vector classes to allocate and link to stack space. \p n is in elements. +#define typed_alloca_link(m,T,n) (m).link ((T*) alloca ((n) * sizeof(T)), (n)) + +} // namespace ustl + +#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/ustlecos.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef CYGONCE_USTLECOS_H -#define CYGONCE_USTLECOS_H -// ========================================================================== -// -// ustlecos.h -// -// eCos specific implementations and additions to uSTL library -// -// =========================================================================== -// ####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 2009 Free Software Foundation, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later -// version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License -// along with eCos; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// As a special exception, if other files instantiate templates or use -// macros or inline functions from this file, or you compile this file -// and link it with other works to produce a work based on this file, -// this file does not by itself cause the resulting work to be covered by -// the GNU General Public License. However the source code for this file -// must still be made available in accordance with section (3) of the GNU -// General Public License v2. -// -// This exception does not invalidate any other reasons why a work based -// on this file might be covered by the GNU General Public License. -// ------------------------------------------- -// ####ECOSGPLCOPYRIGHTEND#### -// =========================================================================== -// =========================================================================== -// #####DESCRIPTIONBEGIN#### -// -// Author(s): Uwe Kindler -// Contributors: -// Date: 2009-07-28 -// Purpose: eCos specific additions to uSTL library -// Description: -// Usage: Do not include directly #include <ustl.h> -// -// ####DESCRIPTIONEND#### -// -// ========================================================================*/ - - -// -// If exception handling is disabled then we provide a low level and -// lightwight "exeption handler" -// -#ifndef __EXCEPTIONS -namespace ustl -{ - -typedef void (*app_exception_handler_t)(const exception& ex); - - -// allow an application to register its own ustl exception handler -void set_app_exception_handler(app_exception_handler_t func); - -// an application exception handler may use this function to print the -// exception to diagnostic output -void diag_print_exception(const exception& ex); -} // namespace ustl -#endif - -// --------------------------------------------------------------------------- -#endif // CYGONCE_USTLECOS_H
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/ustring.h +++ /dev/null @@ -1,268 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef USTRING_H_1249CB7A098A9010763AAC6D37B133CF -#define USTRING_H_1249CB7A098A9010763AAC6D37B133CF - -#include "memblock.h" -#include "utf8.h" -#include <stdarg.h> // for va_list, va_start, and va_end (in string::format) - -namespace ustl { - -/// \class string ustring.h ustl.h -/// \ingroup Sequences -/// -/// \brief STL basic_string<char> equivalent. -/// -/// An STL container for text string manipulation. -/// Differences from C++ standard: -/// - string is a class, not a template. Wide characters are assumed to be -/// encoded with utf8 at all times except when rendering or editing, -/// where you would use a utf8 iterator. -/// - format member function - you can, of course use an \ref ostringstream, -/// which also have format functions, but most of the time this way -/// is more convenient. Because uSTL does not implement locales, -/// format is the only way to create localized strings. -/// - const char* cast operator. It is much clearer to use this than having -/// to type .c_str() every time. -/// - length returns the number of _characters_, not bytes. -/// This function is O(N), so use wisely. -/// -/// An additional note is in order regarding the use of indexes. All indexes -/// passed in as arguments or returned by find are byte offsets, not character -/// offsets. Likewise, sizes are specified in bytes, not characters. The -/// rationale is that there is no way for you to know what is in the string. -/// There is no way for you to know how many characters are needed to express -/// one thing or another. The only thing you can do to a localized string is -/// search for delimiters and modify text between them as opaque blocks. If you -/// do anything else, you are hardcoding yourself into a locale! So stop it! -/// -class string : public memblock { -public: - typedef char value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef wchar_t wvalue_type; - typedef wvalue_type* wpointer; - typedef const wvalue_type* const_wpointer; - typedef pointer iterator; - typedef const_pointer const_iterator; - typedef value_type& reference; - typedef value_type const_reference; - typedef ::ustl::reverse_iterator<iterator> reverse_iterator; - typedef ::ustl::reverse_iterator<const_iterator> const_reverse_iterator; - typedef utf8in_iterator<const_iterator> utf8_iterator; - static const uoff_t npos = static_cast<uoff_t>(-1); ///< Value that means the end of string. -public: - inline string (void) : memblock () { relink ("",0); } - string (const string& s); - inline string (const string& s, uoff_t o, size_type n); - inline explicit string (const cmemlink& l); - string (const_pointer s); - inline string (const_pointer s, size_type len); - inline string (const_pointer s1, const_pointer s2); - explicit string (size_type n, value_type c = 0); - inline pointer data (void) { return (string::pointer (memblock::data())); } - inline const_pointer c_str (void) const { return (string::const_pointer (memblock::cdata())); } - inline size_type max_size (void) const { size_type s (memblock::max_size()); return (s - !!s); } - inline size_type capacity (void) const { size_type c (memblock::capacity()); return (c - !!c); } - void resize (size_type n); - inline void resize (size_type n, value_type c); - inline void clear (void) { resize (0); } - inline const_iterator begin (void) const { return (const_iterator (memblock::begin())); } - inline iterator begin (void) { return (iterator (memblock::begin())); } - inline const_iterator end (void) const { return (const_iterator (memblock::end())); } - inline iterator end (void) { return (iterator (memblock::end())); } - inline const_reverse_iterator rbegin (void) const { return (const_reverse_iterator (end())); } - inline reverse_iterator rbegin (void) { return (reverse_iterator (end())); } - inline const_reverse_iterator rend (void) const { return (const_reverse_iterator (begin())); } - inline reverse_iterator rend (void) { return (reverse_iterator (begin())); } - inline utf8_iterator utf8_begin (void) const { return (utf8_iterator (begin())); } - inline utf8_iterator utf8_end (void) const { return (utf8_iterator (end())); } - inline const_reference at (uoff_t pos) const { assert (pos <= size() && begin()); return (begin()[pos]); } - inline reference at (uoff_t pos) { assert (pos <= size() && begin()); return (begin()[pos]); } - inline const_iterator iat (uoff_t pos) const { return (begin() + min (pos, size())); } - inline iterator iat (uoff_t pos) { return (begin() + min (pos, size())); } - const_iterator wiat (uoff_t i) const; - inline iterator wiat (uoff_t i) { return (const_cast<iterator>(const_cast<const string*>(this)->wiat(i))); } - inline const_reference back (void) const { return (at(size()-1)); } - inline reference back (void) { return (at(size()-1)); } - inline size_type length (void) const { return (distance (utf8_begin(), utf8_end())); } - inline void append (const_iterator i1, const_iterator i2) { append (i1, distance (i1, i2)); } - void append (const_pointer s, size_type len); - void append (const_pointer s); - void append (size_type n, const_reference c); - inline void append (size_type n, wvalue_type c) { insert (size(), c, n); } - inline void append (const_wpointer s1, const_wpointer s2) { insert (size(), s1, s2); } - inline void append (const_wpointer s) { const_wpointer se (s); for (;se&&*se;++se) ; append (s, se); } - inline void append (const string& s) { append (s.begin(), s.end()); } - inline void append (const string& s, uoff_t o, size_type n) { append (s.iat(o), s.iat(o+n)); } - inline void assign (const_iterator i1, const_iterator i2) { assign (i1, distance (i1, i2)); } - void assign (const_pointer s, size_type len); - void assign (const_pointer s); - inline void assign (const_wpointer s1, const_wpointer s2) { clear(); append (s1, s2); } - inline void assign (const_wpointer s1) { clear(); append (s1); } - inline void assign (const string& s) { assign (s.begin(), s.end()); } - inline void assign (const string& s, uoff_t o, size_type n) { assign (s.iat(o), s.iat(o+n)); } - size_type copyto (pointer p, size_type n, const_iterator start = NULL) const; - inline int compare (const string& s) const { return (compare (begin(), end(), s.begin(), s.end())); } - inline int compare (const_pointer s) const { return (compare (begin(), end(), s, s + strlen(s))); } - static int compare (const_iterator first1, const_iterator last1, const_iterator first2, const_iterator last2); - inline operator const value_type* (void) const; - inline operator value_type* (void); - inline const string& operator= (const string& s) { assign (s.begin(), s.end()); return (*this); } - inline const string& operator= (const_reference c) { assign (&c, 1); return (*this); } - inline const string& operator= (const_pointer s) { assign (s); return (*this); } - inline const string& operator= (const_wpointer s) { assign (s); return (*this); } - inline const string& operator+= (const string& s) { append (s.begin(), s.size()); return (*this); } - inline const string& operator+= (const_reference c) { append (1, c); return (*this); } - inline const string& operator+= (const_pointer s) { append (s); return (*this); } - inline const string& operator+= (wvalue_type c) { append (1, c); return (*this); } - inline const string& operator+= (const_wpointer s) { append (s); return (*this); } - inline string operator+ (const string& s) const; - inline bool operator== (const string& s) const { return (memblock::operator== (s)); } - bool operator== (const_pointer s) const; - inline bool operator== (const_reference c) const { return (size() == 1 && c == at(0)); } - inline bool operator!= (const string& s) const { return (!operator== (s)); } - inline bool operator!= (const_pointer s) const { return (!operator== (s)); } - inline bool operator!= (const_reference c) const { return (!operator== (c)); } - inline bool operator< (const string& s) const { return (0 > compare (s)); } - inline bool operator< (const_pointer s) const { return (0 > compare (s)); } - inline bool operator< (const_reference c) const { return (0 > compare (begin(), end(), &c, &c + 1)); } - inline bool operator> (const_pointer s) const { return (0 < compare (s)); } - void insert (const uoff_t ip, wvalue_type c, size_type n = 1); - void insert (const uoff_t ip, const_wpointer first, const_wpointer last, const size_type n = 1); - iterator insert (iterator start, const_reference c, size_type n = 1); - iterator insert (iterator start, const_pointer s, size_type n = 1); - iterator insert (iterator start, const_pointer first, const_iterator last, size_type n = 1); - inline void insert (uoff_t ip, const_pointer s, size_type nlen) { insert (iat(ip), s, s + nlen); } - inline void insert (uoff_t ip, size_type n, value_type c) { insert (iat(ip), c, n); } - inline void insert (uoff_t ip, const string& s, uoff_t sp, size_type slen) { insert (iat(ip), s.iat(sp), s.iat(sp + slen)); } - iterator erase (iterator epo, size_type n = 1); - void erase (uoff_t epo, size_type n = 1); - inline iterator erase (iterator first, const_iterator last) { return (erase (first, size_type(distance(first,last)))); } - inline void eraser (uoff_t first, uoff_t last) { erase (iat(first), iat(last)); } - inline void push_back (const_reference c) { append (1, c); } - inline void push_back (wvalue_type c) { append (1, c); } - inline void pop_back (void) { resize (size() - 1); } - void replace (iterator first, iterator last, const_pointer s); - void replace (iterator first, iterator last, const_pointer i1, const_pointer i2, size_type n = 1); - inline void replace (iterator first, iterator last, const string& s) { replace (first, last, s.begin(), s.end()); } - inline void replace (iterator first, iterator last, const_pointer s, size_type slen) { replace (first, last, s, s + slen); } - inline void replace (iterator first, iterator last, size_type n, value_type c) { replace (first, last, &c, &c + 1, n); } - inline void replace (uoff_t rp, size_type n, const string& s) { replace (iat(rp), iat(rp + n), s); } - inline void replace (uoff_t rp, size_type n, const string& s, uoff_t sp, size_type slen) { replace (iat(rp), iat(rp + n), s.iat(sp), s.iat(sp + slen)); } - inline void replace (uoff_t rp, size_type n, const_pointer s, size_type slen) { replace (iat(rp), iat(rp + n), s, s + slen); } - inline void replace (uoff_t rp, size_type n, const_pointer s) { replace (iat(rp), iat(rp + n), string(s)); } - inline void replace (uoff_t rp, size_type n, size_type count, value_type c) { replace (iat(rp), iat(rp + n), count, c); } - inline string substr (uoff_t o, size_type n = npos) const { return (string (*this, o, n)); } - uoff_t find (const_reference c, uoff_t pos = 0) const; - uoff_t find (const string& s, uoff_t pos = 0) const; - uoff_t rfind (const_reference c, uoff_t pos = npos) const; - uoff_t rfind (const string& s, uoff_t pos = npos) const; - uoff_t find_first_of (const string& s, uoff_t pos = 0) const; - uoff_t find_first_not_of (const string& s, uoff_t pos = 0) const; - uoff_t find_last_of (const string& s, uoff_t pos = npos) const; - uoff_t find_last_not_of (const string& s, uoff_t pos = npos) const; - int vformat (const char* fmt, va_list args); - int format (const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))); - void read (istream&); - void write (ostream& os) const; - size_t stream_size (void) const; - static hashvalue_t hash (const char* f1, const char* l1); -protected: - virtual size_type minimumFreeCapacity (void) const throw() __attribute__((const)); -}; - -//---------------------------------------------------------------------- - -/// Assigns itself the value of string \p s -inline string::string (const cmemlink& s) -: memblock () -{ - assign (const_iterator (s.begin()), s.size()); -} - -/// Assigns itself a [o,o+n) substring of \p s. -inline string::string (const string& s, uoff_t o, size_type n) -: memblock() -{ - assign (s, o, n); -} - -/// Copies the value of \p s of length \p len into itself. -inline string::string (const_pointer s, size_type len) -: memblock () -{ - assign (s, len); -} - -/// Copies into itself the string data between \p s1 and \p s2 -inline string::string (const_pointer s1, const_pointer s2) -: memblock () -{ - assert (s1 <= s2 && "Negative ranges result in memory allocation errors."); - assign (s1, s2); -} - -/// Returns the pointer to the first character. -inline string::operator const string::value_type* (void) const -{ - assert ((!end() || !*end()) && "This string is linked to data that is not 0-terminated. This may cause serious security problems. Please assign the data instead of linking."); - return (begin()); -} - -/// Returns the pointer to the first character. -inline string::operator string::value_type* (void) -{ - assert ((end() && !*end()) && "This string is linked to data that is not 0-terminated. This may cause serious security problems. Please assign the data instead of linking."); - return (begin()); -} - -/// Concatenates itself with \p s -inline string string::operator+ (const string& s) const -{ - string result (*this); - result += s; - return (result); -} - -/// Resize to \p n and fill new entries with \p c -inline void string::resize (size_type n, value_type c) -{ - const size_type oldn = size(); - resize (n); - fill_n (iat(oldn), max(ssize_t(n-oldn),0), c); -} - -//---------------------------------------------------------------------- -// Operators needed to avoid comparing pointer to pointer - -#define PTR_STRING_CMP(op, impl) \ -inline bool op (const char* s1, const string& s2) { return impl; } -PTR_STRING_CMP (operator==, (s2 == s1)) -PTR_STRING_CMP (operator!=, (s2 != s1)) -PTR_STRING_CMP (operator<, (s2 > s1)) -PTR_STRING_CMP (operator<=, (s2 >= s1)) -PTR_STRING_CMP (operator>, (s2 < s1)) -PTR_STRING_CMP (operator>=, (s2 <= s1)) -#undef PTR_STRING_CMP - -//---------------------------------------------------------------------- - -inline hashvalue_t hash_value (const char* first, const char* last) -{ return (string::hash (first, last)); } -inline hashvalue_t hash_value (const char* v) -{ return (hash_value (v, v + strlen(v))); } - -//---------------------------------------------------------------------- - -} // namespace ustl - -// Specialization for stream alignment -ALIGNOF (ustl::string, alignof (string::value_type())) - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/utf8.h +++ /dev/null @@ -1,215 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. -// -// This file contains stream iterators that read and write UTF-8 encoded -// characters. The encoding is defined as follows: -// -// U-00000000 - U-0000007F: 0xxxxxxx -// U-00000080 - U-000007FF: 110xxxxx 10xxxxxx -// U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx -// U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx -// U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx -// U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx -// U-80000000 - U-FFFFFFFF: 11111110 100000xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx - -#ifndef UTF8_H_3D7AEEEB3A88928D4D280B785F78B6F4 -#define UTF8_H_3D7AEEEB3A88928D4D280B785F78B6F4 - -#include "uiterator.h" - -namespace ustl { - -//---------------------------------------------------------------------- - -typedef uint8_t utf8subchar_t; ///< Type for the encoding subcharacters. - -//---------------------------------------------------------------------- - -inline size_t Utf8Bytes (wchar_t v) __attribute__((const)); -inline size_t Utf8Bytes (const wchar_t* first, const wchar_t* last) __attribute__((pure)); -inline size_t Utf8SequenceBytes (wchar_t c) __attribute__((const)); - -//---------------------------------------------------------------------- - -/// Returns the number of bytes required to UTF-8 encode \p v. -inline size_t Utf8Bytes (wchar_t v) -{ - if ((uint32_t) v < 128) - return (1); - size_t n; - #if __i386__ || __x86_64__ - uint32_t r = 0; - asm ("bsr\t%2, %%eax\n\t" - "add\t$4, %0\n\t" - "div\t%3":"=a"(n),"+d"(r):"r"(v),"c"(5)); - #else - static const uint32_t c_Bounds[7] = { 0x0000007F, 0x000007FF, 0x0000FFFF, 0x001FFFFF, 0x03FFFFFF, 0x7FFFFFFF, 0xFFFFFFFF }; - for (n = 0; c_Bounds[n++] < uint32_t(v);); - #endif - return (n); -} - -/// Measures the size of a wchar_t array in UTF-8 encoding. -inline size_t Utf8Bytes (const wchar_t* first, const wchar_t* last) -{ - size_t bc = 0; - for (; first < last; ++first) - bc += Utf8Bytes(*first); - return (bc); -} - -/// Returns the number of bytes in a UTF-8 sequence that starts with \p c. -inline size_t Utf8SequenceBytes (wchar_t c) // a wchar_t to keep c in a full register -{ - // Count the leading bits. Header bits are 1 * nBytes followed by a 0. - // 0 - single byte character. Take 7 bits (0xFF >> 1) - // 1 - error, in the middle of the character. Take 6 bits (0xFF >> 2) - // so you will keep reading invalid entries until you hit the next character. - // >2 - multibyte character. Take remaining bits, and get the next bytes. - // All errors are ignored, since the user can not correct them. - // - wchar_t mask = 0x80; - size_t nBytes = 0; - for (; c & mask; ++nBytes) - mask >>= 1; - return (nBytes ? nBytes : 1); // A sequence is always at least 1 byte. -} - -//---------------------------------------------------------------------- - -/// \class utf8in_iterator utf8.h ustl.h -/// \ingroup IteratorAdaptors -/// -/// \brief An iterator adaptor to character containers for reading UTF-8 encoded text. -/// -/// For example, you can copy from ustl::string to ustl::vector<wchar_t> with -/// copy (utf8in (str.begin()), utf8in (str.end()), back_inserter(wvect)); -/// There is no error handling; if the reading frame slips you'll get extra -/// characters, one for every misaligned byte. Although it is possible to skip -/// to the start of the next character, that would result in omitting the -/// misformatted character and the one after it, making it very difficult to -/// detect by the user. It is better to write some strange characters and let -/// the user know his file is corrupted. Another problem is overflow on bad -/// encodings (like a 0xFF on the end of a string). This is checked through -/// the end-of-string nul character, which will always be there as long as -/// you are using the string class. -/// -template <typename Iterator, typename WChar = wchar_t> -class utf8in_iterator { -public: - typedef typename iterator_traits<Iterator>::value_type value_type; - typedef typename iterator_traits<Iterator>::difference_type difference_type; - typedef typename iterator_traits<Iterator>::pointer pointer; - typedef typename iterator_traits<Iterator>::reference reference; -public: - explicit utf8in_iterator (const Iterator& is) : m_i (is), m_v (0) { Read(); } - utf8in_iterator (const utf8in_iterator& i) : m_i (i.m_i), m_v (i.m_v) {} - inline const utf8in_iterator& operator= (const utf8in_iterator& i) { m_i = i.m_i; m_v = i.m_v; return (*this); } - inline Iterator base (void) const { return (m_i - (Utf8Bytes(m_v) - 1)); } - /// Reads and returns the next value. - inline WChar operator* (void) const { return (m_v); } - inline utf8in_iterator& operator++ (void) { ++m_i; Read(); return (*this); } - inline utf8in_iterator operator++ (int) { utf8in_iterator old (*this); operator++(); return (old); } - inline utf8in_iterator& operator+= (uoff_t n) { while (n--) operator++(); return (*this); } - inline utf8in_iterator operator+ (uoff_t n) { utf8in_iterator v (*this); return (v += n); } - inline bool operator== (const utf8in_iterator& i) const { return (m_i == i.m_i); } - inline bool operator< (const utf8in_iterator& i) const { return (m_i < i.m_i); } - difference_type operator- (const utf8in_iterator& i) const; -private: - void Read (void); -private: - Iterator m_i; - WChar m_v; -}; - -/// Steps to the next character and updates current returnable value. -template <typename Iterator, typename WChar> -void utf8in_iterator<Iterator,WChar>::Read (void) -{ - const utf8subchar_t c = *m_i; - size_t nBytes = Utf8SequenceBytes (c); - m_v = c & (0xFF >> nBytes); // First byte contains bits after the header. - while (--nBytes && *++m_i) // Each subsequent byte has 6 bits. - m_v = (m_v << 6) | (*m_i & 0x3F); -} - -/// Returns the distance in characters (as opposed to the distance in bytes). -template <typename Iterator, typename WChar> -typename utf8in_iterator<Iterator,WChar>::difference_type -utf8in_iterator<Iterator,WChar>::operator- (const utf8in_iterator<Iterator,WChar>& last) const -{ - difference_type dist = 0; - for (Iterator first (last.m_i); first < m_i; ++dist) - first = advance (first, Utf8SequenceBytes (*first)); - return (dist); -} - -//---------------------------------------------------------------------- - -/// \class utf8out_iterator utf8.h ustl.h -/// \ingroup IteratorAdaptors -/// -/// \brief An iterator adaptor to character containers for writing UTF-8 encoded text. -/// -template <typename Iterator, typename WChar = wchar_t> -class utf8out_iterator { -public: - typedef typename iterator_traits<Iterator>::value_type value_type; - typedef typename iterator_traits<Iterator>::difference_type difference_type; - typedef typename iterator_traits<Iterator>::pointer pointer; - typedef typename iterator_traits<Iterator>::reference reference; -public: - explicit utf8out_iterator (const Iterator& os) : m_i (os) {} - utf8out_iterator (const utf8out_iterator& i) : m_i (i.m_i) {} - inline const Iterator& base (void) const { return (m_i); } - /// Writes \p v into the stream. - utf8out_iterator& operator= (WChar v); - inline utf8out_iterator& operator* (void) { return (*this); } - inline utf8out_iterator& operator++ (void) { return (*this); } - inline utf8out_iterator operator++ (int) { return (*this); } - inline bool operator== (const utf8out_iterator& i) const { return (m_i == i.m_i); } - inline bool operator< (const utf8out_iterator& i) const { return (m_i < i.m_i); } -private: - Iterator m_i; -}; - -/// Writes \p v into the stream. -template <typename Iterator, typename WChar> -utf8out_iterator<Iterator,WChar>& utf8out_iterator<Iterator,WChar>::operator= (WChar v) -{ - const size_t nBytes = Utf8Bytes (v); - if (nBytes > 1) { - // Write the bits 6 bits at a time, except for the first one, - // which may be less than 6 bits. - register wchar_t shift = nBytes * 6; - *m_i++ = ((v >> (shift -= 6)) & 0x3F) | (0xFF << (8 - nBytes)); - while (shift) - *m_i++ = ((v >> (shift -= 6)) & 0x3F) | 0x80; - } else // If only one byte, there is no header. - *m_i++ = v; - return (*this); -} - -//---------------------------------------------------------------------- - -/// Returns a UTF-8 adaptor writing to \p i. Useful in conjuction with back_insert_iterator. -template <typename Iterator> -inline utf8out_iterator<Iterator> utf8out (Iterator i) -{ - return (utf8out_iterator<Iterator> (i)); -} - -/// Returns a UTF-8 adaptor reading from \p i. -template <typename Iterator> -inline utf8in_iterator<Iterator> utf8in (Iterator i) -{ - return (utf8in_iterator<Iterator> (i)); -} - -//---------------------------------------------------------------------- - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/utuple.h +++ /dev/null @@ -1,332 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UTUPLE_H_7324ADEC49B397CA74A56F6050FD5A6B -#define UTUPLE_H_7324ADEC49B397CA74A56F6050FD5A6B - -#include "ualgo.h" -#include "metamac.h" - -namespace ustl { - -/// \class tuple utuple.h ustl.h -/// \ingroup Sequences -/// -/// \brief A fixed-size array of \p N \p Ts. -/// -template <size_t N, typename T> -class tuple { -public: - typedef T value_type; - typedef size_t size_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef pointer iterator; - typedef const_pointer const_iterator; - typedef ::ustl::reverse_iterator<iterator> reverse_iterator; - typedef ::ustl::reverse_iterator<const_iterator> const_reverse_iterator; - typedef pair<iterator,iterator> range_t; - typedef pair<const_iterator,const_iterator> const_range_t; -public: - template <typename T2> - inline tuple (const tuple<N,T2>& t); - inline tuple (const tuple<N,T>& t); - inline tuple (const_pointer v); - inline tuple (void); - explicit inline tuple (const_reference v0, const_reference v1 = T(), const_reference v2 = T(), const_reference v3 = T()); - inline iterator begin (void) { return (m_v); } - inline const_iterator begin (void) const { return (m_v); } - inline iterator end (void) { return (begin() + N); } - inline const_iterator end (void) const { return (begin() + N); } - inline size_type size (void) const { return (N); } - inline size_type max_size (void) const { return (N); } - inline bool empty (void) const { return (N == 0); } - inline const_reference at (size_type i) const { return (m_v[i]); } - inline reference at (size_type i) { return (m_v[i]); } - inline const_reference operator[] (size_type i) const { return (m_v[i]); } - inline reference operator[] (size_type i) { return (m_v[i]); } - template <typename T2> - inline const tuple& operator= (const tuple<N,T2>& src); - inline const tuple& operator= (const tuple<N,T>& src); - inline const tuple& operator+= (const_reference v) - { for (uoff_t i = 0; i < N; ++ i) m_v[i] += v; return (*this); } - inline const tuple& operator-= (const_reference v) - { for (uoff_t i = 0; i < N; ++ i) m_v[i] -= v; return (*this); } - inline const tuple& operator*= (const_reference v) - { for (uoff_t i = 0; i < N; ++ i) m_v[i] *= v; return (*this); } - inline const tuple& operator/= (const_reference v) - { for (uoff_t i = 0; i < N; ++ i) m_v[i] /= v; return (*this); } - inline const tuple operator+ (const_reference v) const - { tuple result; for (uoff_t i = 0; i < N; ++ i) result[i] = m_v[i] + v; return (result); } - inline const tuple operator- (const_reference v) const - { tuple result; for (uoff_t i = 0; i < N; ++ i) result[i] = m_v[i] - v; return (result); } - inline const tuple operator* (const_reference v) const - { tuple result; for (uoff_t i = 0; i < N; ++ i) result[i] = m_v[i] * v; return (result); } - inline const tuple operator/ (const_reference v) const - { tuple result; for (uoff_t i = 0; i < N; ++ i) result[i] = m_v[i] / v; return (result); } - inline void swap (tuple<N,T>& v) - { for (uoff_t i = 0; i < N; ++ i) ::ustl::swap (m_v[i], v.m_v[i]); } - inline void read (istream& is) { nr_container_read (is, *this); } - inline void write (ostream& os) const { nr_container_write (os, *this); } - inline void text_write (ostringstream& os) const { container_text_write (os, *this); } - inline size_t stream_size (void) const { return (nr_container_stream_size (*this)); } -private: - T m_v [N]; -}; - -} // namespace ustl - -#include "simd.h" - -namespace ustl { - -template <size_t N, typename T> -template <typename T2> -inline tuple<N,T>::tuple (const tuple<N,T2>& t) -{ simd::pconvert (t, *this, simd::fcast<T2,T>()); } - -template <size_t N, typename T> -inline tuple<N,T>::tuple (const tuple<N,T>& t) -{ simd::passign (t, *this); } - -template <size_t N, typename T> -inline tuple<N,T>::tuple (const_pointer v) -{ simd::ipassign (v, *this); } - -template <size_t N, typename T> -inline tuple<N,T>::tuple (void) -{ - const T v = T(); - if (N > 4 || !numeric_limits<T>::is_integral) - fill_n (m_v, N, v); - else { - m_v[0] = v; - if (N > 1) m_v[1] = v; - if (N > 2) m_v[2] = v; - if (N > 3) m_v[3] = v; - } -} - -template <size_t N, typename T> -inline tuple<N,T>::tuple (const_reference v0, const_reference v1, const_reference v2, const_reference v3) -{ - m_v[0] = v0; - if (N > 1) m_v[1] = v1; - if (N > 2) m_v[2] = v2; - if (N > 3) m_v[3] = v3; - if (N > 4) fill_n (m_v + 4, N - 4, T()); -} - -template <size_t N, typename T> -template <typename T2> -inline const tuple<N,T>& tuple<N,T>::operator= (const tuple<N,T2>& src) -{ simd::pconvert (src, *this, simd::fcast<T2,T>()); return (*this); } - -template <size_t N, typename T> -inline const tuple<N,T>& tuple<N,T>::operator= (const tuple<N,T>& src) -{ simd::passign (src, *this); return (*this); } - -template <size_t N, typename T1, typename T2> -inline bool operator== (const tuple<N,T1>& t1, const tuple<N,T2>& t2) -{ - for (uoff_t i = 0; i < N; ++ i) - if (t1[i] != t2[i]) - return (false); - return (true); -} - -template <size_t N, typename T1, typename T2> -inline bool operator< (const tuple<N,T1>& t1, const tuple<N,T2>& t2) -{ - for (uoff_t i = 0; i < N && t1[i] <= t2[i]; ++ i) - if (t1[i] < t2[i]) - return (true); - return (false); -} - -template <size_t N, typename T1, typename T2> -inline const tuple<N,T1>& operator+= (tuple<N,T1>& t1, const tuple<N,T2>& t2) - { for (uoff_t i = 0; i < N; ++ i) t1[i] = T1(t1[i] + t2[i]); return (t1); } - -template <size_t N, typename T1, typename T2> -inline const tuple<N,T1>& operator-= (tuple<N,T1>& t1, const tuple<N,T2>& t2) - { for (uoff_t i = 0; i < N; ++ i) t1[i] = T1(t1[i] - t2[i]); return (t1); } - -template <size_t N, typename T1, typename T2> -inline const tuple<N,T1>& operator*= (tuple<N,T1>& t1, const tuple<N,T2>& t2) - { for (uoff_t i = 0; i < N; ++ i) t1[i] = T1(t1[i] * t2[i]); return (t1); } - -template <size_t N, typename T1, typename T2> -inline const tuple<N,T1>& operator/= (tuple<N,T1>& t1, const tuple<N,T2>& t2) - { for (uoff_t i = 0; i < N; ++ i) t1[i] = T1(t1[i] / t2[i]); return (t1); } - -template <size_t N, typename T1, typename T2> -inline const tuple<N,T1> operator+ (const tuple<N,T1>& t1, const tuple<N,T2>& t2) -{ - tuple<N,T1> result; - for (uoff_t i = 0; i < N; ++ i) result[i] = T1(t1[i] + t2[i]); - return (result); -} - -template <size_t N, typename T1, typename T2> -inline const tuple<N,T1> operator- (const tuple<N,T1>& t1, const tuple<N,T2>& t2) -{ - tuple<N,T1> result; - for (uoff_t i = 0; i < N; ++ i) result[i] = T1(t1[i] - t2[i]); - return (result); -} - -template <size_t N, typename T1, typename T2> -inline const tuple<N,T1> operator* (const tuple<N,T1>& t1, const tuple<N,T2>& t2) -{ - tuple<N,T1> result; - for (uoff_t i = 0; i < N; ++ i) result[i] = T1(t1[i] * t2[i]); - return (result); -} - -template <size_t N, typename T1, typename T2> -inline const tuple<N,T1> operator/ (const tuple<N,T1>& t1, const tuple<N,T2>& t2) -{ - tuple<N,T1> result; - for (uoff_t i = 0; i < N; ++ i) result[i] = T1(t1[i] / t2[i]); - return (result); -} - -//---------------------------------------------------------------------- -// Define SIMD specializations for member functions. - -#if CPU_HAS_SSE -#define SSE_TUPLE_SPECS(n,type) \ -template <> inline tuple<n,type>::tuple (void) \ -{ asm("xorps %%xmm0, %%xmm0\n\tmovups %%xmm0, %0":"+m"(m_v[0])::"xmm0","memory"); } \ -template<> inline void tuple<n,type>::swap (tuple<n,type>& v) \ -{ \ - asm ("movups %0,%%xmm0\n\tmovups %1,%%xmm1\n\t" \ - "movups %%xmm0,%1\n\tmovups %%xmm1,%0" \ - : "+m"(m_v[0]), "+m"(v.m_v[0]) :: "xmm0","xmm1","memory"); \ -} -SSE_TUPLE_SPECS(4,float) -SSE_TUPLE_SPECS(4,int32_t) -SSE_TUPLE_SPECS(4,uint32_t) -#undef SSE_TUPLE_SPECS -#endif -#if SIZE_OF_LONG == 8 && __GNUC__ -#define LONG_TUPLE_SPECS(n,type) \ -template <> inline tuple<n,type>::tuple (void) \ -{ asm("":"+m"(m_v[0])::"memory"); \ - *noalias_cast<long*>(m_v) = 0; } \ -template<> inline void tuple<n,type>::swap (tuple<n,type>& v) \ -{ asm("":"+m"(m_v[0]),"+m"(v.m_v[0])::"memory"); \ - iter_swap (noalias_cast<long*>(m_v), noalias_cast<long*>(v.m_v)); \ - asm("":"+m"(m_v[0]),"+m"(v.m_v[0])::"memory"); \ -} -LONG_TUPLE_SPECS(2,float) -LONG_TUPLE_SPECS(4,int16_t) -LONG_TUPLE_SPECS(4,uint16_t) -LONG_TUPLE_SPECS(2,int32_t) -LONG_TUPLE_SPECS(2,uint32_t) -LONG_TUPLE_SPECS(8,int8_t) -LONG_TUPLE_SPECS(8,uint8_t) -#undef LONG_TUPLE_SPECS -#elif CPU_HAS_MMX -#define MMX_TUPLE_SPECS(n,type) \ -template <> inline tuple<n,type>::tuple (void) \ -{ asm ("pxor %%mm0, %%mm0\n\tmovq %%mm0, %0" \ - :"=m"(m_v[0])::"mm0","st","memory"); simd::reset_mmx(); } \ -template<> inline void tuple<n,type>::swap (tuple<n,type>& v) \ -{ asm ("movq %2,%%mm0\n\tmovq %3,%%mm1\n\t" \ - "movq %%mm0,%1\n\tmovq %%mm1,%0" \ - :"=m"(m_v[0]),"=m"(v.m_v[0]):"m"(m_v[0]),"m"(v.m_v[0]):"mm0","mm1","st","st(1)","memory"); \ - simd::reset_mmx(); \ -} -MMX_TUPLE_SPECS(2,float) -MMX_TUPLE_SPECS(4,int16_t) -MMX_TUPLE_SPECS(4,uint16_t) -MMX_TUPLE_SPECS(2,int32_t) -MMX_TUPLE_SPECS(2,uint32_t) -MMX_TUPLE_SPECS(8,int8_t) -MMX_TUPLE_SPECS(8,uint8_t) -#undef MMX_TUPLE_SPECS -#endif - -#if __i386__ || __x86_64__ -#define UINT32_TUPLE_SPECS(type,otype) \ -template <> inline tuple<2,type>::tuple (void) \ -{ asm("":"+m"(m_v[0]),"+m"(m_v[1])::"memory"); \ - *noalias_cast<uint32_t*>(m_v) = 0; \ - asm("":"+m"(m_v[0]),"+m"(m_v[1])::"memory"); }\ -template <> inline const tuple<2,type>& tuple<2,type>::operator= (const tuple<2,type>& v)\ -{ asm ("mov %3, %0" \ - :"=m"(*noalias_cast<uint32_t*>(m_v)),"=m"(m_v[0]),"=m"(m_v[1]) \ - :"r"(*noalias_cast<const uint32_t*>(v.begin())),"m"(v[0]),"m"(v[1]):"memory"); \ - return (*this); } \ -template <> template <> \ -inline const tuple<2,type>& tuple<2,type>::operator= (const tuple<2,otype>& v)\ -{ asm ("mov %3, %0" \ - :"=m"(*noalias_cast<uint32_t*>(m_v)),"=m"(m_v[0]),"=m"(m_v[1]) \ - :"r"(*noalias_cast<const uint32_t*>(v.begin())),"m"(v[0]),"m"(v[1]):"memory"); \ - return (*this); } \ -template <> inline tuple<2,type>::tuple (const tuple<2,type>& v) \ -{ operator= (v); } \ -template <> template <> \ -inline tuple<2,type>::tuple (const tuple<2,otype>& v) \ -{ operator= (v); } \ -template<> inline void tuple<2,type>::swap (tuple<2,type>& v) \ -{ asm(""::"m"(m_v[0]),"m"(m_v[1]),"m"(v.m_v[0]),"m"(v.m_v[1]):"memory");\ - iter_swap (noalias_cast<uint32_t*>(m_v), noalias_cast<uint32_t*>(v.m_v)); \ - asm("":"=m"(m_v[0]),"=m"(m_v[1]),"=m"(v.m_v[0]),"=m"(v.m_v[1])::"memory"); } \ -template <> inline const tuple<2,type>& operator+= (tuple<2,type>& t1, const tuple<2,type>& t2) \ - { t1[0] += t2[0]; t1[1] += t2[1]; return (t1); } \ -template <> inline const tuple<2,type>& operator-= (tuple<2,type>& t1, const tuple<2,type>& t2) \ - { t1[0] -= t2[0]; t1[1] -= t2[1]; return (t1); } \ -template <> inline const tuple<2,type> operator+ (const tuple<2,type>& t1, const tuple<2,type>& t2) \ - { return (tuple<2,type> (t1[0] + t2[0], t1[1] + t2[1])); } \ -template <> inline const tuple<2,type> operator- (const tuple<2,type>& t1, const tuple<2,type>& t2) \ - { return (tuple<2,type> (t1[0] - t2[0], t1[1] - t2[1])); } -UINT32_TUPLE_SPECS(int16_t,uint16_t) -UINT32_TUPLE_SPECS(uint16_t,int16_t) -#undef UINT32_TUPLE_SPECS -#endif - -#undef TUPLEV_R1 -#undef TUPLEV_R2 -#undef TUPLEV_W1 -#undef TUPLEV_W2 - -#define SIMD_TUPLE_PACKOP(N,T) \ -template <> inline const tuple<N,T>& operator+= (tuple<N,T>& t1, const tuple<N,T>& t2) \ - { simd::padd (t2, t1); return (t1); } \ -template <> inline const tuple<N,T>& operator-= (tuple<N,T>& t1, const tuple<N,T>& t2) \ - { simd::psub (t2, t1); return (t1); } \ -template <> inline const tuple<N,T>& operator*= (tuple<N,T>& t1, const tuple<N,T>& t2) \ - { simd::pmul (t2, t1); return (t1); } \ -template <> inline const tuple<N,T>& operator/= (tuple<N,T>& t1, const tuple<N,T>& t2) \ - { simd::pdiv (t2, t1); return (t1); } \ -template <> inline const tuple<N,T> operator+ (const tuple<N,T>& t1, const tuple<N,T>& t2) \ - { tuple<N,T> result (t1); simd::padd (t2, result); return (result); } \ -template <> inline const tuple<N,T> operator- (const tuple<N,T>& t1, const tuple<N,T>& t2) \ - { tuple<N,T> result (t1); simd::psub (t2, result); return (result); } \ -template <> inline const tuple<N,T> operator* (const tuple<N,T>& t1, const tuple<N,T>& t2) \ - { tuple<N,T> result (t1); simd::pmul (t2, result); return (result); } \ -template <> inline const tuple<N,T> operator/ (const tuple<N,T>& t1, const tuple<N,T>& t2) \ - { tuple<N,T> result (t1); simd::pdiv (t2, result); return (result); } -SIMD_TUPLE_PACKOP(4,float) -SIMD_TUPLE_PACKOP(2,float) -SIMD_TUPLE_PACKOP(2,double) -SIMD_TUPLE_PACKOP(4,int32_t) -SIMD_TUPLE_PACKOP(4,uint32_t) -SIMD_TUPLE_PACKOP(4,int16_t) -SIMD_TUPLE_PACKOP(4,uint16_t) -SIMD_TUPLE_PACKOP(2,int32_t) -SIMD_TUPLE_PACKOP(2,uint32_t) -SIMD_TUPLE_PACKOP(8,int8_t) -SIMD_TUPLE_PACKOP(8,uint8_t) -#undef SIMD_TUPLE_PACKOP - -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/utypes.h +++ /dev/null @@ -1,67 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UTYPES_H_118BBB3B50B7DBF22F5460C52E515C83 -#define UTYPES_H_118BBB3B50B7DBF22F5460C52E515C83 - -#include "config.h" -#ifndef STDC_HEADERS - #error "This library requires standard C and C++ headers to compile." -#endif -#ifndef STDUNIX_HEADERS - #error "This library compiles only on UNIX systems." -#endif -#define __STDC_LIMIT_MACROS // For WCHAR_MIN and WCHAR_MAX in stdint. -#define __STDC_CONSTANT_MACROS // For UINT??_C macros to avoid using L and UL suffixes on constants. -#if HAVE_STDINT_H - #include <stdint.h> -#elif HAVE_INTTYPES_H - #include <inttypes.h> -#else - #error "Need standard integer types definitions, usually in stdint.h" -#endif -#include <stddef.h> // For ptrdiff_t, size_t -#include <limits.h> -#include <float.h> -#if HAVE_SYS_TYPES_H - #include <sys/types.h> -#endif -#ifndef SIZE_MAX - #define SIZE_MAX UINT_MAX -#endif -#if sun || __sun // Solaris defines UINTPTR_MAX as empty. - #undef UINTPTR_MAX - #define UINTPTR_MAX ULONG_MAX -#endif -#ifndef WCHAR_MAX - #ifdef __WCHAR_MAX__ - #define WCHAR_MAX __WCHAR_MAX__ - #else - #define WCHAR_MAX CHAR_MAX - #endif -#endif -#if HAVE_LONG_LONG - #ifndef LLONG_MAX - #define ULLONG_MAX UINT64_C(0xFFFFFFFFFFFFFFFF) - #define LLONG_MAX INT64_C(0x7FFFFFFFFFFFFFFF) - #define LLONG_MIN ULLONG_MAX - #endif -#endif -#ifndef BYTE_ORDER - #define LITTLE_ENDIAN USTL_LITTLE_ENDIAN - #define BIG_ENDIAN USTL_BIG_ENDIAN - #define BYTE_ORDER USTL_BYTE_ORDER -#endif - -typedef size_t uoff_t; ///< A type for storing offsets into blocks measured by size_t. -typedef uint32_t hashvalue_t; ///< Value type returned by the hash functions. -typedef size_t streamsize; ///< Size of stream data -typedef uoff_t streamoff; ///< Offset into a stream - - -#if !defined(UINTPTR_MAX) || !defined(UINT32_C) - #error "If you include stdint.h before ustl.h, define __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS first" -#endif -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/uutility.h +++ /dev/null @@ -1,383 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. -// -/// \file uutility.h -/// \brief Utility templates. - -#ifndef UUTILITY_H_6A58BD296269A82A4AAAA4FD19FDB3AC -#define UUTILITY_H_6A58BD296269A82A4AAAA4FD19FDB3AC - -#include "utypes.h" -#include "traits.h" -#include "ulimits.h" -#include <assert.h> - -namespace ustl { - -#ifdef __GNUC__ - /// Returns the number of elements in a static vector - #define VectorSize(v) (sizeof(v) / sizeof(*v)) -#else - // Old compilers will not be able to evaluate *v on an empty vector. - // The tradeoff here is that VectorSize will not be able to measure arrays of local structs. - #define VectorSize(v) (sizeof(v) / ustl::size_of_elements(1, v)) -#endif - -/// Expands into a ptr,size expression for the given static vector; useful as link arguments. -#define VectorBlock(v) (v)+0, VectorSize(v) // +0 makes it work under gcc 2.95 -/// Expands into a begin,end expression for the given static vector; useful for algorithm arguments. -#define VectorRange(v) VectorBlock(v)+(v) - -/// Indexes into a static array with bounds limit -#define VectorElement(v,i) v[min(uoff_t(i),uoff_t(VectorSize(v)-1))] - -/// Returns the number of bits in the given type -#define BitsInType(t) (sizeof(t) * CHAR_BIT) - -/// Returns the mask of type \p t with the lowest \p n bits set. -#define BitMask(t,n) (t(~t(0)) >> ((sizeof(t) * CHAR_BIT) - (n))) - -/// Argument that is used only in debug builds (as in an assert) -#ifndef NDEBUG - #define DebugArg(x) x -#else - #define DebugArg(x) -#endif - -/// Shorthand for container iteration. -#define foreach(type,i,ctr) for (type i = (ctr).begin(); i != (ctr).end(); ++ i) -/// Shorthand for container reverse iteration. -#define eachfor(type,i,ctr) for (type i = (ctr).rbegin(); i != (ctr).rend(); ++ i) - -#ifndef DOXYGEN_SHOULD_SKIP_THIS -// Macro for passing template types as macro arguments. -// These are deprecated. Use metamac macros instead. Will remove by next release. -#define TEMPLATE_FULL_DECL1(d1,t1) template <d1 t1> -#define TEMPLATE_FULL_DECL2(d1,t1,d2,t2) template <d1 t1, d2 t2> -#define TEMPLATE_FULL_DECL3(d1,t1,d2,t2,d3,t3) template <d1 t1, d2 t2, d3 t3> -#define TEMPLATE_DECL1(t1) TEMPLATE_FULL_DECL1(typename,t1) -#define TEMPLATE_DECL2(t1,t2) TEMPLATE_FULL_DECL2(typename,t1,typename,t2) -#define TEMPLATE_DECL3(t1,t2,t3) TEMPLATE_FULL_DECL3(typename,t1,typename,t2,typename,t3) -#define TEMPLATE_TYPE1(type,a1) type<a1> -#define TEMPLATE_TYPE2(type,a1,a2) type<a1,a2> -#define TEMPLATE_TYPE3(type,a1,a2,a3) type<a1,a2,a3> -#endif - -/// Returns the minimum of \p a and \p b -template <typename T1, typename T2> -inline T1 min (const T1& a, const T2& b) -{ - return (a < b ? a : b); -} - -/// Returns the maximum of \p a and \p b -template <typename T1, typename T2> -inline T1 max (const T1& a, const T2& b) -{ - return (b < a ? a : b); -} - -/// The alignment performed by default. -const size_t c_DefaultAlignment = __alignof__(void*); - -/// \brief Rounds \p n up to be divisible by \p grain -template <typename T> -inline T Align (T n, size_t grain = c_DefaultAlignment) -{ - n += grain - 1; - return (n - n % grain); -} - -/// Returns a NULL pointer cast to T. -template <typename T> -inline T* NullPointer (void) - { return ((T*) NULL); } - -/// \brief Returns a non-dereferentiable value reference. -/// This is useful for passing to alignof or the like which need a value but -/// don't need to actually use it. -template <typename T> -inline T& NullValue (void) - { return (*NullPointer<T>()); } - -/// Offsets an iterator -template <typename T> -inline T advance (T i, ssize_t offset) -{ - return (i + offset); -} - -#ifndef DOXYGEN_SHOULD_SKIP_THIS -/// Offsets a void pointer -template <> -inline const void* advance (const void* p, ssize_t offset) -{ - assert (p || !offset); - return (reinterpret_cast<const uint8_t*>(p) + offset); -} - -/// Offsets a void pointer -template <> -inline void* advance (void* p, ssize_t offset) -{ - assert (p || !offset); - return (reinterpret_cast<uint8_t*>(p) + offset); -} -#endif - -/// Returns the difference \p p1 - \p p2 -template <typename T1, typename T2> -inline ptrdiff_t distance (T1 i1, T2 i2) -{ - return (i2 - i1); -} - -#ifndef DOXYGEN_SHOULD_SKIP_THIS -#define UNVOID_DISTANCE(T1const,T2const) \ -template <> inline ptrdiff_t distance (T1const void* p1, T2const void* p2) \ -{ return ((T2const uint8_t*)(p2) - (T1const uint8_t*)(p1)); } -UNVOID_DISTANCE(,) -UNVOID_DISTANCE(const,const) -UNVOID_DISTANCE(,const) -UNVOID_DISTANCE(const,) -#undef UNVOID_DISTANCE -#endif - -// The compiler issues a warning if an unsigned type is compared to 0. -template <typename T, bool IsSigned> struct __is_negative { inline bool operator()(const T& v) { return (v < 0); } }; -template <typename T> struct __is_negative<T,false> { inline bool operator()(const T&) { return (false); } }; -/// Warning-free way to check if \p v is negative, even if for unsigned types. -template <typename T> inline bool is_negative (const T& v) { return (__is_negative<T,numeric_limits<T>::is_signed>()(v)); } - -/// \brief Returns the absolute value of \p v -/// Unlike the stdlib functions, this is inline and works with all types. -template <typename T> -inline T absv (T v) -{ - return (is_negative(v) ? -v : v); -} - -/// \brief Returns -1 for negative values, 1 for positive, and 0 for 0 -template <typename T> -inline T sign (T v) -{ - return ((0 < v) - is_negative(v)); -} - -/// Returns the absolute value of the distance i1 and i2 -template <typename T1, typename T2> -inline size_t abs_distance (T1 i1, T2 i2) -{ - return (absv (distance(i1, i2))); -} - -/// Returns the size of \p n elements of size \p T -template <typename T> -inline size_t size_of_elements (size_t n, const T*) -{ - return (n * sizeof(T)); -} - -// Defined in byteswap.h, which is usually unusable. -#undef bswap_16 -#undef bswap_32 -#undef bswap_64 - -inline uint16_t bswap_16 (uint16_t v) -{ -#if CPU_HAS_CMPXCHG8 // If it has that, it has bswap. - if (!__builtin_constant_p(v)) asm ("rorw $8, %0":"+r"(v)); else -#endif - v = v << 8 | v >> 8; - return (v); -} -inline uint32_t bswap_32 (uint32_t v) -{ -#if CPU_HAS_CMPXCHG8 - if (!__builtin_constant_p(v)) asm ("bswap %0":"+r"(v)); else -#endif - v = v << 24 | (v & 0xFF00) << 8 | ((v >> 8) & 0xFF00) | v >> 24; - return (v); -} -#if HAVE_INT64_T -inline uint64_t bswap_64 (uint64_t v) -{ -#if x86_64 - if (!__builtin_constant_p(v)) asm ("bswap %0":"+r"(v)); else -#endif - v = (uint64_t(bswap_32(v)) << 32) | bswap_32(v >> 32); - return (v); -} -#endif - -/// \brief Swaps the byteorder of \p v. -template <typename T> -inline T bswap (const T& v) -{ - switch (BitsInType(T)) { - default: return (v); - case 16: return (T (bswap_16 (uint16_t (v)))); - case 32: return (T (bswap_32 (uint32_t (v)))); -#if HAVE_INT64_T - case 64: return (T (bswap_64 (uint64_t (v)))); -#endif - } -} - -#if BYTE_ORDER == BIG_ENDIAN -template <typename T> inline T le_to_native (const T& v) { return (bswap (v)); } -template <typename T> inline T be_to_native (const T& v) { return (v); } -template <typename T> inline T native_to_le (const T& v) { return (bswap (v)); } -template <typename T> inline T native_to_be (const T& v) { return (v); } -#elif BYTE_ORDER == LITTLE_ENDIAN -template <typename T> inline T le_to_native (const T& v) { return (v); } -template <typename T> inline T be_to_native (const T& v) { return (bswap (v)); } -template <typename T> inline T native_to_le (const T& v) { return (v); } -template <typename T> inline T native_to_be (const T& v) { return (bswap (v)); } -#endif // BYTE_ORDER - -/// Deletes \p p and sets it to NULL -template <typename T> -inline void Delete (T*& p) -{ - delete p; - p = NULL; -} - -/// Deletes \p p as an array and sets it to NULL -template <typename T> -inline void DeleteVector (T*& p) -{ - delete [] p; - p = NULL; -} - -/// Template of making != from ! and == -template <typename T> -inline bool operator!= (const T& x, const T& y) -{ - return (!(x == y)); -} - -/// Template of making > from < -template <typename T> -inline bool operator> (const T& x, const T& y) -{ - return (y < x); -} - -/// Template of making <= from < and == -template <typename T> -inline bool operator<= (const T& x, const T& y) -{ - return (!(y < x)); -} - -/// Template of making >= from < and == -template <typename T> -inline bool operator>= (const T& x, const T& y) -{ - return (!(x < y)); -} - -/// Packs \p s multiple times into \p b. Useful for loop unrolling. -template <typename TSmall, typename TBig> -inline void pack_type (TSmall s, TBig& b) -{ - const size_t n = sizeof(TBig) / sizeof(TSmall); - b = s; - // Calls to min are here to avoid warnings for shifts bigger than the type. min will be gone when optimized. - if (n < 2) return; - b = (b << min (BitsInType(TSmall), BitsInType(TBig))) | b; - if (n < 4) return; - b = (b << min (BitsInType(TSmall) * 2, BitsInType(TBig))) | b; - if (n < 8) return; - b = (b << min (BitsInType(TSmall) * 4, BitsInType(TBig))) | b; -} - -/// \brief Divides \p n1 by \p n2 and rounds the result up. -/// This is in contrast to regular division, which rounds down. -template <typename T1, typename T2> -inline T1 DivRU (T1 n1, T2 n2) -{ - T2 adj = n2 - 1; - if (is_negative (n1)) - adj = -adj; - return ((n1 + adj) / n2); -} - -#if __GNUC__ >= 3 -inline bool TestAndSet (int* pm) INLINE; -#endif -/// Sets the contents of \p pm to 1 and returns true if the previous value was 0. -inline bool TestAndSet (int* pm) -{ -#if CPU_HAS_CMPXCHG8 - bool rv; - int oldVal (1); - asm volatile ( // cmpxchg compares to %eax and swaps if equal - "cmpxchgl %3, %1\n\t" - "sete %0" - : "=a" (rv), "=m" (*pm), "=r" (oldVal) - : "2" (oldVal), "a" (0) - : "memory"); - return (rv); -#elif __i386__ || __x86_64__ - int oldVal (1); - asm volatile ("xchgl %0, %1" : "=r"(oldVal), "=m"(*pm) : "0"(oldVal), "m"(*pm) : "memory"); - return (!oldVal); -#elif __sparc32__ // This has not been tested - int rv; - asm volatile ("ldstub %1, %0" : "=r"(rv), "=m"(*pm) : "m"(pm)); - return (!rv); -#else - const int oldVal (*pm); - *pm = 1; - return (!oldVal); -#endif -} - -/// \brief This template is to be used for dereferencing a type-punned pointer without a warning. -/// -/// When casting a local variable to an unrelated type through a pointer (for -/// example, casting a float to a uint32_t without conversion), the resulting -/// memory location can be accessed through either pointer, which violates the -/// strict aliasing rule. While -fno-strict-aliasing option can be given to -/// the compiler, eliminating this warning, inefficient code may result in -/// some instances, because aliasing inhibits some optimizations. By using -/// this template, and by ensuring the memory is accessed in one way only, -/// efficient code can be produced without the warning. For gcc 4.1.0+. -/// -template <typename DEST, typename SRC> -inline DEST noalias (const DEST&, SRC* s) -{ - asm("":"+g"(s)::"memory"); - union UPun { SRC s; DEST d; }; - return (((UPun*)(s))->d); -} - -template <typename DEST, typename SRC> -inline DEST noalias_cast (SRC s) -{ - asm("":"+g"(s)::"memory"); - union { SRC s; DEST d; } u = {s}; - return (u.d); -} - -namespace simd { - /// Call after you are done using SIMD algorithms for 64 bit tuples. - inline void reset_mmx (void) INLINE; - #define ALL_MMX_REGS_CHANGELIST "mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7","st","st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)" -#if CPU_HAS_3DNOW - inline void reset_mmx (void) { asm ("femms":::ALL_MMX_REGS_CHANGELIST); } -#elif CPU_HAS_MMX - inline void reset_mmx (void) { asm ("emms":::ALL_MMX_REGS_CHANGELIST); } -#else - inline void reset_mmx (void) {} -#endif -} // namespace simd -} // namespace ustl - -#endif
deleted file mode 100644 --- a/packages/language/cxx/ustl/current/include/uvector.h +++ /dev/null @@ -1,272 +0,0 @@ -// This file is part of the uSTL library, an STL implementation. -// -// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net> -// This file is free software, distributed under the MIT License. - -#ifndef UVECTOR_H_00BB13AF082BEB7829C031B265518169 -#define UVECTOR_H_00BB13AF082BEB7829C031B265518169 - -#include "memblock.h" -#include "umemory.h" - -namespace ustl { - -/// \class vector uvector.h ustl.h -/// \ingroup Sequences -/// -/// \brief STL vector equivalent. -/// -/// Provides a typed array-like interface to a managed memory block, including -/// element access, iteration, modification, resizing, and serialization. In -/// this design elements frequently undergo bitwise move, so don't put it in -/// here if it doesn't support it. This mostly means having no self-pointers. -/// -template <typename T> -class vector { -public: - typedef T value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef pointer iterator; - typedef const_pointer const_iterator; - typedef memblock::size_type size_type; - typedef memblock::written_size_type written_size_type; - typedef memblock::difference_type difference_type; - typedef ::ustl::reverse_iterator<iterator> reverse_iterator; - typedef ::ustl::reverse_iterator<const_iterator> const_reverse_iterator; -public: - inline vector (void); - inline explicit vector (size_type n); - vector (size_type n, const T& v); - vector (const vector<T>& v); - vector (const_iterator i1, const_iterator i2); - inline ~vector (void) throw(); - inline const vector<T>& operator= (const vector<T>& v); - inline bool operator== (const vector<T>& v) const { return (m_Data == v.m_Data); } - inline operator cmemlink (void) const { return (cmemlink (m_Data)); } - inline operator cmemlink (void) { return (cmemlink (m_Data)); } - inline operator memlink (void) { return (memlink (m_Data)); } - inline void reserve (size_type n, bool bExact = true); - inline void resize (size_type n, bool bExact = true); - inline size_type capacity (void) const { return (m_Data.capacity() / sizeof(T)); } - inline size_type size (void) const { return (m_Data.size() / sizeof(T)); } - inline size_type max_size (void) const { return (m_Data.max_size() / sizeof(T)); } - inline bool empty (void) const { return (m_Data.empty()); } - inline iterator begin (void) { return (iterator (m_Data.begin())); } - inline const_iterator begin (void) const { return (const_iterator (m_Data.begin())); } - inline iterator end (void) { return (iterator (m_Data.end())); } - inline const_iterator end (void) const { return (const_iterator (m_Data.end())); } - inline reverse_iterator rbegin (void) { return (reverse_iterator (end())); } - inline const_reverse_iterator rbegin (void) const { return (const_reverse_iterator (end())); } - inline reverse_iterator rend (void) { return (reverse_iterator (begin())); } - inline const_reverse_iterator rend (void) const { return (const_reverse_iterator (begin())); } - inline iterator iat (size_type i) { assert (i <= size()); return (begin() + i); } - inline const_iterator iat (size_type i) const { assert (i <= size()); return (begin() + i); } - inline reference at (size_type i) { assert (i < size()); return (begin()[i]); } - inline const_reference at (size_type i) const { assert (i < size()); return (begin()[i]); } - inline reference operator[] (size_type i) { return (at (i)); } - inline const_reference operator[] (size_type i) const { return (at (i)); } - inline reference front (void) { return (at(0)); } - inline const_reference front (void) const { return (at(0)); } - inline reference back (void) { assert (!empty()); return (end()[-1]); } - inline const_reference back (void) const { assert (!empty()); return (end()[-1]); } - inline void push_back (const T& v = T()); - inline void pop_back (void) { m_Data.memlink::resize (m_Data.size() - sizeof(T)); } - inline void clear (void) { m_Data.clear(); } - inline void deallocate (void) throw(); - inline void assign (const_iterator i1, const_iterator i2); - inline void assign (size_type n, const T& v); - inline void swap (vector<T>& v) { m_Data.swap (v.m_Data); } - inline iterator insert (iterator ip, const T& v = T()); - inline iterator insert (iterator ip, size_type n, const T& v); - inline iterator insert (iterator ip, const_iterator i1, const_iterator i2); - inline iterator erase (iterator ep, size_type n = 1); - inline iterator erase (iterator ep1, iterator ep2); - inline void manage (pointer p, size_type n) { m_Data.manage (p, n * sizeof(T)); } - inline bool is_linked (void) const { return (m_Data.is_linked()); } - inline void unlink (void) { m_Data.unlink(); } - inline void copy_link (void) { m_Data.copy_link(); } - inline void link (const_pointer p, size_type n) { m_Data.link (p, n * sizeof(T)); } - inline void link (pointer p, size_type n) { m_Data.link (p, n * sizeof(T)); } - inline void link (const vector<T>& v) { m_Data.link (v); } - inline void link (vector<T>& v) { m_Data.link (v); } - inline void link (const_pointer first, const_pointer last) { m_Data.link (first, last); } - inline void link (pointer first, pointer last) { m_Data.link (first, last); } - inline void read (istream& is) { container_read (is, *this); } - inline void write (ostream& os) const { container_write (os, *this); } - inline void text_write (ostringstream& os) const { container_text_write (os, *this); } - inline size_t stream_size (void) const { return (container_stream_size (*this)); } -private: - inline iterator insert_space (iterator ip, size_type n); -private: - memblock m_Data; ///< Raw element data, consecutively stored. -}; - -/// Allocates space for at least \p n elements. -template <typename T> -inline void vector<T>::reserve (size_type n, bool bExact) -{ - const size_type oldCapacity = m_Data.capacity() - m_Data.capacity() % sizeof(T); - m_Data.reserve (n * sizeof(T), bExact); - construct (iterator (m_Data.begin() + oldCapacity), iterator (m_Data.begin() + m_Data.capacity())); -} - -/// Resizes the vector to contain \p n elements. -template <typename T> -inline void vector<T>::resize (size_type n, bool bExact) -{ - const size_type nb = n * sizeof(T); - if (m_Data.capacity() < nb) - reserve (n, bExact); - m_Data.memlink::resize (nb); -} - -/// Calls element destructors and frees storage. -template <typename T> -inline void vector<T>::deallocate (void) throw() -{ - destroy (begin(), iterator (m_Data.begin() + m_Data.capacity())); - m_Data.deallocate(); -} - -/// Initializes empty vector. -template <typename T> -inline vector<T>::vector (void) -: m_Data () -{ -} - -/// Initializes a vector of size \p n. -template <typename T> -inline vector<T>::vector (size_type n) -: m_Data () -{ - resize (n); -} - -/// Copies \p n elements from \p v. -template <typename T> -vector<T>::vector (size_type n, const T& v) -: m_Data () -{ - resize (n); - ::ustl::fill (begin(), end(), v); -} - -/// Copies \p v. -template <typename T> -vector<T>::vector (const vector<T>& v) -: m_Data () -{ - resize (v.size()); - ::ustl::copy (v.begin(), v.end(), begin()); -} - -/// Copies range [\p i1, \p i2] -template <typename T> -vector<T>::vector (const_iterator i1, const_iterator i2) -: m_Data () -{ - resize (distance (i1, i2)); - ::ustl::copy (i1, i2, begin()); -} - -/// Destructor -template <typename T> -inline vector<T>::~vector (void) throw() -{ - destroy (begin(), iterator (m_Data.begin() + m_Data.capacity())); -} - -/// Copies the range [\p i1, \p i2] -template <typename T> -inline void vector<T>::assign (const_iterator i1, const_iterator i2) -{ - assert (i1 <= i2); - resize (distance (i1, i2)); - ::ustl::copy (i1, i2, begin()); -} - -/// Copies \p n elements with value \p v. -template <typename T> -inline void vector<T>::assign (size_type n, const T& v) -{ - resize (n); - ::ustl::fill (begin(), end(), v); -} - -/// Copies contents of \p v. -template <typename T> -inline const vector<T>& vector<T>::operator= (const vector<T>& v) -{ - assign (v.begin(), v.end()); - return (*this); -} - -/// Inserts \p n uninitialized elements at \p ip. -template <typename T> -inline typename vector<T>::iterator vector<T>::insert_space (iterator ip, size_type n) -{ - const uoff_t ipmi = distance (m_Data.begin(), memblock::iterator(ip)); - reserve (size() + n, false); - return (iterator (m_Data.insert (m_Data.iat(ipmi), n * sizeof(T)))); -} - -/// Inserts \p n elements with value \p v at offsets \p ip. -template <typename T> -inline typename vector<T>::iterator vector<T>::insert (iterator ip, size_type n, const T& v) -{ - ip = insert_space (ip, n); - ::ustl::fill (ip, ip + n, v); - return (ip); -} - -/// Inserts value \p v at offset \p ip. -template <typename T> -inline typename vector<T>::iterator vector<T>::insert (iterator ip, const T& v) -{ - *(ip = insert_space (ip, 1)) = v; - return (ip); -} - -/// Inserts range [\p i1, \p i2] at offset \p ip. -template <typename T> -inline typename vector<T>::iterator vector<T>::insert (iterator ip, const_iterator i1, const_iterator i2) -{ - assert (i1 <= i2); - ip = insert_space (ip, distance (i1, i2)); - ::ustl::copy (i1, i2, ip); - return (ip); -} - -/// Removes \p count elements at offset \p ep. -template <typename T> -inline typename vector<T>::iterator vector<T>::erase (iterator ep, size_type n) -{ - return (iterator (m_Data.erase (memblock::iterator(ep), n * sizeof(T)))); -} - -/// Removes elements from \p ep1 to \p ep2. -template <typename T> -inline typename vector<T>::iterator vector<T>::erase (iterator ep1, iterator ep2) -{ - assert (ep1 <= ep2); - return (erase (ep1, distance(ep1, ep2))); -} - -/// Inserts value \p v at the end of the vector. -template <typename T> -inline void vector<T>::push_back (const T& v) -{ - resize (size() + 1, false); - back() = v; -} - -/// Use with vector classes to allocate and link to stack space. \p n is in elements. -#define typed_alloca_link(m,T,n) (m).link ((T*) alloca ((n) * sizeof(T)), (n)) - -} // namespace ustl - -#endif
