first commit

This commit is contained in:
Jose Caban
2025-06-07 11:34:38 -04:00
commit 0eb2d7c07d
4708 changed files with 1500614 additions and 0 deletions

59
extern/ustl/1.5/Config.mk.in vendored Normal file
View File

@@ -0,0 +1,59 @@
################ Build options #######################################
NAME := @PKG_NAME@
MAJOR := @PKG_MAJOR@
MINOR := @PKG_MINOR@
#DEBUG := 1
BUILD_SHARED := 1
#BUILD_STATIC := 1
NOLIBSTDCPP := 1
################ Programs ############################################
CXX := @CXX@
LD := @CXX@
AR := @AR@
RANLIB := @RANLIB@
DOXYGEN := @DOXYGEN@
INSTALL := @INSTALL@
INSTALLDATA := ${INSTALL} -D -p -m 644
INSTALLLIB := ${INSTALLDATA}
################ Destination #########################################
prefix := @prefix@
exec_prefix := @exec_prefix@
BINDIR := @bindir@
INCDIR := @includedir@
LIBDIR := @libdir@
################ Compiler options ####################################
WARNOPTS := -Wall -Wextra -Woverloaded-virtual -Wpointer-arith\
-Wshadow -Wredundant-decls -Wcast-qual @SYSWARNS@
TGTOPTS := @PROCESSOR_OPTS@
INLINEOPTS := @INLINE_OPTS@
CXXFLAGS := ${WARNOPTS} ${TGTOPTS} @CUSTOMINCDIR@ -fPIC
LDFLAGS := @CUSTOMLIBDIR@
LIBS :=
ifdef DEBUG
CXXFLAGS += -O0 -g
LDFLAGS += -rdynamic
else
CXXFLAGS += -Os -g0 -DNDEBUG=1 -fomit-frame-pointer ${INLINEOPTS}
LDFLAGS += -s -Wl,-gc-sections
endif
ifdef NOLIBSTDCPP
LD := @CC@
STAL_LIBS := @libsupc++@ @libgcc_eh@ @libSystemStubs@
LIBS := ${STAL_LIBS}
endif
O := .o/
slib_lnk = lib$1.so
slib_son = lib$1.so.${MAJOR}.${MINOR}
slib_tgt = lib$1.so.${MAJOR}.${MINOR}
slib_flags = @SHBLDFL@

22
extern/ustl/1.5/LICENSE vendored Normal file
View File

@@ -0,0 +1,22 @@
The MIT License
Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

154
extern/ustl/1.5/Makefile vendored Normal file
View File

@@ -0,0 +1,154 @@
-include Config.mk
################ Source files ##########################################
SRCS := $(wildcard *.cc)
INCS := $(wildcard *.h)
OBJS := $(addprefix $O,$(SRCS:.cc=.o))
################ Compilation ###########################################
.PHONY: all clean html check dist distclean maintainer-clean
all: Config.mk config.h ${NAME}/config.h
ALLTGTS := Config.mk config.h ${NAME}/config.h
ifdef BUILD_SHARED
SLIBL := $O$(call slib_lnk,${NAME})
SLIBS := $O$(call slib_son,${NAME})
SLIBT := $O$(call slib_tgt,${NAME})
SLINKS := ${SLIBL}
ifneq (${SLIBS},${SLIBT})
SLINKS += ${SLIBS}
endif
ALLTGTS += ${SLIBT} ${SLINKS}
all: ${SLIBT} ${SLINKS}
${SLIBT}: ${OBJS}
@echo "Linking $(notdir $@) ..."
@${LD} -fPIC ${LDFLAGS} $(call slib_flags,$(subst $O,,${SLIBS})) -o $@ $^ ${LIBS}
${SLINKS}: ${SLIBT}
@(cd $(dir $@); rm -f $(notdir $@); ln -s $(notdir $<) $(notdir $@))
endif
ifdef BUILD_STATIC
LIBA := $Olib${NAME}.a
ALLTGTS += ${LIBA}
all: ${LIBA}
${LIBA}: ${OBJS}
@echo "Linking $@ ..."
@rm -f $@
@${AR} qc $@ ${OBJS}
@${RANLIB} $@
endif
$O%.o: %.cc
@echo " Compiling $< ..."
@[ -d $(dir $@) ] || mkdir -p $(dir $@)
@${CXX} ${CXXFLAGS} -MMD -MT "$(<:.cc=.s) $@" -o $@ -c $<
%.s: %.cc
@echo " Compiling $< to assembly ..."
@${CXX} ${CXXFLAGS} -S -o $@ -c $<
include bvt/Module.mk
################ Installation ##########################################
.PHONY: install uninstall install-incs uninstall-incs
####### Install headers
ifdef INCDIR # These ifdefs allow cold bootstrap to work correctly
LIDIR := ${INCDIR}/${NAME}
INCSI := $(addprefix ${LIDIR}/,$(filter-out ${NAME}.h,${INCS}))
RINCI := ${LIDIR}.h
install: install-incs
install-incs: ${INCSI} ${RINCI}
${INCSI}: ${LIDIR}/%.h: %.h
@echo "Installing $@ ..."
@${INSTALLDATA} $< $@
${RINCI}: ${NAME}.h
@echo "Installing $@ ..."
@${INSTALLDATA} $< $@
uninstall: uninstall-incs
uninstall-incs:
@echo "Removing ${LIDIR}/ and ${LIDIR}.h ..."
@(cd ${INCDIR}; rm -f ${INCSI} ${NAME}.h; [ ! -d ${NAME} ] || rm -rf ${NAME})
endif
####### Install libraries (shared and/or static)
ifdef LIBDIR
ifdef BUILD_SHARED
LIBTI := ${LIBDIR}/$(notdir ${SLIBT})
LIBLI := $(addprefix ${LIBDIR}/,$(notdir ${SLINKS}))
install: ${LIBTI} ${LIBLI}
${LIBTI}: ${SLIBT}
@echo "Installing $@ ..."
@${INSTALLLIB} $< $@
${LIBLI}: ${LIBTI}
@(cd ${LIBDIR}; rm -f $@; ln -s $(notdir $<) $(notdir $@))
endif
ifdef BUILD_STATIC
LIBAI := ${LIBDIR}/$(notdir ${LIBA})
install: ${LIBAI}
${LIBAI}: ${LIBA}
@echo "Installing $@ ..."
@${INSTALLLIB} $< $@
endif
uninstall:
@echo "Removing library from ${LIBDIR} ..."
@rm -f ${LIBTI} ${LIBLI} ${LIBSI} ${LIBAI}
endif
################ Maintenance ###########################################
clean:
@[ ! -d ./$O ] || rm -rf ./$O
html: ${SRCS} ${INCS} ${NAME}doc.in
@${DOXYGEN} ${NAME}doc.in
ifdef MAJOR
DISTVER := ${MAJOR}.${MINOR}
DISTNAM := ${NAME}-${DISTVER}
DISTLSM := ${DISTNAM}.lsm
DISTTAR := ${DISTNAM}.tar.bz2
dist:
@echo "Generating ${DISTTAR} and ${DISTLSM} ..."
@mkdir .${DISTNAM}
@rm -f ${DISTTAR}
@cp -r * .${DISTNAM} && mv .${DISTNAM} ${DISTNAM}
@+${MAKE} -sC ${DISTNAM} maintainer-clean
@tar jcf ${DISTTAR} ${DISTNAM} && rm -rf ${DISTNAM}
@echo "s/@version@/${DISTVER}/" > ${DISTLSM}.sed
@echo "s/@date@/`date +%F`/" >> ${DISTLSM}.sed
@echo -n "s/@disttar@/`du -h --apparent-size ${DISTTAR}`/" >> ${DISTLSM}.sed;
@sed -f ${DISTLSM}.sed docs/${NAME}.lsm > ${DISTLSM} && rm -f ${DISTLSM}.sed
endif
distclean: clean
@rm -f Config.mk config.h config.status ${NAME}
maintainer-clean: distclean
@if [ -d docs/html ]; then rm -f docs/html/*; rmdir docs/html; fi
INPLACE_INCS := $(addprefix ${NAME}/,$(filter-out config.h,${INCS}))
${INPLACE_INCS}: ${NAME}/%: ${NAME}/config.h
${NAME}/config.h: config.h
@echo " Linking inplace header location ..."
@rm -f ${NAME}; ln -s . ${NAME}
${OBJS}: Makefile Config.mk config.h
Config.mk: Config.mk.in
config.h: config.h.in
Config.mk config.h: configure
@if [ -x config.status ]; then echo "Reconfiguring ..."; ./config.status; \
else echo "Running configure ..."; ./configure; fi
-include ${OBJS:.o=.d}

141
extern/ustl/1.5/bktrace.cc vendored Normal file
View File

@@ -0,0 +1,141 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2006 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "bktrace.h"
#include "sostream.h"
#include "mistream.h"
#if linux && __GNUC__
#include <execinfo.h>
#else
static inline int backtrace (void**, int) { return (0); }
static inline char** backtrace_symbols (void* const*, int) { return (NULL); }
#endif
namespace ustl {
/// Default constructor. The backtrace is obtained here.
CBacktrace::CBacktrace (void) throw()
: m_Symbols (NULL),
m_nFrames (0),
m_SymbolsSize (0)
{
m_nFrames = backtrace (VectorBlock (m_Addresses));
GetSymbols();
}
/// Copy constructor.
CBacktrace::CBacktrace (const CBacktrace& v) throw()
: m_Symbols (NULL),
m_nFrames (0),
m_SymbolsSize (0)
{
operator= (v);
}
/// Copy operator.
const CBacktrace& CBacktrace::operator= (const CBacktrace& v) throw()
{
memcpy (m_Addresses, v.m_Addresses, sizeof(m_Addresses));
m_Symbols = strdup (v.m_Symbols);
m_nFrames = v.m_nFrames;
m_SymbolsSize = v.m_SymbolsSize;
return (*this);
}
/// Converts a string returned by backtrace_symbols into readable form.
static size_t ExtractAbiName (const char* isym, char* nmbuf) throw()
{
// Prepare the demangled name, if possible
size_t nmSize = 0;
if (isym) {
// Copy out the name; the strings are: "file(function+0x42) [0xAddress]"
const char* mnStart = strchr (isym, '(');
if (++mnStart == (const char*)(1))
mnStart = isym;
const char* mnEnd = strchr (isym, '+');
const char* isymEnd = isym + strlen (isym);
if (!mnEnd)
mnEnd = isymEnd;
nmSize = min (size_t (distance (mnStart, mnEnd)), 255U);
memcpy (nmbuf, mnStart, nmSize);
}
nmbuf[nmSize] = 0;
// Demangle
demangle_type_name (nmbuf, 255U, &nmSize);
return (nmSize);
}
/// Tries to get symbol information for the addresses.
void CBacktrace::GetSymbols (void) throw()
{
char** symbols = backtrace_symbols (m_Addresses, m_nFrames);
if (!symbols)
return;
char nmbuf [256];
size_t symSize = 1;
for (uoff_t i = 0; i < m_nFrames; ++ i)
symSize += ExtractAbiName (symbols[i], nmbuf) + 1;
if ((m_Symbols = (char*) calloc (symSize, 1))) {
for (uoff_t i = 0; m_SymbolsSize < symSize - 1; ++ i) {
size_t sz = ExtractAbiName (symbols[i], nmbuf);
memcpy (m_Symbols + m_SymbolsSize, nmbuf, sz);
m_SymbolsSize += sz + 1;
m_Symbols [m_SymbolsSize - 1] = '\n';
}
}
free (symbols);
}
#if SIZE_OF_LONG == 8
#define ADDRESS_FMT "%16p "
#else
#define ADDRESS_FMT "%8p "
#endif
/// Prints the backtrace to \p os.
void CBacktrace::text_write (ostringstream& os) const
{
const char *ss = m_Symbols, *se;
for (uoff_t i = 0; i < m_nFrames; ++ i) {
os.format (ADDRESS_FMT, m_Addresses[i]);
se = strchr (ss, '\n') + 1;
os.write (ss, distance (ss, se));
ss = se;
}
}
/// Reads the object from stream \p is.
void CBacktrace::read (istream& is)
{
assert (is.aligned (alignof (m_Addresses[0])) && "Backtrace object contains pointers and must be void* aligned");
is >> m_nFrames >> m_SymbolsSize;
nfree (m_Symbols);
m_Symbols = (char*) malloc (m_SymbolsSize + 1);
is.read (m_Symbols, m_SymbolsSize);
m_Symbols [m_SymbolsSize] = 0;
is.align();
is.read (m_Addresses, m_nFrames * sizeof(void*));
}
/// Writes the object to stream \p os.
void CBacktrace::write (ostream& os) const
{
assert (os.aligned (alignof (m_Addresses[0])) && "Backtrace object contains pointers and must be void* aligned");
os << m_nFrames << m_SymbolsSize;
os.write (m_Symbols, m_SymbolsSize);
os.align();
os.write (m_Addresses, m_nFrames * sizeof(void*));
}
/// Returns the size of the written object.
size_t CBacktrace::stream_size (void) const
{
return (Align (stream_size_of (m_nFrames) +
stream_size_of (m_SymbolsSize) +
m_nFrames * sizeof(void*) +
m_SymbolsSize));
}
} // namespace ustl

52
extern/ustl/1.5/bktrace.h vendored Normal file
View File

@@ -0,0 +1,52 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2006 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

52
extern/ustl/1.5/bvt/Module.mk vendored Normal file
View File

@@ -0,0 +1,52 @@
################ Source files ##########################################
bvt/SRCS := $(wildcard bvt/bvt*.cc)
bvt/BVTS := $(bvt/SRCS:.cc=)
bvt/OBJS := $(addprefix $O,$(bvt/SRCS:.cc=.o))
bvt/LIBS := -L$(abspath $O.) -l${NAME}
ifdef BUILD_SHARED
bvt/LIBS := -Wl,--rpath=$(abspath $O.) ${bvt/LIBS}
endif
ifdef NOLIBSTDCPP
bvt/LIBS += ${STAL_LIBS} -lm
endif
CXXFLAGS += -I.
################ Compilation ###########################################
.PHONY: bvt/all bvt/run bvt/clean bvt/check
bvt/all: ${bvt/BVTS}
# The correct output of a bvt is stored in bvtXX.std
# When the bvt runs, its output is compared to .std
#
bvt/run: ${bvt/BVTS}
@echo "Running build verification tests:"
@for i in ${bvt/BVTS}; do \
echo "Running $$i"; \
./$$i < $$i.cc &> $$i.out; \
diff $$i.std $$i.out && rm -f $$i.out; \
done
${bvt/BVTS}: bvt/%: $Obvt/%.o $Obvt/stdtest.o ${ALLTGTS}
@echo "Linking $@ ..."
@${LD} ${LDFLAGS} -o $@ $< $Obvt/stdtest.o ${bvt/LIBS}
bvt/bench: $Obvt/bench.o $Obvt/stdtest.o ${ALLTGTS}
@echo "Linking $@ ..."
@${LD} ${LDFLAGS} -o $@ $< $Obvt/stdtest.o ${bvt/LIBS}
################ Maintenance ###########################################
clean: bvt/clean
bvt/clean:
@rm -f ${bvt/BVTS} ${bvt/OBJS} $(bvt/OBJS:.o=.d) bvt/bench $Obvt/bench.o $Obvt/stdtest.o $Obvt/bench.d $Obvt/stdtest.d
@rmdir $O/bvt &> /dev/null || true
check: bvt/run
bvt/check: check
${bvt/OBJS} $Obvt/stdtest.o $Obvt/bench.o: Makefile bvt/Module.mk Config.mk ${NAME}/config.h
-include ${bvt/OBJS:.o=.d} $Obvt/stdtest.d

311
extern/ustl/1.5/bvt/bench.cc vendored Normal file
View File

@@ -0,0 +1,311 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include <ustl.h>
#include <time.h>
using namespace ustl;
//----------------------------------------------------------------------
// Copy functions
//----------------------------------------------------------------------
#if __i386__ || __x86_64__
extern "C" void movsb_copy (const char* src, size_t nBytes, char* dest)
{
asm volatile ("rep\tmovsb":"+S"(src),"+D"(dest):"c"(nBytes):"memory");
}
extern "C" void movsd_copy (const char* src, size_t nBytes, char* dest)
{
asm volatile ("rep\tmovsl":"+S"(src),"+D"(dest):"c"(nBytes/4):"memory");
}
#if __x86_64__
extern "C" void movsq_copy (const char* src, size_t nBytes, char* dest)
{
asm volatile ("rep\tmovsq":"+S"(src),"+D"(dest):"c"(nBytes/8):"memory");
}
#endif
extern "C" void risc_copy (const char* src, size_t nBytes, char* dest)
{
unsigned long* ldest ((unsigned long*) dest);
const unsigned long* lsrc ((const unsigned long*) src);
nBytes /= sizeof(*lsrc);
do {
*ldest++ = *lsrc++;
} while (--nBytes);
}
extern "C" void unroll_copy (const char* src, size_t nBytes, char* dest)
{
unsigned long* ldest ((unsigned long*) dest);
const unsigned long* lsrc ((const unsigned long*) src);
nBytes /= 4 * sizeof(unsigned long);
do {
ldest[0] = lsrc[0];
ldest[1] = lsrc[1];
ldest[2] = lsrc[2];
ldest[3] = lsrc[3];
ldest += 4;
lsrc += 4;
} while (--nBytes);
}
#if CPU_HAS_MMX
extern "C" void mmx_copy (const char* src, size_t nBytes, char* dest)
{
nBytes /= 32;
do {
prefetch (src + 512, 0, 0);
asm (
"movq\t%4, %%mm0\n\t"
"movq\t%5, %%mm1\n\t"
"movq\t%6, %%mm2\n\t"
"movq\t%7, %%mm3\n\t"
"movq\t%%mm0, %0\n\t"
"movq\t%%mm1, %1\n\t"
"movq\t%%mm2, %2\n\t"
"movq\t%%mm3, %3"
: "=m"(dest[0]), "=m"(dest[8]), "=m"(dest[16]), "=m"(dest[24])
: "m"(src[0]), "m"(src[8]), "m"(src[16]), "m"(src[24])
: "mm0", "mm1", "mm2", "mm3", "st", "st(1)", "st(2)", "st(3)");
src += 32;
dest += 32;
} while (--nBytes);
simd::reset_mmx();
}
#endif // CPU_HAS_MMX
#if CPU_HAS_SSE
extern "C" void sse_copy (const char* src, size_t nBytes, char* dest)
{
nBytes /= 32;
do {
prefetch (src + 512, 0, 0);
asm (
"movaps\t%2, %%xmm0\n\t"
"movaps\t%3, %%xmm1\n\t"
"movntps\t%%xmm0, %0\n\t"
"movntps\t%%xmm1, %1"
: "=m"(dest[0]), "=m"(dest[16])
: "m"(src[0]), "m"(src[16])
: "xmm0", "xmm1");
src += 32;
dest += 32;
} while (--nBytes);
}
#endif // CPU_HAS_SSE
#endif // __i386__
extern "C" void memcpy_copy (const char* src, size_t nBytes, char* dest)
{
memcpy (dest, src, nBytes);
}
template <typename CopyFunction>
void TestCopyFunction (const char* name, CopyFunction pfn)
{
const uoff_t misalignment = 0;
const uoff_t headBytes = 0;
const uoff_t tailBytes = 0;
const size_t nIter = 128;
const size_t nBytes = 1024 * 1024 + misalignment;
string buf1 (nBytes), buf2 (nBytes);
iota (buf1.begin(), buf1.end(), '\x1');
fill (buf2, 0);
const clock_t first = clock();
for (uoff_t i = 0; i < nIter; ++ i)
(*pfn)(buf1.cdata() + headBytes, nBytes - headBytes - tailBytes, buf2.data() + headBytes + misalignment);
clock_t last = clock();
last += (last == first);
const size_t mbps = nIter * CLOCKS_PER_SEC / (last - first);
cout.format ("%s transfer rate is %4zu Mbps, data is ", name, mbps);
size_t nBad = 0;
for (uoff_t i = headBytes; i < buf1.size() - tailBytes; ++ i)
nBad += (buf1[i] != buf2[i + misalignment]);
if (!nBad)
cout << "GOOD\n";
else {
cout << "BAD\n";
for (uoff_t i = headBytes; i < buf1.size() - tailBytes; ++ i)
if (buf1[i] != buf2[i + misalignment])
cout.format ("\t\t%zu\tbuf1: %#x, buf2: %#x\n", i, (int) buf1[i], (int) buf2[i + misalignment]);
}
cout.flush();
}
//----------------------------------------------------------------------
// Fill functions
//----------------------------------------------------------------------
extern "C" void memset_fill (char* dest, size_t nBytes, char v)
{
memset (dest, v, nBytes);
}
#if __i386__ || __x86_64__
extern "C" void stosb_fill (char* dest, size_t nBytes, char v)
{
asm volatile (
"rep\tstosb\n\t"
: "=&D"(dest)
: "0"(dest), "a"(v), "c"(nBytes)
: "memory");
}
extern "C" void stosd_fill (char* dest, size_t nBytes, char v)
{
uint32_t lv;
pack_type (v, lv);
asm volatile (
"rep\tstosl\n\t"
: "=&D"(dest)
: "0"(dest), "a"(lv), "c"(nBytes / sizeof(lv))
: "memory");
}
extern "C" void risc_fill (char* dest, size_t nBytes, char v)
{
unsigned long lv;
pack_type (v, lv);
unsigned long* ldest ((unsigned long*) dest);
nBytes /= sizeof(lv);
do {
*ldest++ = lv;
} while (--nBytes);
}
extern "C" void unroll_fill (char* dest, size_t nBytes, char v)
{
unsigned long lv;
pack_type (v, lv);
unsigned long* ldest ((unsigned long*) dest);
nBytes /= 4 * sizeof(lv);
do {
ldest[0] = lv;
ldest[1] = lv;
ldest[2] = lv;
ldest[3] = lv;
ldest += 4;
} while (--nBytes);
}
#if CPU_HAS_MMX
extern "C" void mmx_fill (char* dest, size_t nBytes, char v)
{
asm volatile (
"movd %0, %%mm0 \n\t"
"punpcklbw %%mm0, %%mm0 \n\t"
"punpcklwd %%mm0, %%mm0 \n\t"
"punpckldq %%mm0, %%mm0"
::"r"(uint32_t(v))
: "mm0", "st");
const size_t nBlocks (nBytes / 32);
for (uoff_t i = 0; i < nBlocks; ++ i) {
prefetch (dest + 512, 1, 0);
asm volatile (
"movq %%mm0, %0 \n\t"
"movq %%mm0, %1 \n\t"
"movq %%mm0, %2 \n\t"
"movq %%mm0, %3"
: "=m"(dest[0]), "=m"(dest[8]), "=m"(dest[16]), "=m"(dest[24]));
dest += 32;
}
simd::reset_mmx();
}
#endif // CPU_HAS_MMX
#if CPU_HAS_SSE
extern "C" void sse_fill (char* dest, size_t nBytes, char v)
{
prefetch (dest + 512, 1, 0);
uint32_t v4 = uint32_t(v) * 0x01010101;
asm volatile (
"movd\t%0, %%xmm0\n\t"
"unpcklps\t%%xmm0, %%xmm0\n\t"
"movlhps\t%%xmm0, %%xmm0"
::"r"(v4) : "xmm0");
long i = nBytes / 32;
do {
asm volatile (
"movntps\t%%xmm0, (%0)\n\t"
"movntps\t%%xmm0, 16(%0)"
::"r"(dest):"memory");
dest += 32;
} while (--i);
asm("sfence");
}
#endif // CPU_HAS_MMX
#endif // __i386__
template <typename FillFunction>
void TestFillFunction (const char* name, FillFunction pfn)
{
const size_t nIter = 256;
const size_t nBytes = 1024 * 1024;
string buf1 (nBytes), buf2 (nBytes);
iota (buf1.begin(), buf1.end(), '\x1');
fill (buf2, 42);
clock_t first = clock();
for (uoff_t i = 0; i < nIter; ++ i)
(*pfn)(buf1.data(), nBytes, char(42));
clock_t last = clock();
last += (last == first);
const size_t mbps = nIter * CLOCKS_PER_SEC / (last - first);
cout << name << " transfer rate is " << mbps << " Mbps, data is ";
if (buf1 == buf2)
cout << "GOOD" << endl;
else
cout << "BAD" << endl;
cout.flush();
}
//----------------------------------------------------------------------
int main (void)
{
cout << "Testing fill" << endl;
cout << "---------------------------------------------------------" << endl;
#if __i386__ || __x86_64__
#if CPU_HAS_SSE
TestFillFunction ("sse_fill\t", &sse_fill);
#endif
#if CPU_HAS_MMX && HAVE_INT64_T
TestFillFunction ("mmx_fill\t", &mmx_fill);
#endif
TestFillFunction ("stosb_fill\t", &stosb_fill);
TestFillFunction ("stosd_fill\t", &stosd_fill);
TestFillFunction ("unroll_fill\t", &unroll_fill);
TestFillFunction ("risc_fill\t", &risc_fill);
#endif
TestFillFunction ("memset_fill\t", &memset_fill);
TestFillFunction ("fill_n\t\t", &fill_n<char*, char>);
cout << endl;
cout << "Testing copy" << endl;
cout << "---------------------------------------------------------" << endl;
#if __i386__ || __x86_64__
#if CPU_HAS_SSE
TestCopyFunction ("sse_copy\t", &sse_copy);
#endif
#if CPU_HAS_MMX
TestCopyFunction ("mmx_copy\t", &mmx_copy);
#endif
TestCopyFunction ("movsb_copy\t", &movsb_copy);
TestCopyFunction ("movsd_copy\t", &movsd_copy);
#if __x86_64__
TestCopyFunction ("movsq_copy\t", &movsq_copy);
#endif
TestCopyFunction ("risc_copy\t", &risc_copy);
TestCopyFunction ("unroll_copy\t", &unroll_copy);
#endif
TestCopyFunction ("memcpy_copy\t", &memcpy_copy);
TestCopyFunction ("copy_n\t\t", &copy_n<const char*, char*>);
return (EXIT_SUCCESS);
}

46
extern/ustl/1.5/bvt/bvt00.cc vendored Normal file
View File

@@ -0,0 +1,46 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
void WriteCML (const cmemlink& l)
{
cout.format ("cmemlink{%zu}: ", l.size());
const void* pv = l.cdata();
const char* pc = reinterpret_cast<const char*>(pv);
size_t nc = l.size();
if (pc[nc - 1] == 0)
-- nc;
cout.write (l.begin(), nc);
cout << endl;
}
void TestCML (void)
{
const char hello[] = "Hello world!";
const char* phello = hello; // const storage is sometimes copied on pointing
cmemlink a, b;
a.link (phello, VectorSize(hello));
if (a.begin() != phello)
cout.format ("a.begin() failed: %p != %p\n", a.begin(), phello);
a.link (VectorRange (hello));
if (*(const char*)(a.begin() + 5) != hello[5])
cout.format ("begin()[5] failed: %c != %c\n", *(const char*)(a.begin() + 5), VectorElement(hello,5));
if (a.size() != VectorSize(hello))
cout << "link to VectorRange doesn't work\n";
if (0 != memcmp (a.begin(), hello, VectorSize(hello)))
cout << "memcmp failed on cmemlink\n";
b.static_link (hello);
WriteCML (a);
WriteCML (b);
if (!(a == b))
cout << "operator== failed on cmemlink\n";
b.resize (VectorSize(hello) - 5);
a = b;
WriteCML (a);
}
StdBvtMain (TestCML)

3
extern/ustl/1.5/bvt/bvt00.std vendored Normal file
View File

@@ -0,0 +1,3 @@
cmemlink{13}: Hello world!
cmemlink{13}: Hello world!
cmemlink{8}: Hello wo

60
extern/ustl/1.5/bvt/bvt01.cc vendored Normal file
View File

@@ -0,0 +1,60 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
void WriteCML (const cmemlink& l)
{
cout.format ("memlink{%zu}: ", l.size());
const char* pc = reinterpret_cast<const char*>(l.cdata());
size_t nc = l.size();
if (pc[nc - 1] == 0)
-- nc;
cout.write (l.cdata(), nc);
cout << endl;
}
void TestML (void)
{
char str[] = "abcdefghijklmnopqrstuvwzyz";
memlink::const_pointer cstr = str;
memlink a, b;
a.static_link (str);
if (a.begin() != str)
cout << "begin() failed on memlink\n";
a.link (VectorRange(str));
if (a.begin() + 5 != &str[5])
cout << "begin() + 5 failed on memlink\n";
if (0 != memcmp (a.begin(), str, VectorSize(str)))
cout << "memcmp failed on memlink\n";
WriteCML (a);
b.link (cstr, VectorSize(str));
if (b.data() != cstr)
cout << "begin() of const failed on cmemlink\n";
if (b.cmemlink::begin() != cstr)
cout << "begin() failed on cmemlink\n";
WriteCML (b);
if (!(a == b))
cout << "operator== failed on cmemlink\n";
b.resize (VectorSize(str) - 2);
a = b;
if (a.data() != b.data())
cout << "begin() after assignment failed on cmemlink\n";
a.relink (str, VectorSize(str) - 1);
WriteCML (a);
a.insert (a.begin() + 5, 9);
a.fill (a.begin() + 5, "-", 1, 9);
WriteCML (a);
a.erase (a.begin() + 9, 7);
a.fill (a.end() - 7, "=", 1, 7);
WriteCML (a);
a.fill (a.begin() + 5, "TEST", 4, 3);
WriteCML (a);
copy_n (cstr, VectorSize(str) - 1, a.begin());
WriteCML (a);
}
StdBvtMain (TestML)

7
extern/ustl/1.5/bvt/bvt01.std vendored Normal file
View File

@@ -0,0 +1,7 @@
memlink{27}: abcdefghijklmnopqrstuvwzyz
memlink{27}: abcdefghijklmnopqrstuvwzyz
memlink{26}: abcdefghijklmnopqrstuvwzyz
memlink{26}: abcde---------fghijklmnopq
memlink{26}: abcde----hijklmnopq=======
memlink{26}: abcdeTESTTESTTESTpq=======
memlink{26}: abcdeTESTTESTTESTpq=======

72
extern/ustl/1.5/bvt/bvt02.cc vendored Normal file
View File

@@ -0,0 +1,72 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
void WriteCML (const memblock& l)
{
cout.format ("memblock{%zu}: ", l.size());
const char* pc = reinterpret_cast<const char*>(l.cdata());
size_t nc = l.size();
while (nc && pc[nc - 1] == 0)
-- nc;
cout.write (l.cdata(), nc);
cout << endl;
}
void TestMB (void)
{
char strTest[] = "abcdefghijklmnopqrstuvwxyz";
const size_t strTestLen = strlen(strTest);
const char* cstrTest = strTest;
memblock a, b;
a.link (strTest, strTestLen);
if (a.begin() != strTest)
cout << "begin() failed on memblock\n";
if (a.begin() + 5 != &strTest[5])
cout << "begin() + 5 failed on memblock\n";
if (0 != memcmp (a.begin(), strTest, strTestLen))
cout << "memcmp failed on memblock\n";
WriteCML (a);
b.link (cstrTest, strTestLen);
if (b.data() != cstrTest)
cout << "begin() of const failed on memblock\n";
if (b.cmemlink::begin() != cstrTest)
cout << "cmemlink::begin() failed on memblock\n";
WriteCML (b);
if (!(a == b))
cout << "operator== failed on memblock\n";
b.copy_link();
if (b.data() == NULL || b.cdata() == cstrTest)
cout << "copy_link failed on memblock\n";
if (!(a == b))
cout << "copy_link didn't copy\n";
b.resize (strTestLen - 2);
a = b;
if (a.begin() == b.begin())
cout << "Assignment does not copy a link\n";
a.deallocate();
a.assign (strTest, strTestLen);
WriteCML (a);
a.insert (a.begin() + 5, 9);
a.fill (a.begin() + 5, "-", 1, 9);
WriteCML (a);
a.erase (a.begin() + 2, 7);
a.fill (a.end() - 7, "=", 1, 7);
WriteCML (a);
a.fill (a.begin() + 5, "TEST", 4, 3);
WriteCML (a);
a.resize (26 + 24);
a.fill (a.begin() + 26, "-+=", 3, 24 / 3);
WriteCML (a);
a.resize (0);
WriteCML (a);
a.resize (strTestLen + strTestLen / 2);
WriteCML (a);
}
StdBvtMain (TestMB)

9
extern/ustl/1.5/bvt/bvt02.std vendored Normal file
View File

@@ -0,0 +1,9 @@
memblock{26}: abcdefghijklmnopqrstuvwxyz
memblock{26}: abcdefghijklmnopqrstuvwxyz
memblock{26}: abcdefghijklmnopqrstuvwxyz
memblock{35}: abcde---------fghijklmnopqrstuvwxyz
memblock{28}: ab-----fghijklmnopqrs=======
memblock{28}: ab---TESTTESTTESTpqrs=======
memblock{50}: ab---TESTTESTTESTpqrs=====-+=-+=-+=-+=-+=-+=-+=-+=
memblock{0}:
memblock{39}: ab---TESTTESTTESTpqrs=====-+=-+=-+=-+=-

117
extern/ustl/1.5/bvt/bvt03.cc vendored Normal file
View File

@@ -0,0 +1,117 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
#include <unistd.h>
void TestStreams (void)
{
const uint8_t magic_Char = 0x12;
const uint16_t magic_Short = 0x1234;
const uint32_t magic_Int = 0x12345678;
const float magic_Float = 0.12345678;
const double magic_Double = 0.123456789123456789;
const bool magic_Bool = true;
char c = magic_Char;
unsigned char uc = magic_Char;
int i = magic_Int;
short si = magic_Short;
long li = magic_Int;
unsigned int ui = magic_Int;
unsigned short usi = magic_Short;
unsigned long uli = magic_Int;
float f = magic_Float;
double d = magic_Double;
bool bv = magic_Bool;
size_t totalSize = stream_size_of(c);
totalSize += stream_size_of(uc);
totalSize = Align (totalSize, alignof(bv));
totalSize += stream_size_of(bv);
totalSize = Align (totalSize, alignof(i));
totalSize += stream_size_of(i);
totalSize += stream_size_of(ui);
totalSize = Align (totalSize);
totalSize += stream_size_of(li);
totalSize += stream_size_of(uli);
totalSize = Align (totalSize, alignof(f));
totalSize += stream_size_of(f);
totalSize = Align (totalSize, alignof(d));
totalSize += stream_size_of(d);
totalSize += stream_size_of(si);
totalSize += stream_size_of(usi);
memblock b;
b.resize (totalSize);
b.fill (b.begin(), "\xCD", 1, b.size());
ostream os (b);
os << c;
os << uc;
os << ios::talign<bool>() << bv;
os << ios::talign<int>() << i;
os << ui;
os << ios::align() << li;
os << uli;
os << ios::talign<float>() << f;
os << ios::talign<double>() << d;
os << si;
os << usi;
if (b.size() == os.pos())
cout << "Correct number of bytes written\n";
else
cout.format ("Incorrect (%zu of %zu) number of bytes written\n", os.pos(), b.size());
cout.flush();
c = 0;
uc = 0;
bv = false;
i = ui = li = uli = 0;
f = 0; d = 0;
si = usi = 0;
istream is (b);
is >> c;
is >> uc;
is >> ios::talign<bool>() >> bv;
is >> ios::talign<int>() >> i;
is >> ui;
is >> ios::align() >> li;
is >> uli;
is >> ios::talign<float>() >> f;
is >> ios::talign<double>() >> d;
is >> si;
is >> usi;
if (is.pos() != b.size())
cout << "Positional error\n";
cout.format ("Values:\n"
"char: 0x%02X\n"
"u_char: 0x%02X\n"
"bool: %d\n"
"int: 0x%08X\n"
"u_int: 0x%08X\n"
"long: 0x%08lX\n"
"u_long: 0x%08lX\n"
"float: %.8f\n"
"double: %.16f\n"
"short: 0x%04X\n"
"u_short: 0x%04X\n",
static_cast<int>(c), static_cast<int>(uc), static_cast<int>(bv),
i, ui, li, uli, f, d, static_cast<int>(si), static_cast<int>(usi));
if (isatty (STDIN_FILENO)) {
cout << "\nBinary dump:\n";
foreach (memblock::const_iterator, pc, b) {
if (pc > b.begin() && !(distance(b.begin(), pc) % 8))
cout << endl;
cout.format ("%02X ", uint8_t(*pc));
}
cout << endl;
}
}
StdBvtMain (TestStreams)

13
extern/ustl/1.5/bvt/bvt03.std vendored Normal file
View File

@@ -0,0 +1,13 @@
Correct number of bytes written
Values:
char: 0x12
u_char: 0x12
bool: 1
int: 0x12345678
u_int: 0x12345678
long: 0x12345678
u_long: 0x12345678
float: 0.12345678
double: 0.1234567891234568
short: 0x1234
u_short: 0x1234

68
extern/ustl/1.5/bvt/bvt04.cc vendored Normal file
View File

@@ -0,0 +1,68 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
class A {
public:
A (void)
{ cout << "A::A\n"; }
A (const A&)
{ cout << "Copy A::A\n"; }
const A& operator= (const A&)
{ cout << "A::operator=\n"; return (*this); }
~A (void)
{ cout << "A::~A\n"; }
};
void TestVector (void)
{
static const int c_TestNumbers[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13, 14, 15, 16, 17, 18 };
vector<int> v;
v.push_back (1);
cout << v << endl;
v.reserve (20);
cout.format ("Reserved to capacity() == %zu (%zu used, ", v.capacity(), v.size());
if (v.max_size() == SIZE_MAX / sizeof(int))
cout << "SIZE_MAX/elsize";
else
cout << v.max_size();
cout << " max)\n";
v.insert (v.begin() + 1, 1 + VectorRange(c_TestNumbers));
cout << v << endl;
cout.format ("front() = %d, back() = %d\n", v.front(), v.back());
v.erase (v.begin());
v.pop_back();
cout << v << endl;
v.insert (v.begin() + 10, 3, 666);
v.at(5) = 777;
cout << v << endl;
v.resize (v.size() - 5);
if (v.empty())
cout << "v is now empty\n";
cout << v << endl;
cout.format ("v[5] == %d\n", v[5]);
v.clear();
if (v.empty())
cout << "v is now empty\n";
vector<int> v2 (20, 66);
cout << v2 << endl;
v2.assign (20, 33);
cout << v2 << endl;
v.assign (VectorRange (c_TestNumbers));
cout << v << endl;
if (v == v2)
cout << "v == v2\n";
v2 = v;
if (v == v2)
cout << "v == v2\n";
vector<A> ctv;
A a;
ctv.assign (3, a);
ctv.pop_back();
cout << "Class insertion testing successful\n";
}
StdBvtMain (TestVector)

25
extern/ustl/1.5/bvt/bvt04.std vendored Normal file
View File

@@ -0,0 +1,25 @@
(1)
Reserved to capacity() == 20 (1 used, SIZE_MAX/elsize max)
(1,2,3,4,5,6,7,8,9,10,11,12,13,13,14,15,16,17,18)
front() = 1, back() = 18
(2,3,4,5,6,7,8,9,10,11,12,13,13,14,15,16,17)
(2,3,4,5,6,777,8,9,10,11,666,666,666,12,13,13,14,15,16,17)
(2,3,4,5,6,777,8,9,10,11,666,666,666,12,13)
v[5] == 777
v is now empty
(66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66)
(33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33)
(1,2,3,4,5,6,7,8,9,10,11,12,13,13,14,15,16,17,18)
v == v2
A::A
A::A
A::A
A::A
A::operator=
A::operator=
A::operator=
Class insertion testing successful
A::~A
A::~A
A::~A
A::~A

399
extern/ustl/1.5/bvt/bvt05.cc vendored Normal file
View File

@@ -0,0 +1,399 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
typedef vector<int> intvec_t;
typedef const intvec_t& rcintvec_t;
typedef intvec_t::const_iterator intiter_t;
static void printint (int i)
{
cout.format ("%d ", i);
}
static void PrintVector (rcintvec_t v)
{
cout << "{ ";
foreach (intiter_t, i, v)
printint (*i);
cout << "}\n";
}
static bool is_even (int i)
{
return (i % 2 == 0);
}
static int sqr (int i)
{
return (i * i);
}
static int genint (void)
{
static int counter = 0;
return (counter++);
}
// In its own function because compilers differ in selecting const/nonconst
// members where no choice is needed.
//
static void TestEqualRange (rcintvec_t v)
{
pair<intiter_t,intiter_t> rv;
rv = equal_range (v, 10);
cout.format ("Range of 10 is { %2zd, %2zd }\n", abs_distance (v.begin(), rv.first), abs_distance (v.begin(), rv.second));
rv = equal_range (v, 0);
cout.format ("Range of 0 is { %2zd, %2zd }\n", abs_distance (v.begin(), rv.first), abs_distance (v.begin(), rv.second));
rv = equal_range (v, 100);
cout.format ("Range of 100 is { %2zd, %2zd }\n", abs_distance (v.begin(), rv.first), abs_distance (v.begin(), rv.second));
}
template <typename T>
void TestBigFill (const size_t size, const T magic)
{
vector<T> vbig (size);
fill (vbig.begin() + 1, vbig.end(), magic); // offset to test prealignment loop
typename vector<T>::const_iterator iMismatch;
iMismatch = find_if (vbig.begin() + 1, vbig.end(), bind1st (not_equal_to<T>(), magic));
if (iMismatch == vbig.end())
cout << "works\n";
else
cout.format ("does not work: mismatch at %zd, =0x%lX\n", abs_distance (vbig.begin(), iMismatch), (unsigned long)(*iMismatch));
}
template <typename T>
void TestBigCopy (const size_t size, const T magic)
{
vector<T> vbig1 (size), vbig2 (size);
fill (vbig1, magic);
copy (vbig1.begin() + 1, vbig1.end(), vbig2.begin() + 1); // offset to test prealignment loop
typedef typename vector<T>::const_iterator iter_t;
pair<iter_t, iter_t> iMismatch;
iMismatch = mismatch (vbig1.begin() + 1, vbig1.end(), vbig2.begin() + 1);
assert (iMismatch.second <= vbig2.end());
if (iMismatch.first == vbig1.end())
cout << "works\n";
else
cout.format ("does not work: mismatch at %zd, 0x%lX != 0x%lX\n", abs_distance(vbig1.begin(), iMismatch.first), (unsigned long)(*iMismatch.first), (unsigned long)(*iMismatch.second));
}
static void TestAlgorithms (void)
{
static const int c_TestNumbers[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 13, 14, 15, 16, 17, 18 };
const int* first = c_TestNumbers;
const int* last = first + VectorSize(c_TestNumbers);
intvec_t v, buf;
v.assign (first, last);
PrintVector (v);
cout << "swap(1,2)\n";
swap (v[0], v[1]);
PrintVector (v);
v.assign (first, last);
cout << "copy(0,8,9)\n";
copy (v.begin(), v.begin() + 8, v.begin() + 9);
PrintVector (v);
v.assign (first, last);
cout << "copy with back_inserter\n";
v.clear();
copy (first, last, back_inserter(v));
PrintVector (v);
v.assign (first, last);
cout << "copy with inserter\n";
v.clear();
copy (first, first + 5, inserter(v, v.begin()));
copy (first, first + 5, inserter(v, v.begin() + 3));
PrintVector (v);
v.assign (first, last);
cout << "copy_n(0,8,9)\n";
copy_n (v.begin(), 8, v.begin() + 9);
PrintVector (v);
v.assign (first, last);
cout << "copy_if(is_even)\n";
intvec_t v_even;
copy_if (v, back_inserter(v_even), &is_even);
PrintVector (v_even);
v.assign (first, last);
cout << "for_each(printint)\n{ ";
for_each (v, &printint);
cout << "}\n";
cout << "for_each(reverse_iterator, printint)\n{ ";
for_each (v.rbegin(), v.rend(), &printint);
cout << "}\n";
cout << "find(10)\n";
cout.format ("10 found at offset %zd\n", abs_distance (v.begin(), find (v, 10)));
cout << "count(13)\n";
cout.format ("%zu values of 13, %zu values of 18\n", count(v,13), count(v,18));
cout << "transform(sqr)\n";
transform (v, &sqr);
PrintVector (v);
v.assign (first, last);
cout << "replace(13,666)\n";
replace (v, 13, 666);
PrintVector (v);
v.assign (first, last);
cout << "fill(13)\n";
fill (v, 13);
PrintVector (v);
v.assign (first, last);
cout << "fill_n(5, 13)\n";
fill_n (v.begin(), 5, 13);
PrintVector (v);
v.assign (first, last);
cout << "fill 64083 uint8_t(0x41) ";
TestBigFill<uint8_t> (64083, 0x41);
cout << "fill 64083 uint16_t(0x4142) ";
TestBigFill<uint16_t> (64083, 0x4142);
cout << "fill 64083 uint32_t(0x41424344) ";
TestBigFill<uint32_t> (64083, 0x41424344);
cout << "fill 64083 float(0.4242) ";
TestBigFill<float> (64083, 0x4242f);
#if HAVE_INT64_T
cout << "fill 64083 uint64_t(0x4142434445464748) ";
TestBigFill<uint64_t> (64083, UINT64_C(0x4142434445464748));
#else
cout << "No 64bit types available on this platform\n";
#endif
cout << "copy 64083 uint8_t(0x41) ";
TestBigCopy<uint8_t> (64083, 0x41);
cout << "copy 64083 uint16_t(0x4142) ";
TestBigCopy<uint16_t> (64083, 0x4142);
cout << "copy 64083 uint32_t(0x41424344) ";
TestBigCopy<uint32_t> (64083, 0x41424344);
cout << "copy 64083 float(0.4242) ";
TestBigCopy<float> (64083, 0.4242f);
#if HAVE_INT64_T
cout << "copy 64083 uint64_t(0x4142434445464748) ";
TestBigCopy<uint64_t> (64083, UINT64_C(0x4142434445464748));
#else
cout << "No 64bit types available on this platform\n";
#endif
cout << "generate(genint)\n";
generate (v, &genint);
PrintVector (v);
v.assign (first, last);
cout << "rotate(4)\n";
rotate (v, 7);
rotate (v, -3);
PrintVector (v);
v.assign (first, last);
cout << "merge with (3,5,10,11,11,14)\n";
const int c_MergeWith[] = { 3,5,10,11,11,14 };
intvec_t vmerged;
merge (v.begin(), v.end(), VectorRange(c_MergeWith), back_inserter(vmerged));
PrintVector (vmerged);
v.assign (first, last);
cout << "inplace_merge with (3,5,10,11,11,14)\n";
v.insert (v.end(), VectorRange(c_MergeWith));
inplace_merge (v.begin(), v.end() - VectorSize(c_MergeWith), v.end());
PrintVector (v);
v.assign (first, last);
cout << "remove(13)\n";
remove (v, 13);
PrintVector (v);
v.assign (first, last);
cout << "remove (elements 3, 4, 6, 15, and 45)\n";
vector<uoff_t> toRemove;
toRemove.push_back (3);
toRemove.push_back (4);
toRemove.push_back (6);
toRemove.push_back (15);
toRemove.push_back (45);
typedef index_iterate<intvec_t::iterator, vector<uoff_t>::iterator> riiter_t;
riiter_t rfirst = index_iterator (v.begin(), toRemove.begin());
riiter_t rlast = index_iterator (v.begin(), toRemove.end());
remove (v, rfirst, rlast);
PrintVector (v);
v.assign (first, last);
cout << "unique\n";
unique (v);
PrintVector (v);
v.assign (first, last);
cout << "reverse\n";
reverse (v);
PrintVector (v);
v.assign (first, last);
cout << "lower_bound(10)\n";
PrintVector (v);
cout.format ("10 begins at position %zd\n", abs_distance (v.begin(), lower_bound (v, 10)));
v.assign (first, last);
cout << "upper_bound(10)\n";
PrintVector (v);
cout.format ("10 ends at position %zd\n", abs_distance (v.begin(), upper_bound (v, 10)));
v.assign (first, last);
cout << "equal_range(10)\n";
PrintVector (v);
TestEqualRange (v);
v.assign (first, last);
cout << "sort\n";
reverse (v);
PrintVector (v);
random_shuffle (v);
sort (v);
PrintVector (v);
v.assign (first, last);
cout << "stable_sort\n";
reverse (v);
PrintVector (v);
random_shuffle (v);
stable_sort (v);
PrintVector (v);
v.assign (first, last);
cout << "is_sorted\n";
random_shuffle (v);
const bool bNotSorted = is_sorted (v.begin(), v.end());
sort (v);
const bool bSorted = is_sorted (v.begin(), v.end());
cout << "unsorted=" << bNotSorted << ", sorted=" << bSorted << endl;
v.assign (first, last);
cout << "find_first_of\n";
static const int c_FFO[] = { 10000, -34, 14, 27 };
cout.format ("found 14 at position %zd\n", abs_distance (v.begin(), find_first_of (v.begin(), v.end(), VectorRange(c_FFO))));
v.assign (first, last);
static const int LC1[] = { 3, 1, 4, 1, 5, 9, 3 };
static const int LC2[] = { 3, 1, 4, 2, 8, 5, 7 };
static const int LC3[] = { 1, 2, 3, 4 };
static const int LC4[] = { 1, 2, 3, 4, 5 };
cout << "lexicographical_compare";
cout << "\nLC1 < LC2 == " << lexicographical_compare (VectorRange(LC1), VectorRange(LC2));
cout << "\nLC2 < LC2 == " << lexicographical_compare (VectorRange(LC2), VectorRange(LC2));
cout << "\nLC3 < LC4 == " << lexicographical_compare (VectorRange(LC3), VectorRange(LC4));
cout << "\nLC4 < LC1 == " << lexicographical_compare (VectorRange(LC4), VectorRange(LC1));
cout << "\nLC1 < LC4 == " << lexicographical_compare (VectorRange(LC1), VectorRange(LC4));
cout << "\nmax_element\n";
cout.format ("max element is %d\n", *max_element (v.begin(), v.end()));
v.assign (first, last);
cout << "min_element\n";
cout.format ("min element is %d\n", *min_element (v.begin(), v.end()));
v.assign (first, last);
cout << "partial_sort\n";
reverse (v);
partial_sort (v.begin(), v.iat(v.size() / 2), v.end());
PrintVector (v);
v.assign (first, last);
cout << "partial_sort_copy\n";
reverse (v);
buf.resize (v.size());
partial_sort_copy (v.begin(), v.end(), buf.begin(), buf.end());
PrintVector (buf);
v.assign (first, last);
cout << "partition\n";
partition (v.begin(), v.end(), &is_even);
PrintVector (v);
v.assign (first, last);
cout << "stable_partition\n";
stable_partition (v.begin(), v.end(), &is_even);
PrintVector (v);
v.assign (first, last);
cout << "next_permutation\n";
buf.resize (3);
iota (buf.begin(), buf.end(), 1);
PrintVector (buf);
while (next_permutation (buf.begin(), buf.end()))
PrintVector (buf);
cout << "prev_permutation\n";
reverse (buf);
PrintVector (buf);
while (prev_permutation (buf.begin(), buf.end()))
PrintVector (buf);
v.assign (first, last);
cout << "reverse_copy\n";
buf.resize (v.size());
reverse_copy (v.begin(), v.end(), buf.begin());
PrintVector (buf);
v.assign (first, last);
cout << "rotate_copy\n";
buf.resize (v.size());
rotate_copy (v.begin(), v.iat (v.size() / 3), v.end(), buf.begin());
PrintVector (buf);
v.assign (first, last);
static const int c_Search1[] = { 5, 6, 7, 8, 9 }, c_Search2[] = { 10, 10, 11, 14 };
cout << "search\n";
cout.format ("{5,6,7,8,9} at %zd\n", abs_distance (v.begin(), search (v.begin(), v.end(), VectorRange(c_Search1))));
cout.format ("{10,10,11,14} at %zd\n", abs_distance (v.begin(), search (v.begin(), v.end(), VectorRange(c_Search2))));
cout << "find_end\n";
cout.format ("{5,6,7,8,9} at %zd\n", abs_distance (v.begin(), find_end (v.begin(), v.end(), VectorRange(c_Search1))));
cout.format ("{10,10,11,14} at %zd\n", abs_distance (v.begin(), find_end (v.begin(), v.end(), VectorRange(c_Search2))));
cout << "search_n\n";
cout.format ("{14} at %zd\n", abs_distance (v.begin(), search_n (v.begin(), v.end(), 1, 14)));
cout.format ("{13,13} at %zd\n", abs_distance (v.begin(), search_n (v.begin(), v.end(), 2, 13)));
cout.format ("{10,10,10} at %zd\n", abs_distance (v.begin(), search_n (v.begin(), v.end(), 3, 10)));
v.assign (first, last);
cout << "includes\n";
static const int c_Includes[] = { 5, 14, 15, 18, 20 };
cout << "includes=" << includes (v.begin(), v.end(), VectorRange(c_Includes)-1);
cout << ", not includes=" << includes (v.begin(), v.end(), VectorRange(c_Includes));
cout << endl;
static const int c_Set1[] = { 1, 2, 3, 4, 5, 6 }, c_Set2[] = { 4, 4, 6, 7, 8 };
intvec_t::iterator setEnd;
cout << "set_difference\n";
v.resize (4);
setEnd = set_difference (VectorRange(c_Set1), VectorRange(c_Set2), v.begin());
PrintVector (v);
assert (setEnd == v.end());
cout << "set_symmetric_difference\n";
v.resize (7);
setEnd = set_symmetric_difference (VectorRange(c_Set1), VectorRange(c_Set2), v.begin());
PrintVector (v);
assert (setEnd == v.end());
cout << "set_intersection\n";
v.resize (2);
setEnd = set_intersection (VectorRange(c_Set1), VectorRange(c_Set2), v.begin());
PrintVector (v);
assert (setEnd == v.end());
cout << "set_union\n";
v.resize (9);
setEnd = set_union (VectorRange(c_Set1), VectorRange(c_Set2), v.begin());
PrintVector (v);
assert (setEnd == v.end());
v.assign (first, last);
}
StdBvtMain (TestAlgorithms)

132
extern/ustl/1.5/bvt/bvt05.std vendored Normal file
View File

@@ -0,0 +1,132 @@
{ 1 2 3 4 5 6 7 8 9 10 10 11 12 13 13 14 15 16 17 18 }
swap(1,2)
{ 2 1 3 4 5 6 7 8 9 10 10 11 12 13 13 14 15 16 17 18 }
copy(0,8,9)
{ 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 16 17 18 }
copy with back_inserter
{ 1 2 3 4 5 6 7 8 9 10 10 11 12 13 13 14 15 16 17 18 }
copy with inserter
{ 1 2 3 1 2 3 4 5 4 5 }
copy_n(0,8,9)
{ 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 16 17 18 }
copy_if(is_even)
{ 2 4 6 8 10 10 12 14 16 18 }
for_each(printint)
{ 1 2 3 4 5 6 7 8 9 10 10 11 12 13 13 14 15 16 17 18 }
for_each(reverse_iterator, printint)
{ 18 17 16 15 14 13 13 12 11 10 10 9 8 7 6 5 4 3 2 1 }
find(10)
10 found at offset 9
count(13)
2 values of 13, 1 values of 18
transform(sqr)
{ 1 4 9 16 25 36 49 64 81 100 100 121 144 169 169 196 225 256 289 324 }
replace(13,666)
{ 1 2 3 4 5 6 7 8 9 10 10 11 12 666 666 14 15 16 17 18 }
fill(13)
{ 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 }
fill_n(5, 13)
{ 13 13 13 13 13 6 7 8 9 10 10 11 12 13 13 14 15 16 17 18 }
fill 64083 uint8_t(0x41) works
fill 64083 uint16_t(0x4142) works
fill 64083 uint32_t(0x41424344) works
fill 64083 float(0.4242) works
fill 64083 uint64_t(0x4142434445464748) works
copy 64083 uint8_t(0x41) works
copy 64083 uint16_t(0x4142) works
copy 64083 uint32_t(0x41424344) works
copy 64083 float(0.4242) works
copy 64083 uint64_t(0x4142434445464748) works
generate(genint)
{ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 }
rotate(4)
{ 15 16 17 18 1 2 3 4 5 6 7 8 9 10 10 11 12 13 13 14 }
merge with (3,5,10,11,11,14)
{ 1 2 3 3 4 5 5 6 7 8 9 10 10 10 11 11 11 12 13 13 14 14 15 16 17 18 }
inplace_merge with (3,5,10,11,11,14)
{ 1 2 3 3 4 5 5 6 7 8 9 10 10 10 11 11 11 12 13 13 14 14 15 16 17 18 }
remove(13)
{ 1 2 3 4 5 6 7 8 9 10 10 11 12 14 15 16 17 18 }
remove (elements 3, 4, 6, 15, and 45)
{ 1 2 3 6 8 9 10 10 11 12 13 13 15 16 17 18 }
unique
{ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 }
reverse
{ 18 17 16 15 14 13 13 12 11 10 10 9 8 7 6 5 4 3 2 1 }
lower_bound(10)
{ 1 2 3 4 5 6 7 8 9 10 10 11 12 13 13 14 15 16 17 18 }
10 begins at position 9
upper_bound(10)
{ 1 2 3 4 5 6 7 8 9 10 10 11 12 13 13 14 15 16 17 18 }
10 ends at position 11
equal_range(10)
{ 1 2 3 4 5 6 7 8 9 10 10 11 12 13 13 14 15 16 17 18 }
Range of 10 is { 9, 11 }
Range of 0 is { 0, 0 }
Range of 100 is { 20, 20 }
sort
{ 18 17 16 15 14 13 13 12 11 10 10 9 8 7 6 5 4 3 2 1 }
{ 1 2 3 4 5 6 7 8 9 10 10 11 12 13 13 14 15 16 17 18 }
stable_sort
{ 18 17 16 15 14 13 13 12 11 10 10 9 8 7 6 5 4 3 2 1 }
{ 1 2 3 4 5 6 7 8 9 10 10 11 12 13 13 14 15 16 17 18 }
is_sorted
unsorted=false, sorted=true
find_first_of
found 14 at position 15
lexicographical_compare
LC1 < LC2 == true
LC2 < LC2 == false
LC3 < LC4 == true
LC4 < LC1 == true
LC1 < LC4 == false
max_element
max element is 18
min_element
min element is 1
partial_sort
{ 1 2 3 4 5 6 7 8 9 10 10 11 12 13 13 14 15 16 17 18 }
partial_sort_copy
{ 1 2 3 4 5 6 7 8 9 10 10 11 12 13 13 14 15 16 17 18 }
partition
{ 2 4 6 8 10 10 12 14 16 18 1 3 5 7 9 11 13 13 15 17 }
stable_partition
{ 2 4 6 8 10 10 12 14 16 18 1 3 5 7 9 11 13 13 15 17 }
next_permutation
{ 1 2 3 }
{ 1 3 2 }
{ 2 1 3 }
{ 2 3 1 }
{ 3 1 2 }
{ 3 2 1 }
prev_permutation
{ 3 2 1 }
{ 3 1 2 }
{ 2 3 1 }
{ 2 1 3 }
{ 1 3 2 }
{ 1 2 3 }
reverse_copy
{ 18 17 16 15 14 13 13 12 11 10 10 9 8 7 6 5 4 3 2 1 }
rotate_copy
{ 7 8 9 10 10 11 12 13 13 14 15 16 17 18 1 2 3 4 5 6 }
search
{5,6,7,8,9} at 4
{10,10,11,14} at 20
find_end
{5,6,7,8,9} at 4
{10,10,11,14} at 20
search_n
{14} at 15
{13,13} at 13
{10,10,10} at 20
includes
includes=true, not includes=false
set_difference
{ 1 2 3 5 }
set_symmetric_difference
{ 1 2 3 4 5 7 8 }
set_intersection
{ 4 6 }
set_union
{ 1 2 3 4 4 5 6 7 8 }

59
extern/ustl/1.5/bvt/bvt06.cc vendored Normal file
View File

@@ -0,0 +1,59 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
void PrintBlock (const cmemlink& l)
{
const int* numbers = reinterpret_cast<const int*>(l.begin());
const size_t nNumbers = l.size() / sizeof(int);
for (size_t i = 0; i < nNumbers; ++ i)
cout << numbers[i] << ' ';
cout << endl;
}
void TestObjectVector (void)
{
vector<memblock> v;
const size_t nNumbers = 1000;
int numbers [nNumbers];
const size_t nLinks = 10;
cmemlink links [nLinks];
for (size_t i = 0; i < nNumbers; ++ i)
numbers[i] = i;
uoff_t offset = 0;
for (size_t l = 0; l < nLinks; ++ l) {
links[l].link (numbers + offset, l * sizeof(int));
offset += l;
v.push_back (memblock(links[l]));
}
cout.format ("---\nvector<memblock> of %zu elements:\n---\n", v.size());
for_each (v.begin(), v.end(), &PrintBlock);
cout.format ("---\nsize() = %zu, max_size() = ", v.size());
if (v.max_size() == SIZE_MAX / sizeof(memblock))
cout << "SIZE_MAX/elsize";
else
cout << v.max_size();
static const char tf[2][6]={"false","true"};
cout.format (", empty() = %s\n", tf[v.empty()]);
v.push_back (memblock(5));
cout.format ("back()->size() = %zu\n", v.back().size());
v.back().resize (40);
cout.format ("back()->size() = %zu\n", v.back().size());
v.pop_back();
PrintBlock (v.back());
vector<memblock> cache;
cache.assign (v.begin(), v.end());
v.clear();
v.assign (cache.begin(), cache.end());
v.erase (v.begin() + 5, 2);
v.erase (v.end() - 1, 1);
v.erase (v.end(), streamsize(0));
cout.format ("---\nvector of %zu elements backwards:\n---\n", v.size());
for_each (v.rbegin(), v.rend(), &PrintBlock);
cout << "---\n";
}
StdBvtMain (TestObjectVector)

29
extern/ustl/1.5/bvt/bvt06.std vendored Normal file
View File

@@ -0,0 +1,29 @@
---
vector<memblock> of 10 elements:
---
0
1 2
3 4 5
6 7 8 9
10 11 12 13 14
15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31 32 33 34 35
36 37 38 39 40 41 42 43 44
---
size() = 10, max_size() = SIZE_MAX/elsize, empty() = false
back()->size() = 5
back()->size() = 40
36 37 38 39 40 41 42 43 44
---
vector of 7 elements backwards:
---
28 29 30 31 32 33 34 35
21 22 23 24 25 26 27
6 7 8 9
3 4 5
1 2
0
---

135
extern/ustl/1.5/bvt/bvt07.cc vendored Normal file
View File

@@ -0,0 +1,135 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
void MyFormat (const char* fmt, ...) __attribute__((__format__(__printf__,1,2)));
void TestString (void)
{
static const char c_TestString1[] = "123456789012345678901234567890";
static const char c_TestString2[] = "abcdefghijklmnopqrstuvwxyz";
static const char c_TestString3[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string s1 (c_TestString1);
string s2 (VectorRange (c_TestString2));
string s3 (s1);
cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl;
s3.reserve (48);
s3.resize (20);
uoff_t i;
for (i = 0; i < s3.length(); ++ i)
s3.at(i) = s3.at(i);
for (i = 0; i < s3.length(); ++ i)
s3[i] = s3[i];
cout.format ("%s\ns3.size() = %zu, max_size() = ", s3.c_str(), s3.size());
if (s3.max_size() == SIZE_MAX - 1)
cout << "(SIZE_MAX/elsize)-1";
else
cout << s3.max_size();
cout.format (", capacity() = %zu\n", s3.capacity());
s1.unlink();
s1 = c_TestString2;
s1 += c_TestString3;
s1 += '$';
cout << s1 << endl;
s1 = "Hello";
s2.unlink();
s2 = "World";
s3 = s1 + s2;
cout << s3 << endl;
s3 = "Concatenated " + s1 + s2 + " string.";
cout << s3 << endl;
if (s1 < s2)
cout << "s1 < s2\n";
if (s1 == s1)
cout << "s1 == s1\n";
if (s1[0] != s1[0])
cout << "s1[0] != s1[0]\n";
string s4;
s4.link (s1);
if (s1 == s4)
cout << "s1 == s4\n";
s1 = c_TestString1;
string s5 (s1.begin() + 4, s1.begin() + 4 + 5);
string s6 (s1.begin() + 4, s1.begin() + 4 + 5);
if (s5 == s6)
cout.format ("%s == %s\n", s5.c_str(), s6.c_str());
string tail (s1.begin() + 7, s1.end());
cout.format ("&s1[7] = %s\n", tail.c_str());
cout.format ("initial:\t\t%s\n", s1.c_str());
cout << "erase(5,find(9)-5)\t";
s1.erase (5, s1.find ('9')-5);
cout << s1 << endl;
cout << "erase(5,5)\t\t";
s1.erase (s1.begin() + 5, 2U);
s1.erase (5, 3);
assert (!*s1.end());
cout << s1 << endl;
cout << "push_back('x')\t\t";
s1.push_back ('x');
assert (!*s1.end());
cout << s1 << endl;
cout << "pop_back()\n";
s1.pop_back();
assert (!*s1.end());
cout << "insert(10,#)\t\t";
s1.insert (s1.begin() + 10, '#');
assert (!*s1.end());
cout << s1 << endl;
cout << "replace(0,5,@)\t\t";
s1.replace (s1.begin(), s1.begin() + 5, 1, '@');
assert (!*s1.end());
cout << s1 << endl;
s1 = c_TestString1;
cout.format ("8 found at %zu\n", s1.find ('8'));
cout.format ("9 found at %zu\n", s1.find ("9"));
cout.format ("7 rfound at %zu\n", s1.rfind ('7'));
cout.format ("7 rfound again at %zu\n", s1.rfind ('7', s1.rfind ('7') - 1));
cout.format ("67 rfound at %zu\n", s1.rfind ("67"));
if (s1.rfind("X") == string::npos)
cout << "X was not rfound\n";
else
cout.format ("X rfound at %zu\n", s1.rfind ("X"));
uoff_t poundfound = s1.find ("#");
if (poundfound != string::npos)
cout.format ("# found at %zu\n", poundfound);
cout.format ("[456] found at %zu\n", s1.find_first_of ("456"));
cout.format ("[456] last found at %zu\n", s1.find_last_of ("456"));
s2.clear();
assert (!*s2.end());
if (s2.empty())
cout.format ("s2 is empty [%s], capacity %zu bytes\n", s2.c_str(), s2.capacity());
s2.format ("<const] %d, %s, 0x%08X", 42, "[rfile>", 0xDEADBEEF);
cout.format ("<%zu bytes of %zu> Format '%s'\n", s2.length(), s2.capacity(), s2.c_str());
MyFormat ("'<const] %d, %s, 0x%08X'", 42, "[rfile>", 0xDEADBEEF);
cout.format ("hash_value(s2) = %08X, string::hash(s2) = %08X\n", hash_value (s2.begin()), string::hash (s2.begin(), s2.end()));
}
void MyFormat (const char* fmt, ...)
{
string buf;
simd::reset_mmx();
va_list args;
va_start (args, fmt);
buf.vformat (fmt, args);
cout.format ("Custom vararg MyFormat: %s\n", buf.c_str());
va_end (args);
}
StdBvtMain (TestString)

32
extern/ustl/1.5/bvt/bvt07.std vendored Normal file
View File

@@ -0,0 +1,32 @@
123456789012345678901234567890
abcdefghijklmnopqrstuvwxyz
123456789012345678901234567890
12345678901234567890
s3.size() = 20, max_size() = (SIZE_MAX/elsize)-1, capacity() = 48
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$
HelloWorld
Concatenated HelloWorld string.
s1 < s2
s1 == s1
s1 == s4
56789 == 56789
&s1[7] = 89012345678901234567890
initial: 123456789012345678901234567890
erase(5,find(9)-5) 123459012345678901234567890
erase(5,5) 1234545678901234567890
push_back('x') 1234545678901234567890x
pop_back()
insert(10,#) 1234545678#901234567890
replace(0,5,@) @45678#901234567890
8 found at 7
9 found at 8
7 rfound at 26
7 rfound again at 16
67 rfound at 25
X was not rfound
[456] found at 3
[456] last found at 25
s2 is empty [], capacity 5 bytes
<31 bytes of 31> Format '<const] 42, [rfile>, 0xDEADBEEF'
Custom vararg MyFormat: '<const] 42, [rfile>, 0xDEADBEEF'
hash_value(s2) = 95A714F3, string::hash(s2) = 95A714F3

57
extern/ustl/1.5/bvt/bvt08.cc vendored Normal file
View File

@@ -0,0 +1,57 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
inline void PrintString (const string& str)
{
cout << str << endl;
}
void TestStringVector (void)
{
vector<string> v;
vector<string>::iterator bogusi = find (v, string("bogus"));
if (bogusi != v.end())
cout << "bogus found at position " << bogusi - v.begin() << endl;
v.push_back (string("Hello world!"));
v.push_back (string("Hello again!"));
v.push_back (string("element3"));
v.push_back (string("element4"));
v.push_back (string("element5_long_element5"));
for_each (v, &PrintString);
if (!(v[2] == string("element3")))
cout << "operator== failed" << endl;
vector<string>::iterator el3i = find (v, string("element3"));
if (el3i != v.end())
cout << *el3i << " found at position " << el3i - v.begin() << endl;
bogusi = find (v, string("bogus"));
if (bogusi != v.end())
cout << *bogusi << " found at position " << bogusi - v.begin()<< endl;
vector<string> v2;
v2 = v;
v = v2;
v.erase (v.end(), v.end());
cout << "After erase (end,end):" << endl;
for_each (v, &PrintString);
v = v2;
v.erase (v.begin() + 2, 2);
cout << "After erase (2,2):" << endl;
for_each (v, &PrintString);
v = v2;
v.pop_back();
cout << "After pop_back():" << endl;
for_each (v, &PrintString);
v = v2;
v.insert (v.begin() + 1, v2.begin() + 1, v2.begin() + 1 + 3);
cout << "After insert(1,1,3):" << endl;
for_each (v, &PrintString);
}
StdBvtMain (TestStringVector)

30
extern/ustl/1.5/bvt/bvt08.std vendored Normal file
View File

@@ -0,0 +1,30 @@
Hello world!
Hello again!
element3
element4
element5_long_element5
element3 found at position 2
After erase (end,end):
Hello world!
Hello again!
element3
element4
element5_long_element5
After erase (2,2):
Hello world!
Hello again!
element5_long_element5
After pop_back():
Hello world!
Hello again!
element3
element4
After insert(1,1,3):
Hello world!
Hello again!
element3
element4
Hello again!
element3
element4
element5_long_element5

84
extern/ustl/1.5/bvt/bvt09.cc vendored Normal file
View File

@@ -0,0 +1,84 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
void TestStringStreams (void)
{
const unsigned char magic_Char = 'c';
const unsigned short magic_Short = 1234;
const long magic_Int = -12345678;
const unsigned long magic_UInt = 12345678;
const float magic_Float = 123.45678;
const double magic_Double = 123456789123456.789;
const bool magic_Bool = true;
char c = magic_Char;
unsigned char uc = magic_Char;
int i = magic_Int;
short si = magic_Short;
long li = magic_Int;
unsigned int ui = magic_UInt;
unsigned short usi = magic_Short;
unsigned long uli = magic_UInt;
float f = magic_Float;
double d = magic_Double;
bool bv = magic_Bool;
ostringstream os;
os << c << endl;
os << uc << endl;
os << bv << endl;
os << i << endl;
os << ui << endl;
os << li << endl;
os << uli << endl;
os << f << endl;
os << d << endl;
os << si << endl;
os << usi << endl << ends;
os.flush();
cout << os.pos() << " bytes written" << endl;
c = 0;
uc = 0;
bv = false;
i = ui = li = uli = 0;
f = 0; d = 0;
si = usi = 0;
istringstream is (os.str());
is >> c;
is >> uc;
is >> bv;
is >> i;
is >> ui;
is >> li;
is >> uli;
is >> f;
is >> d;
is >> si;
is >> usi;
cout << "Values:" << endl;
cout.format ("char: '%c'\n", static_cast<int>(c));
cout.format ("u_char: '%c'\n", static_cast<int>(uc));
cout.format ("bool: %d\n", static_cast<int>(bv));
cout.format ("int: %d\n", i);
cout.format ("u_int: %d\n", ui);
cout.format ("long: %ld\n", li);
cout.format ("u_long: %ld\n", uli);
cout.format ("float: %.2f\n", f);
cout.format ("double: %.2f\n", d);
cout.format ("short: %d\n", static_cast<int>(si));
cout.format ("u_short: %d\n", static_cast<int>(usi));
cout << endl;
cout << "Dump:" << endl;
cout << os.str().cdata() << endl;
cout << endl;
}
StdBvtMain (TestStringStreams)

28
extern/ustl/1.5/bvt/bvt09.std vendored Normal file
View File

@@ -0,0 +1,28 @@
84 bytes written
Values:
char: 'c'
u_char: 'c'
bool: 1
int: -12345678
u_int: 12345678
long: -12345678
u_long: 12345678
float: 123.46
double: 123456789123456.78
short: 1234
u_short: 1234
Dump:
c
c
true
-12345678
12345678
-12345678
12345678
123.46
123456789123456.78
1234
1234

171
extern/ustl/1.5/bvt/bvt10.cc vendored Normal file
View File

@@ -0,0 +1,171 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
template <typename Container>
void PrintVector (const Container& ctr)
{
cout << "{";
foreach (typename Container::const_iterator, i, ctr)
cout << ' ' << *i;
cout << " }\n";
}
class A {
public:
A (int dv = 6) : m_v1 (0), m_v (dv) {}
int addsix (int i) { return (i + m_v); }
void addsix (int& i) const { i += m_v; }
void addtosix (int i) { m_v += i; }
inline void text_write (ostringstream& os) const { os << m_v; }
public:
int m_v1;
int m_v;
};
INTEGRAL_STREAMABLE(A)
TEXT_STREAMABLE(A)
void TestFunctors (void)
{
vector<int> v;
v.resize (20);
fill (v, 2);
foreach (vector<int>::iterator, i, v)
*i -= distance(v.begin(), i) & 1;
vector<int> v1 (v);
cout << "start:\t\t\t";
PrintVector (v);
v = v1;
cout << "plus:\t\t\t";
transform (v, v.begin(), v.begin(), plus<int>());
PrintVector (v);
v = v1;
cout << "minus:\t\t\t";
transform (v, v.begin(), v.begin(), minus<int>());
PrintVector (v);
v = v1;
cout << "divides:\t\t";
transform (v, v.begin(), v.begin(), divides<int>());
PrintVector (v);
v = v1;
cout << "multiplies:\t\t";
transform (v, v.begin(), v.begin(), multiplies<int>());
PrintVector (v);
v = v1;
cout << "modulus:\t\t";
transform (v, v.begin(), v.begin(), modulus<int>());
PrintVector (v);
v = v1;
cout << "logical_and:\t\t";
transform (v, v.begin(), v.begin(), logical_and<int>());
PrintVector (v);
v = v1;
cout << "logical_or:\t\t";
transform (v, v.begin(), v.begin(), logical_or<int>());
PrintVector (v);
v = v1;
cout << "equal_to:\t\t";
transform (v, v.begin(), v.begin(), equal_to<int>());
PrintVector (v);
v = v1;
cout << "not_equal_to:\t\t";
transform (v, v.begin(), v.begin(), not_equal_to<int>());
PrintVector (v);
v = v1;
cout << "greater:\t\t";
transform (v, v.begin(), v.begin(), greater<int>());
PrintVector (v);
v = v1;
cout << "less:\t\t\t";
transform (v, v.begin(), v.begin(), less<int>());
PrintVector (v);
v = v1;
cout << "greater_equal:\t\t";
transform (v, v.begin(), v.begin(), greater_equal<int>());
PrintVector (v);
v = v1;
cout << "less_equal:\t\t";
transform (v, v.begin(), v.begin(), less_equal<int>());
PrintVector (v);
v = v1;
cout << "compare:\t\t";
transform (v, v.begin(), v.begin(), compare<int>());
PrintVector (v);
v = v1;
cout << "negate:\t\t\t";
transform (v, negate<int>());
PrintVector (v);
v = v1;
cout << "logical_not:\t\t";
transform (v, logical_not<int>());
PrintVector (v);
v = v1;
cout << "unary_neg(negate):\t";
transform (v, unary_negator(negate<int>()));
PrintVector (v);
v = v1;
cout << "binder1st(plus,5):\t";
transform (v, bind1st(plus<int>(), 5));
PrintVector (v);
v = v1;
cout << "binder2nd(minus,1):\t";
transform (v, bind2nd(minus<int>(), 1));
PrintVector (v);
v = v1;
cout << "compose1(-,+5):\t\t";
transform (v, compose1 (negate<int>(), bind2nd(plus<int>(), 5)));
PrintVector (v);
v = v1;
cout << "compose1(-,-4):\t\t";
transform (v, compose1 (negate<int>(), bind2nd(minus<int>(), 4)));
PrintVector (v);
v = v1;
cout << "compose2(/,+6,-4):\t";
transform (v, compose2 (divides<int>(), bind2nd(plus<int>(), 6), bind2nd(minus<int>(), 4)));
PrintVector (v);
cout << "mem_var(plus,6):\t";
vector<A> av;
for (uoff_t i = 0; i < 20; ++ i)
av.push_back (A(i));
transform (av, mem_var1(&A::m_v, bind2nd(plus<int>(), 6)));
PrintVector (av);
vector<A>::iterator found = find_if (av, mem_var_equal_to(&A::m_v, 14));
cout << "14 found at position " << found - av.begin() << endl;
found = lower_bound (av.begin(), av.end(), 18, mem_var_less(&A::m_v));
cout << "18 found at position " << found - av.begin() << endl;
cout << "add next:\t\t";
transform (av.begin(), av.end() - 1, av.begin() + 1, av.begin(), mem_var2(&A::m_v, plus<int>()));
PrintVector (av);
}
StdBvtMain (TestFunctors)

27
extern/ustl/1.5/bvt/bvt10.std vendored Normal file
View File

@@ -0,0 +1,27 @@
start: { 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 }
plus: { 4 2 4 2 4 2 4 2 4 2 4 2 4 2 4 2 4 2 4 2 }
minus: { 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 }
divides: { 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 }
multiplies: { 4 1 4 1 4 1 4 1 4 1 4 1 4 1 4 1 4 1 4 1 }
modulus: { 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 }
logical_and: { 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 }
logical_or: { 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 }
equal_to: { 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 }
not_equal_to: { 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 }
greater: { 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 }
less: { 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 }
greater_equal: { 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 }
less_equal: { 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 }
compare: { 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 }
negate: { -2 -1 -2 -1 -2 -1 -2 -1 -2 -1 -2 -1 -2 -1 -2 -1 -2 -1 -2 -1 }
logical_not: { 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 }
unary_neg(negate): { 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 }
binder1st(plus,5): { 7 6 7 6 7 6 7 6 7 6 7 6 7 6 7 6 7 6 7 6 }
binder2nd(minus,1): { 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 }
compose1(-,+5): { -7 -6 -7 -6 -7 -6 -7 -6 -7 -6 -7 -6 -7 -6 -7 -6 -7 -6 -7 -6 }
compose1(-,-4): { 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 }
compose2(/,+6,-4): { -4 -2 -4 -2 -4 -2 -4 -2 -4 -2 -4 -2 -4 -2 -4 -2 -4 -2 -4 -2 }
mem_var(plus,6): { 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 }
14 found at position 8
18 found at position 12
add next: { 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 25 }

36
extern/ustl/1.5/bvt/bvt11.cc vendored Normal file
View File

@@ -0,0 +1,36 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
void PrintVector (const int* first, const int* last)
{
cout << "{";
while (first < last)
cout << ' ' << *first++;
cout << " }" << endl;
}
void TestSetAndMultiset (void)
{
const int vv[] = { 1, 8, 9, 2, 3, 1, 1, 4, 6, 1, 3, 4 };
set<int> v (VectorRange (vv));
multiset<int> mv (VectorRange (vv));
cout << "set:\t\t";
PrintVector (v.begin(), v.end());
cout << "erase(3):\t";
v.erase (3);
PrintVector (v.begin(), v.end());
cout << "multiset:\t";
PrintVector (mv.begin(), mv.end());
cout << "count(1) = " << mv.count(1) << endl;
cout << "find(4) = " << lower_bound (mv, 4) - mv.begin() << endl;
cout << "find(5) = " << binary_search (mv, 5) << endl;
cout << "erase(3):\t";
mv.erase (3);
PrintVector (mv.begin(), mv.end());
}
StdBvtMain (TestSetAndMultiset)

7
extern/ustl/1.5/bvt/bvt11.std vendored Normal file
View File

@@ -0,0 +1,7 @@
set: { 1 2 3 4 6 8 9 }
erase(3): { 1 2 4 6 8 9 }
multiset: { 1 1 1 1 2 3 3 4 4 6 8 9 }
count(1) = 4
find(4) = 7
find(5) = false
erase(3): { 1 1 1 1 2 4 4 6 8 9 }

81
extern/ustl/1.5/bvt/bvt12.cc vendored Normal file
View File

@@ -0,0 +1,81 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
void ObjectSerialization (void)
{
#define RW(stream) rws[stream.pos() == expect]
const void* pBufC = NULL;
void* pBuf = NULL;
memblock buffer;
string testString ("TestString");
const string* pStrC = NULL;
string* pStr = NULL;
vector<uint16_t> tv (7);
static const char* rws[2] = { "wrong", "right" };
const size_t bufSize = stream_size_of(pBufC) +
stream_size_of(pBuf) +
Align(stream_size_of(testString)) +
stream_size_of(pStrC) +
stream_size_of(pStr) +
stream_size_of(tv);
buffer.resize (bufSize);
pBufC = buffer.cdata();
pBuf = buffer.data();
uoff_t expect = 0;
ostream os (buffer);
os << pBufC; expect += stream_size_of(pBufC);
cout << "Write const void*, pos is " << RW(os) << endl;
os << pBuf; expect += stream_size_of(pBuf);
cout << "Write void*, pos is " << RW(os) << endl;
os << testString; expect += stream_size_of(testString);
cout << "Write string, pos is " << RW(os) << endl;
os.align(); expect = Align (expect);
os << const_cast<const string*>(&testString); expect += stream_size_of(&testString);
cout << "Write const string*, pos is " << RW(os) << endl;
os << &testString; expect += stream_size_of(&testString);
cout << "Write string*, pos is " << RW(os) << endl;
os << tv; expect += stream_size_of(tv);
cout << "Write vector<uint16_t>(7), pos is " << RW(os) << endl;
if (os.pos() != bufSize)
cout << "Incorrect number of bytes written: " << os.pos() << " of " << bufSize << endl;
istream is (buffer);
expect = 0;
is >> pBufC;
expect += stream_size_of(pBufC);
cout << "Read const void*, pos is " << RW(is);
cout << ", value is " << rws[pBufC == buffer.cdata()] << endl;
is >> pBuf;
expect += stream_size_of(pBuf);
cout << "Read void*, pos is " << RW(is);
cout << ", value is " << rws[pBuf == buffer.cdata()] << endl;
testString.clear();
is >> testString;
expect += stream_size_of(testString);
cout << "Read string, pos is " << RW(is) << ", value is " << testString << endl;
is.align();
expect = Align (expect);
is >> pStrC;
expect += stream_size_of(pStrC);
cout << "Read const string*, pos is " << RW(is);
cout << ", value is " << rws[pStrC == &testString] << endl;
is >> pStr;
expect += stream_size_of(pStr);
cout << "Read string*, pos is " << RW(is);
cout << ", value is " << rws[pStr == &testString] << endl;
vector<uint16_t> rv;
is >> rv;
expect += stream_size_of(rv);
cout << "Read vector<uint16_t>(" << rv.size() << "), pos is " << RW(is);
cout << ", value is " << rws[rv == tv] << endl;
if (is.pos() != bufSize)
cout << "Incorrect number of bytes read: " << is.pos() << " of " << bufSize << endl;
}
StdBvtMain (ObjectSerialization)

12
extern/ustl/1.5/bvt/bvt12.std vendored Normal file
View File

@@ -0,0 +1,12 @@
Write const void*, pos is right
Write void*, pos is right
Write string, pos is right
Write const string*, pos is right
Write string*, pos is right
Write vector<uint16_t>(7), pos is right
Read const void*, pos is right, value is right
Read void*, pos is right, value is right
Read string, pos is right, value is TestString
Read const string*, pos is right, value is right
Read string*, pos is right, value is right
Read vector<uint16_t>(7), pos is right, value is right

36
extern/ustl/1.5/bvt/bvt13.cc vendored Normal file
View File

@@ -0,0 +1,36 @@
// "Testing string reads" 12345678 4321 0x78675645 1.234567890123456
// (the above line is the input to this test, so must be at the beginning)
//
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
#include <stdio.h>
void TestCoutCinCerr (void)
{
string testStr;
cin >> testStr;
if (testStr != "//") {
cout.format ("You must put bvt13.cc on stdin (read \"%s\")\n", testStr.c_str());
return;
}
uint32_t n1 = 0, n3 = 0;
uint16_t n2 = 0;
double f1 = 0.0;
cin >> testStr >> n1 >> n2 >> n3 >> f1;
cout << testStr << endl;
cout << "A string printed to stdout\n";
cout.format ("%d %s: %d, %hd, 0x%08X, %1.15f\n", 4, "numbers", n1, n2, n3, f1);
string testString;
testString.format ("A ustl::string object printed %d times\n", 3);
for (int i = 0; i < 3; ++ i)
cout << testString;
cout.flush();
fprintf (stderr, "All ");
cerr << "done.\n";
}
StdBvtMain (TestCoutCinCerr)

7
extern/ustl/1.5/bvt/bvt13.std vendored Normal file
View File

@@ -0,0 +1,7 @@
Testing string reads
A string printed to stdout
4 numbers: 12345678, 4321, 0x78675645, 1.234567890123456
A ustl::string object printed 3 times
A ustl::string object printed 3 times
A ustl::string object printed 3 times
All done.

59
extern/ustl/1.5/bvt/bvt14.cc vendored Normal file
View File

@@ -0,0 +1,59 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
void TestMap (void)
{
typedef map<string,int> monthmap_t;
monthmap_t months;
months["january"] = 31;
months["february"] = 28;
months["march"] = 31;
months["april"] = 30;
months["may"] = 31;
months["june"] = 30;
months["july"] = 31;
months["august"] = 31;
months["september"] = 30;
months["october"] = 31;
months["november"] = 30;
months["december"] = 31;
const monthmap_t& cmonths = months;
cout << "There are " << cmonths["january"] << " days in january." << endl;
cout << "There are " << cmonths["september"] << " days in september." << endl;
cout << "There are " << cmonths["december"] << " days in december." << endl;
monthmap_t::const_iterator found_may = months.find ("may");
cout << found_may->first << " found at index " << found_may - months.begin() << endl;
cout << "Alphabetical listing:" << endl;
monthmap_t::const_iterator i;
for (i = months.begin(); i < months.end(); ++ i)
cout << i->first << " has " << i->second << " days." << endl;
monthmap_t mcopy (months);
mcopy.erase ("may");
cout << "After erasing may:" << endl;
for (i = mcopy.begin(); i < mcopy.end(); ++ i)
cout << i->first << " ";
cout << endl;
mcopy.assign (months.begin(), months.end() - 1);
mcopy.erase (mcopy.begin() + 1, mcopy.begin() + 4);
cout << "After erasing months 2, 3, 4, and the last one:" << endl;
for (i = mcopy.begin(); i < mcopy.end(); ++ i)
cout << i->first << " ";
cout << endl;
mcopy = months;
monthmap_t::iterator frob = mcopy.insert (mcopy.begin(), make_pair (string("frobuary"), 42));
cout << "After inserting " << frob->first << "," << frob->second << ":" << endl;
for (i = mcopy.begin(); i < mcopy.end(); ++ i)
cout << i->first << " ";
cout << endl;
}
StdBvtMain (TestMap)

23
extern/ustl/1.5/bvt/bvt14.std vendored Normal file
View File

@@ -0,0 +1,23 @@
There are 31 days in january.
There are 30 days in september.
There are 31 days in december.
may found at index 8
Alphabetical listing:
april has 30 days.
august has 31 days.
december has 31 days.
february has 28 days.
january has 31 days.
july has 31 days.
june has 30 days.
march has 31 days.
may has 31 days.
november has 30 days.
october has 31 days.
september has 30 days.
After erasing may:
april august december february january july june march november october september
After erasing months 2, 3, 4, and the last one:
april january july june march may november october
After inserting frobuary,42:
april august december february frobuary january july june march may november october september

57
extern/ustl/1.5/bvt/bvt15.cc vendored Normal file
View File

@@ -0,0 +1,57 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
typedef multimap<int,string> empmap_t;
typedef empmap_t::const_iterator citer_t;
void PrintEntries (citer_t first, citer_t last)
{
for (citer_t i = first; i < last; ++ i)
cout << i->second << "\t- $" << i->first << endl;
}
inline void PrintEntries (const empmap_t& m) { PrintEntries (m.begin(), m.end()); }
void TestMultiMap (void)
{
empmap_t employees;
employees.insert (make_pair (27000, string("Dave")));
employees.insert (make_pair (27000, string("Jim")));
employees.insert (make_pair (99000, string("BigBoss")));
employees.insert (make_pair (47000, string("Gail")));
employees.insert (make_pair (15000, string("Dumb")));
employees.insert (make_pair (47000, string("Barbara")));
employees.insert (make_pair (47000, string("Mary")));
cout << "As-inserted listing:\n";
PrintEntries (employees);
cout << "Alphabetical listing:\n";
sort (employees);
PrintEntries (employees);
empmap_t::range_t middles = employees.equal_range (47000);
cout << "Employees making $" << middles.first->first << ":";
empmap_t::const_iterator i;
for (i = middles.first; i < middles.second; ++ i)
cout << " " << i->second;
cout << endl;
cout << employees.find(27000)->second << " makes $27000\n";
cout << "There are " << employees.count (27000) << " low-paid employees\n";
cout << "Firing all low-paid employees:\n";
employees.erase (27000);
PrintEntries (employees);
cout << "Firing dumb employees:\n";
employees.erase (employees.begin(), employees.begin() + 1);
PrintEntries (employees);
}
StdBvtMain (TestMultiMap)

30
extern/ustl/1.5/bvt/bvt15.std vendored Normal file
View File

@@ -0,0 +1,30 @@
As-inserted listing:
Dumb - $15000
Dave - $27000
Jim - $27000
Gail - $47000
Barbara - $47000
Mary - $47000
BigBoss - $99000
Alphabetical listing:
Dumb - $15000
Dave - $27000
Jim - $27000
Barbara - $47000
Gail - $47000
Mary - $47000
BigBoss - $99000
Employees making $47000: Barbara Gail Mary
Dave makes $27000
There are 2 low-paid employees
Firing all low-paid employees:
Dumb - $15000
Barbara - $47000
Gail - $47000
Mary - $47000
BigBoss - $99000
Firing dumb employees:
Barbara - $47000
Gail - $47000
Mary - $47000
BigBoss - $99000

86
extern/ustl/1.5/bvt/bvt16.cc vendored Normal file
View File

@@ -0,0 +1,86 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
static void Widen (const string& str, vector<wchar_t>& result)
{
result.clear();
result.resize (str.length());
copy (str.utf8_begin(), str.utf8_end(), result.begin());
}
static void DumpWchars (const vector<wchar_t>& v)
{
foreach (vector<wchar_t>::const_iterator, i, v)
cout.format (" %u", uint32_t(*i));
}
void TestUTF8 (void)
{
cout << "Generating Unicode characters ";
vector<wchar_t> srcChars;
srcChars.resize (0xFFFF);
iota (srcChars.begin(), srcChars.end(), 0);
cout.format ("%zu - %zu\n", size_t(srcChars[0]), size_t(srcChars.back()));
cout << "Encoding to utf8.\n";
string encoded;
encoded.reserve (srcChars.size() * 4);
copy (srcChars, utf8out (back_inserter(encoded)));
static const char c_ProperEncoding[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
if (encoded.compare (encoded.begin(), encoded.begin() + VectorSize(c_ProperEncoding), VectorRange(c_ProperEncoding))) {
cout << "Encoding failed: ";
for (string::const_iterator i = encoded.begin(); i != encoded.begin() + VectorSize(c_ProperEncoding); ++ i)
cout << uint32_t(*i);
cout << endl;
}
cout << "Decoding back.\n";
vector<wchar_t> decChars;
Widen (encoded, decChars);
cout.format ("Comparing.\nsrc = %zu chars, encoded = %zu chars, decoded = %zu\n", srcChars.size(), encoded.size(), decChars.size());
size_t nDiffs = 0;
for (uoff_t i = 0; i < min (srcChars.size(), decChars.size()); ++ i) {
if (srcChars[i] != decChars[i]) {
cout.format ("%u != %u\n", uint32_t(srcChars[i]), uint32_t(decChars[i]));
++ nDiffs;
}
}
cout.format ("%zu differences between src and decoded.\n", nDiffs);
cout << "Testing wide character string::insert\n";
string ws ("1234567890", 10);
ws.insert (ws.find('1'), wchar_t(1234));
static const wchar_t c_WChars[2] = { 3456, 4567 };
ws.insert (ws.find('3'), VectorRange(c_WChars), 2);
ws.insert (ws.find('3'), wchar_t(2345));
ws.insert (ws.size(), wchar_t(5678));
cout.format ("Values[%zu]:", ws.length());
for (string::utf8_iterator j = ws.utf8_begin(); j < ws.utf8_end(); ++ j)
cout.format (" %u", uint32_t(*j));
cout << endl;
cout << "Character offsets:";
for (string::utf8_iterator k = ws.utf8_begin(); k < ws.utf8_end(); ++ k)
cout.format (" %zu", distance (ws.begin(), k.base()));
cout << endl;
cout.format ("Erasing character %zu: ", ws.length() - 1);
ws.erase (ws.wiat(ws.length() - 1), ws.end());
Widen (ws, decChars);
DumpWchars (decChars);
cout << endl;
cout << "Erasing 2 characters after '2': ";
ws.erase (ws.find('2')+1, Utf8Bytes(VectorRange(c_WChars)));
Widen (ws, decChars);
DumpWchars (decChars);
cout << endl;
}
StdBvtMain (TestUTF8)

11
extern/ustl/1.5/bvt/bvt16.std vendored Normal file
View File

@@ -0,0 +1,11 @@
Generating Unicode characters 0 - 65534
Encoding to utf8.
Decoding back.
Comparing.
src = 65535 chars, encoded = 194429 chars, decoded = 65535
0 differences between src and decoded.
Testing wide character string::insert
Values[17]: 1234 49 50 3456 4567 3456 4567 2345 51 52 53 54 55 56 57 48 5678
Character offsets: 0 2 3 4 7 10 13 16 19 20 21 22 23 24 25 26 27
Erasing character 16: 1234 49 50 3456 4567 3456 4567 2345 51 52 53 54 55 56 57 48
Erasing 2 characters after '2': 1234 49 50 3456 4567 2345 51 52 53 54 55 56 57 48

98
extern/ustl/1.5/bvt/bvt17.cc vendored Normal file
View File

@@ -0,0 +1,98 @@
// 011010011001011001011000100100
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
size_t SizeOfSet (const bitset<30>& v)
{
return (stream_size_of (v));
}
void TestBitset (void)
{
bitset<30> bs1;
cout.format ("bitset<%zu> bs1: capacity() = %zu, sizeof() = %zu\n", bs1.size(), bs1.capacity(), sizeof(bs1));
cout << bs1 << endl;
bs1.set();
bs1.set (6, false);
cout << bs1 << endl;
bs1.flip();
cout << bs1 << endl;
bs1.flip();
cout << bs1 << endl;
bs1.reset();
string comment; // See line 0 in this file
cin >> comment >> bs1;
cout << bs1 << endl;
cout.format ("count = %zu\n", bs1.count());
bs1.reset();
cout << bs1;
static const char tf[2][6] = { "false", "true" };
cout.format ("\nany = %s, none = %s, count = %zu\n", tf[bs1.any()], tf[bs1.none()], bs1.count());
bs1.flip();
cout << bs1;
cout.format ("\nany = %s, none = %s, count = %zu\n", tf[bs1.any()], tf[bs1.none()], bs1.count());
bs1.reset();
bs1.set (4);
bs1.set (7);
bs1.set (8);
cout << bs1;
cout.format ("\ntest(7) == %s, [9] = %s, [8] = %s", tf[bs1.test(7)], tf[bs1[9]], tf[bs1[8]]);
cout.format ("\nany = %s, none = %s, count = %zu\n", tf[bs1.any()], tf[bs1.none()], bs1.count());
cout << "~bs1 == " << ~bs1;
cout.format ("\nto_value == 0x%X\n", bs1.to_value());
bitset<70> bs2 ("0101101");
cout.format ("bitset<%zu> bs2: capacity() = %zu, sizeof() = %zu\n", bs2.size(), bs2.capacity(), sizeof(bs2));
cout << bs2;
bs2.set (34, 40, 13);
cout << "\nbs2.set(34,40,13)\n";
cout << bs2;
cout.format ("\nbs2.at(34,40) = %u\n", bs2.at(34,40));
bitset<256> bs3 (0x3030);
cout.format ("bitset<%zu> bs3: capacity() = %zu, sizeof() = %zu\n", bs3.size(), bs3.capacity(), sizeof(bs3));
cout.format ("bs3.to_value() == 0x%X\n", bs3.to_value());
bitset<30> bs4 (bs1);
if (bs1 == bs4)
cout << "bs4 == bs1\n";
bs4 = 0x50505050;
cout << "bs4 = 0x50505050: " << bs4;
bs1 = 0x30303030;
cout << "\nbs1 = 0x30303030: " << bs1;
bs4 &= bs1;
cout << "\nbs4 &= bs1; bs4 = " << bs4;
bs4 = 0x50505050;
bs4 &= bs1;
cout << "\nbs4 & bs1; bs4 = " << bs4;
bs4 = 0x50505050;
bs4 |= bs1;
cout << "\nbs4 |= bs1; bs4 = " << bs4;
bs4 = 0x50505050;
bs4 = bs4 | bs1;
cout << "\nbs4 | bs1; bs4 = " << bs4;
bs4 = 0x50505050;
bs4 ^= bs1;
cout << "\nbs4 ^= bs1; bs4 = " << bs4;
bs4 = 0x50505050;
bs4 = bs4 ^ 0x30303030;
cout << "\nbs4 ^ bs1; bs4 = " << bs4;
memblock b (stream_size_of (bs4));
ostream os (b);
os << bs4;
istream is (b);
bs4 = 0;
is >> bs4;
cout.format ("\nstream[%zu]; bs4 = ", b.size());
cout << bs4 << endl;
}
StdBvtMain (TestBitset)

33
extern/ustl/1.5/bvt/bvt17.std vendored Normal file
View File

@@ -0,0 +1,33 @@
bitset<30> bs1: capacity() = 32, sizeof() = 4
000000000000000000000000000000
111111111111111111111110111111
000000000000000000000001000000
111111111111111111111110111111
011010011001011001011000100100
count = 13
000000000000000000000000000000
any = false, none = true, count = 0
111111111111111111111111111111
any = true, none = false, count = 32
000000000000000000000110010000
test(7) == true, [9] = false, [8] = true
any = true, none = false, count = 3
~bs1 == 111111111111111111111001101111
to_value == 0x190
bitset<70> bs2: capacity() = 96, sizeof() = 12
0000000000000000000000000000000000000000000000000000000000000000101101
bs2.set(34,40,13)
0000000000000000000000000000000011010000000000000000000000000000101101
bs2.at(34,40) = 13
bitset<256> bs3: capacity() = 256, sizeof() = 32
bs3.to_value() == 0x3030
bs4 == bs1
bs4 = 0x50505050: 010000010100000101000001010000
bs1 = 0x30303030: 110000001100000011000000110000
bs4 &= bs1; bs4 = 010000000100000001000000010000
bs4 & bs1; bs4 = 010000000100000001000000010000
bs4 |= bs1; bs4 = 110000011100000111000001110000
bs4 | bs1; bs4 = 110000011100000111000001110000
bs4 ^= bs1; bs4 = 100000011000000110000001100000
bs4 ^ bs1; bs4 = 100000011000000110000001100000
stream[4]; bs4 = 100000011000000110000001100000

77
extern/ustl/1.5/bvt/bvt18.cc vendored Normal file
View File

@@ -0,0 +1,77 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
template <size_t N, typename T>
void TestTuple (const char* ctrType)
{
cout << "================================================" << endl;
cout << "Testing " << ctrType << endl;
cout << "================================================" << endl;
assert (N <= 8);
T pt1v[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
T increment;
tuple<N,T> pt1 (pt1v);
tuple<N,T> pt2 (5, 6, 7, 8);
increment = pt1v[2];
cout << "pt1:\t\t\tsize = " << pt1.size() << ", value = " << pt1 << endl;
cout << "pt2:\t\t\t" << pt2 << endl;
iota (pt2.begin(), pt2.end(), 10);
cout << "pt2:\t\t\t" << pt2 << endl;
pt1 *= increment;
cout << "pt1 *= 3:\t\t" << pt1 << endl;
pt1 /= increment;
cout << "pt1 /= 3:\t\t" << pt1 << endl;
pt1 += increment;
cout << "pt1 += 3:\t\t" << pt1 << endl;
pt1 -= increment;
cout << "pt1 -= 3:\t\t" << pt1 << endl;
pt1 *= pt2;
cout << "pt1 *= pt2:\t\t" << pt1 << endl;
pt1 /= pt2;
cout << "pt1 /= pt2:\t\t" << pt1 << endl;
pt1 += pt2;
cout << "pt1 += pt2:\t\t" << pt1 << endl;
pt1 -= pt2;
cout << "pt1 -= pt2:\t\t" << pt1 << endl;
pt1 = pt1 * pt2;
cout << "pt1 = pt1 * pt2:\t" << pt1 << endl;
pt1 = pt1 / pt2;
cout << "pt1 = pt1 / pt2:\t" << pt1 << endl;
pt1 = pt1 + pt2;
cout << "pt1 = pt1 + pt2:\t" << pt1 << endl;
pt1 = pt1 - pt2;
cout << "pt1 = pt1 - pt2:\t" << pt1 << endl;
}
void TestIntegralTuples (void)
{
TestTuple<4,float> ("tuple<4,float>");
TestTuple<2,float> ("tuple<2,float>");
TestTuple<4,int32_t> ("tuple<4,int32_t>");
TestTuple<4,uint32_t> ("tuple<4,uint32_t>");
TestTuple<2,int32_t> ("tuple<2,int32_t>");
TestTuple<2,uint32_t> ("tuple<2,uint32_t>");
TestTuple<4,int16_t> ("tuple<4,int16_t>");
TestTuple<4,uint16_t> ("tuple<4,uint16_t>");
TestTuple<8,int8_t> ("tuple<8,int8_t>");
TestTuple<8,uint8_t> ("tuple<8,uint8_t>");
cout << "================================================" << endl;
cout << "Testing tuple<3,string>" << endl;
cout << "================================================" << endl;
tuple<3, string> strv;
strv[0] = "str0";
strv[1] = "str1";
strv[2] = "str2";
cout << "str: " << strv << endl;
}
StdBvtMain (TestIntegralTuples)

184
extern/ustl/1.5/bvt/bvt18.std vendored Normal file
View File

@@ -0,0 +1,184 @@
================================================
Testing tuple<4,float>
================================================
pt1: size = 4, value = (1.00,2.00,3.00,4.00)
pt2: (5.00,6.00,7.00,8.00)
pt2: (10.00,11.00,12.00,13.00)
pt1 *= 3: (3.00,6.00,9.00,12.00)
pt1 /= 3: (1.00,2.00,3.00,4.00)
pt1 += 3: (4.00,5.00,6.00,7.00)
pt1 -= 3: (1.00,2.00,3.00,4.00)
pt1 *= pt2: (10.00,22.00,36.00,52.00)
pt1 /= pt2: (1.00,2.00,3.00,4.00)
pt1 += pt2: (11.00,13.00,15.00,17.00)
pt1 -= pt2: (1.00,2.00,3.00,4.00)
pt1 = pt1 * pt2: (10.00,22.00,36.00,52.00)
pt1 = pt1 / pt2: (1.00,2.00,3.00,4.00)
pt1 = pt1 + pt2: (11.00,13.00,15.00,17.00)
pt1 = pt1 - pt2: (1.00,2.00,3.00,4.00)
================================================
Testing tuple<2,float>
================================================
pt1: size = 2, value = (1.00,2.00)
pt2: (5.00,6.00)
pt2: (10.00,11.00)
pt1 *= 3: (3.00,6.00)
pt1 /= 3: (1.00,2.00)
pt1 += 3: (4.00,5.00)
pt1 -= 3: (1.00,2.00)
pt1 *= pt2: (10.00,22.00)
pt1 /= pt2: (1.00,2.00)
pt1 += pt2: (11.00,13.00)
pt1 -= pt2: (1.00,2.00)
pt1 = pt1 * pt2: (10.00,22.00)
pt1 = pt1 / pt2: (1.00,2.00)
pt1 = pt1 + pt2: (11.00,13.00)
pt1 = pt1 - pt2: (1.00,2.00)
================================================
Testing tuple<4,int32_t>
================================================
pt1: size = 4, value = (1,2,3,4)
pt2: (5,6,7,8)
pt2: (10,11,12,13)
pt1 *= 3: (3,6,9,12)
pt1 /= 3: (1,2,3,4)
pt1 += 3: (4,5,6,7)
pt1 -= 3: (1,2,3,4)
pt1 *= pt2: (10,22,36,52)
pt1 /= pt2: (1,2,3,4)
pt1 += pt2: (11,13,15,17)
pt1 -= pt2: (1,2,3,4)
pt1 = pt1 * pt2: (10,22,36,52)
pt1 = pt1 / pt2: (1,2,3,4)
pt1 = pt1 + pt2: (11,13,15,17)
pt1 = pt1 - pt2: (1,2,3,4)
================================================
Testing tuple<4,uint32_t>
================================================
pt1: size = 4, value = (1,2,3,4)
pt2: (5,6,7,8)
pt2: (10,11,12,13)
pt1 *= 3: (3,6,9,12)
pt1 /= 3: (1,2,3,4)
pt1 += 3: (4,5,6,7)
pt1 -= 3: (1,2,3,4)
pt1 *= pt2: (10,22,36,52)
pt1 /= pt2: (1,2,3,4)
pt1 += pt2: (11,13,15,17)
pt1 -= pt2: (1,2,3,4)
pt1 = pt1 * pt2: (10,22,36,52)
pt1 = pt1 / pt2: (1,2,3,4)
pt1 = pt1 + pt2: (11,13,15,17)
pt1 = pt1 - pt2: (1,2,3,4)
================================================
Testing tuple<2,int32_t>
================================================
pt1: size = 2, value = (1,2)
pt2: (5,6)
pt2: (10,11)
pt1 *= 3: (3,6)
pt1 /= 3: (1,2)
pt1 += 3: (4,5)
pt1 -= 3: (1,2)
pt1 *= pt2: (10,22)
pt1 /= pt2: (1,2)
pt1 += pt2: (11,13)
pt1 -= pt2: (1,2)
pt1 = pt1 * pt2: (10,22)
pt1 = pt1 / pt2: (1,2)
pt1 = pt1 + pt2: (11,13)
pt1 = pt1 - pt2: (1,2)
================================================
Testing tuple<2,uint32_t>
================================================
pt1: size = 2, value = (1,2)
pt2: (5,6)
pt2: (10,11)
pt1 *= 3: (3,6)
pt1 /= 3: (1,2)
pt1 += 3: (4,5)
pt1 -= 3: (1,2)
pt1 *= pt2: (10,22)
pt1 /= pt2: (1,2)
pt1 += pt2: (11,13)
pt1 -= pt2: (1,2)
pt1 = pt1 * pt2: (10,22)
pt1 = pt1 / pt2: (1,2)
pt1 = pt1 + pt2: (11,13)
pt1 = pt1 - pt2: (1,2)
================================================
Testing tuple<4,int16_t>
================================================
pt1: size = 4, value = (1,2,3,4)
pt2: (5,6,7,8)
pt2: (10,11,12,13)
pt1 *= 3: (3,6,9,12)
pt1 /= 3: (1,2,3,4)
pt1 += 3: (4,5,6,7)
pt1 -= 3: (1,2,3,4)
pt1 *= pt2: (10,22,36,52)
pt1 /= pt2: (1,2,3,4)
pt1 += pt2: (11,13,15,17)
pt1 -= pt2: (1,2,3,4)
pt1 = pt1 * pt2: (10,22,36,52)
pt1 = pt1 / pt2: (1,2,3,4)
pt1 = pt1 + pt2: (11,13,15,17)
pt1 = pt1 - pt2: (1,2,3,4)
================================================
Testing tuple<4,uint16_t>
================================================
pt1: size = 4, value = (1,2,3,4)
pt2: (5,6,7,8)
pt2: (10,11,12,13)
pt1 *= 3: (3,6,9,12)
pt1 /= 3: (1,2,3,4)
pt1 += 3: (4,5,6,7)
pt1 -= 3: (1,2,3,4)
pt1 *= pt2: (10,22,36,52)
pt1 /= pt2: (1,2,3,4)
pt1 += pt2: (11,13,15,17)
pt1 -= pt2: (1,2,3,4)
pt1 = pt1 * pt2: (10,22,36,52)
pt1 = pt1 / pt2: (1,2,3,4)
pt1 = pt1 + pt2: (11,13,15,17)
pt1 = pt1 - pt2: (1,2,3,4)
================================================
Testing tuple<8,int8_t>
================================================
pt1: size = 8, value = (1,2,3,4,5,6,7,8)
pt2: (5,6,7,8,0,0,0,0)
pt2: (10,11,12,13,14,15,16,17)
pt1 *= 3: (3,6,9,12,15,18,21,24)
pt1 /= 3: (1,2,3,4,5,6,7,8)
pt1 += 3: (4,5,6,7,8,9,10,11)
pt1 -= 3: (1,2,3,4,5,6,7,8)
pt1 *= pt2: (10,22,'$','4','F','Z','p',-120)
pt1 /= pt2: (1,2,3,4,5,6,7,-7)
pt1 += pt2: (11,13,15,17,19,21,23,10)
pt1 -= pt2: (1,2,3,4,5,6,7,-7)
pt1 = pt1 * pt2: (10,22,'$','4','F','Z','p',-119)
pt1 = pt1 / pt2: (1,2,3,4,5,6,7,-7)
pt1 = pt1 + pt2: (11,13,15,17,19,21,23,10)
pt1 = pt1 - pt2: (1,2,3,4,5,6,7,-7)
================================================
Testing tuple<8,uint8_t>
================================================
pt1: size = 8, value = (1,2,3,4,5,6,7,8)
pt2: (5,6,7,8,0,0,0,0)
pt2: (10,11,12,13,14,15,16,17)
pt1 *= 3: (3,6,9,12,15,18,21,24)
pt1 /= 3: (1,2,3,4,5,6,7,8)
pt1 += 3: (4,5,6,7,8,9,10,11)
pt1 -= 3: (1,2,3,4,5,6,7,8)
pt1 *= pt2: (10,22,'$','4','F','Z','p',136)
pt1 /= pt2: (1,2,3,4,5,6,7,8)
pt1 += pt2: (11,13,15,17,19,21,23,25)
pt1 -= pt2: (1,2,3,4,5,6,7,8)
pt1 = pt1 * pt2: (10,22,'$','4','F','Z','p',136)
pt1 = pt1 / pt2: (1,2,3,4,5,6,7,8)
pt1 = pt1 + pt2: (11,13,15,17,19,21,23,25)
pt1 = pt1 - pt2: (1,2,3,4,5,6,7,8)
================================================
Testing tuple<3,string>
================================================
str: (str0,str1,str2)

33
extern/ustl/1.5/bvt/bvt19.cc vendored Normal file
View File

@@ -0,0 +1,33 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
void TestEnumArithmetic (void)
{
enum EFruit {
apple,
orange,
plum,
peach,
pear,
nectarine,
NFruits
};
const char* fruits [NFruits + 1] = {
"apple",
"orange",
"plum",
"peach",
"pear",
"nectarine",
"invalid"
};
cout << "Testing operator+" << endl;
cout << "apple = " << fruits [apple] << endl;
cout << "peach = " << fruits [apple + 3] << endl;
}
StdBvtMain (TestEnumArithmetic)

3
extern/ustl/1.5/bvt/bvt19.std vendored Normal file
View File

@@ -0,0 +1,3 @@
Testing operator+
apple = apple
peach = peach

33
extern/ustl/1.5/bvt/bvt20.cc vendored Normal file
View File

@@ -0,0 +1,33 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
void TestStackAndQueue (void)
{
stack<int> s;
cout << "Testing stack: ";
for (size_t i = 0; i < 5; ++ i)
s.push (1 + i);
cout << "popping: ";
for (size_t j = 0; j < 5; ++ j) {
cout << s.top() << ' ';
s.pop();
}
cout << endl;
queue<int> q;
cout << "Testing queue: ";
for (size_t k = 0; k < 5; ++ k)
q.push (1 + k);
cout << "popping: ";
for (size_t l = 0; l < 5; ++ l) {
cout << q.front() << ' ';
q.pop();
}
cout << endl;
}
StdBvtMain (TestStackAndQueue)

2
extern/ustl/1.5/bvt/bvt20.std vendored Normal file
View File

@@ -0,0 +1,2 @@
Testing stack: popping: 5 4 3 2 1
Testing queue: popping: 1 2 3 4 5

108
extern/ustl/1.5/bvt/bvt21.cc vendored Normal file
View File

@@ -0,0 +1,108 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
template <typename T>
void TestBswap (T v)
{
const T vsw (bswap(v));
#if BYTE_ORDER == LITTLE_ENDIAN
const T vbe (vsw), vle (v);
#elif BYTE_ORDER == BIG_ENDIAN
const T vbe (v), vle (vsw);
#endif
static const char ok[2][4] = { "bad", "ok" };
cout << "bswap(" << v << ") = " << vsw << endl;
cout << "le_to_native(" << v << ") = " << ok[le_to_native(vle) == v] << endl;
cout << "native_to_le(" << v << ") = " << ok[native_to_le(v) == vle] << endl;
cout << "be_to_native(" << v << ") = " << ok[be_to_native(vbe) == v] << endl;
cout << "native_to_be(" << v << ") = " << ok[native_to_be(v) == vbe] << endl;
}
void TestUtility (void)
{
cout << "DivRU(13,5) = " << DivRU(13,5) << endl;
cout << "DivRU(15,5) = " << DivRU(15,5) << endl;
cout << "DivRU(-12,5) = " << DivRU(-12,5) << endl;
cout << endl;
cout << "Align(5) = " << Align(5) << endl;
cout << "Align(5,2) = " << Align(5,2) << endl;
cout << "Align(17,7) = " << Align(17,7) << endl;
cout << "Align(14,7) = " << Align(14,7) << endl;
cout << endl;
cout << "NextPow2(0) = " << NextPow2(0) << endl;
cout << "NextPow2(1) = " << NextPow2(1) << endl;
cout << "NextPow2(4) = " << NextPow2(4) << endl;
cout << "NextPow2(3827) = " << NextPow2(3827) << endl;
cout << "NextPow2(0xFFFFFFF0) = " << NextPow2(0xFFFFFFF0) << endl;
cout << endl;
cout << "advance(42,0) = " << advance(42,0) << endl;
cout << "advance(42,3) = " << advance(42,3) << endl;
const void *cvp = (const void*) 0x1234;
void* vp = (void*) 0x4321;
cout << ios::hex;
cout << "cvp = " << cvp << endl;
cout << "vp = " << vp << endl;
cout << "advance(cvp,5) = " << advance(cvp,5) << endl;
cout << "advance(vp,4) = " << advance(vp,4) << endl;
cout << "distance(cvp,vp) = " << distance(cvp,vp) << endl;
cout << "abs_distance(vp,cvp) = " << abs_distance(vp,cvp) << endl;
cout << ios::dec << endl;
const int32_t c_Numbers[] = { 1, 2, 3, 4, 5 };
const int32_t c_Empty[] = { };
cout << "size_of_elements(3, c_Numbers) = " << size_of_elements(3, c_Numbers) << endl;
cout << "VectorSize(c_Numbers[5]) = " << VectorSize(c_Numbers) << endl;
cout << "VectorSize(c_Numbers[0]) = " << VectorSize(c_Empty) << endl;
cout << endl;
cout << "BitsInType(uint32_t) = " << BitsInType(uint32_t) << endl;
cout << "BitsInType(int16_t) = " << BitsInType(int16_t) << endl;
cout << "BitsInType(char) = " << BitsInType(char) << endl;
cout << ios::hex << endl;
cout << "BitMask(uint32_t,12) = " << BitMask(uint32_t,12) << endl;
cout << "BitMask(uint16_t,1) = " << BitMask(uint16_t,1) << endl;
cout << "BitMask(uint8_t,8) = " << BitMask(uint8_t,8) << endl;
cout << "BitMask(uint16_t,0) = " << BitMask(uint16_t,0) << endl;
cout << endl;
uint16_t packed16 = 0xCDCD;
pack_type (uint8_t(0x42), packed16);
cout << "pack_type(uint8_t, uint16_t) = " << packed16 << endl;
uint32_t packed32 = 0xCDCDCDCD;
pack_type (uint8_t(0x42), packed32);
cout << "pack_type(uint8_t, uint32_t) = " << packed32 << endl;
packed32 = 0xCDCDCDCD;
pack_type (uint16_t(0x4243), packed32);
cout << "pack_type(uint16_t, uint32_t) = " << packed32 << endl;
#if HAVE_INT64_T
uint64_t packed64 = UINT64_C(0x123456789ABCDEF0);
pack_type (uint8_t(0x42), packed64);
cout << "pack_type(uint8_t, uint64_t) = " << packed64 << endl;
packed64 = UINT64_C(0x123456789ABCDEF0);
pack_type (uint32_t(0x42434445), packed64);
cout << "pack_type(uint32_t, uint64_t) = " << packed64 << endl;
#else
cout << "No 64bit types available on this platform" << endl;
#endif
cout << endl;
TestBswap (uint16_t (0x1234));
TestBswap (uint32_t (0x12345678));
#if HAVE_INT64_T
TestBswap (uint64_t (UINT64_C(0x123456789ABCDEF0)));
#else
cout << "No 64bit types available on this platform" << endl;
#endif
cout << ios::dec << endl;
cout << "absv(12) = " << absv(12) << endl;
cout << "absv(-12) = " << absv(-12) << endl;
cout << "sign(12) = " << sign(12) << endl;
cout << "sign(-12) = " << sign(-12) << endl;
cout << "sign(0) = " << sign(0) << endl;
cout << "min(3,4) = " << min(3,4) << endl;
cout << "min(6U,1U) = " << min(6U,1U) << endl;
cout << "max(-3,-6) = " << max(-3,-6) << endl;
cout << "max(-3L,6L) = " << max(-3L,6L) << endl;
}
StdBvtMain (TestUtility)

68
extern/ustl/1.5/bvt/bvt21.std vendored Normal file
View File

@@ -0,0 +1,68 @@
DivRU(13,5) = 3
DivRU(15,5) = 3
DivRU(-12,5) = -3
Align(5) = 8
Align(5,2) = 6
Align(17,7) = 21
Align(14,7) = 14
NextPow2(0) = 1
NextPow2(1) = 2
NextPow2(4) = 4
NextPow2(3827) = 4096
NextPow2(0xFFFFFFF0) = 1
advance(42,0) = 42
advance(42,3) = 45
cvp = 1234
vp = 4321
advance(cvp,5) = 1239
advance(vp,4) = 4325
distance(cvp,vp) = 30ED
abs_distance(vp,cvp) = 30ED
size_of_elements(3, c_Numbers) = 12
VectorSize(c_Numbers[5]) = 5
VectorSize(c_Numbers[0]) = 0
BitsInType(uint32_t) = 32
BitsInType(int16_t) = 16
BitsInType(char) = 8
BitMask(uint32_t,12) = FFF
BitMask(uint16_t,1) = 1
BitMask(uint8_t,8) = FF
BitMask(uint16_t,0) = 0
pack_type(uint8_t, uint16_t) = 4242
pack_type(uint8_t, uint32_t) = 42424242
pack_type(uint16_t, uint32_t) = 42434243
pack_type(uint8_t, uint64_t) = 4242424242424242
pack_type(uint32_t, uint64_t) = 4243444542434445
bswap(1234) = 3412
le_to_native(1234) = ok
native_to_le(1234) = ok
be_to_native(1234) = ok
native_to_be(1234) = ok
bswap(12345678) = 78563412
le_to_native(12345678) = ok
native_to_le(12345678) = ok
be_to_native(12345678) = ok
native_to_be(12345678) = ok
bswap(123456789ABCDEF0) = F0DEBC9A78563412
le_to_native(123456789ABCDEF0) = ok
native_to_le(123456789ABCDEF0) = ok
be_to_native(123456789ABCDEF0) = ok
native_to_be(123456789ABCDEF0) = ok
absv(12) = 12
absv(-12) = 12
sign(12) = 1
sign(-12) = -1
sign(0) = 0
min(3,4) = 3
min(6U,1U) = 1
max(-3,-6) = -3
max(-3L,6L) = 6

71
extern/ustl/1.5/bvt/bvt22.cc vendored Normal file
View File

@@ -0,0 +1,71 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
template <size_t NX, size_t NY, typename T>
void TestMatrix (void)
{
matrix<NX,NY,T> m1, m2;
load_identity (m1);
cout << "load_identity(m1)"
"\n m1 = " << m1;
m2 = m1;
cout << "\nm1 = m2"
"\n m2 = " << m2;
m1 += m2;
cout << "\nm1 += m2"
"\n m1 = " << m1;
m1 /= 2;
cout << "\nm1 /= 2"
"\n m1 = " << m1;
m1 = m1 * m2;
cout << "\nm1 = m1 * m2"
"\n m1 = " << m1;
m1 += 3;
cout << "\nm1 += 3"
"\n m1 = " << m1;
load_identity (m2);
m2 *= 2;
m1 = m1 * m2;
cout << "\nm1 *= I(2)";
cout << "\n m1 = " << m1;
iota (m1.begin(), m1.end(), 1);
cout << "\nm1 = iota(1)"
"\n m1 = " << m1;
cout << "\n m1 row [1] = " << m1.row(1);
cout << "\n m1 column [2] = " << m1.column(2);
m1 = m1 * m2;
cout << "\nm1 *= I(2)"
"\n m1 = " << m1;
typename matrix<NX,NY,T>::column_type v, vt;
iota (v.begin(), v.end(), 1);
cout << "\nv = iota(1)"
"\n v = " << v;
load_identity (m2);
m2 *= 2;
for (uoff_t y = 0; y < NY - 1; ++ y)
m2[NY - 1][y] = 1;
cout << "\nm2 = I(2) + T(1)"
"\n m2 = " << m2;
vt = v * m2;
cout << "\nvt = v * m2"
"\n vt = " << vt << endl;
}
void TestMatrixAlgorithms (void)
{
cout << "========================================\n"
"Testing 4x4 int matrix:\n"
"========================================\n";
TestMatrix<4,4,int>();
cout << "========================================\n"
"Testing 4x4 float matrix:\n"
"========================================\n";
cout.set_precision (1);
TestMatrix<4,4,float>();
}
StdBvtMain (TestMatrixAlgorithms)

58
extern/ustl/1.5/bvt/bvt22.std vendored Normal file
View File

@@ -0,0 +1,58 @@
========================================
Testing 4x4 int matrix:
========================================
load_identity(m1)
m1 = ((1,0,0,0)(0,1,0,0)(0,0,1,0)(0,0,0,1))
m1 = m2
m2 = ((1,0,0,0)(0,1,0,0)(0,0,1,0)(0,0,0,1))
m1 += m2
m1 = ((2,0,0,0)(0,2,0,0)(0,0,2,0)(0,0,0,2))
m1 /= 2
m1 = ((1,0,0,0)(0,1,0,0)(0,0,1,0)(0,0,0,1))
m1 = m1 * m2
m1 = ((1,0,0,0)(0,1,0,0)(0,0,1,0)(0,0,0,1))
m1 += 3
m1 = ((4,3,3,3)(3,4,3,3)(3,3,4,3)(3,3,3,4))
m1 *= I(2)
m1 = ((8,6,6,6)(6,8,6,6)(6,6,8,6)(6,6,6,8))
m1 = iota(1)
m1 = ((1,2,3,4)(5,6,7,8)(9,10,11,12)(13,14,15,16))
m1 row [1] = (5,6,7,8)
m1 column [2] = (3,7,11,15)
m1 *= I(2)
m1 = ((2,4,6,8)(10,12,14,16)(18,20,22,24)(26,28,30,32))
v = iota(1)
v = (1,2,3,4)
m2 = I(2) + T(1)
m2 = ((2,0,0,0)(0,2,0,0)(0,0,2,0)(1,1,1,2))
vt = v * m2
vt = (6,8,10,8)
========================================
Testing 4x4 float matrix:
========================================
load_identity(m1)
m1 = ((1.0,0.0,0.0,0.0)(0.0,1.0,0.0,0.0)(0.0,0.0,1.0,0.0)(0.0,0.0,0.0,1.0))
m1 = m2
m2 = ((1.0,0.0,0.0,0.0)(0.0,1.0,0.0,0.0)(0.0,0.0,1.0,0.0)(0.0,0.0,0.0,1.0))
m1 += m2
m1 = ((2.0,0.0,0.0,0.0)(0.0,2.0,0.0,0.0)(0.0,0.0,2.0,0.0)(0.0,0.0,0.0,2.0))
m1 /= 2
m1 = ((1.0,0.0,0.0,0.0)(0.0,1.0,0.0,0.0)(0.0,0.0,1.0,0.0)(0.0,0.0,0.0,1.0))
m1 = m1 * m2
m1 = ((1.0,0.0,0.0,0.0)(0.0,1.0,0.0,0.0)(0.0,0.0,1.0,0.0)(0.0,0.0,0.0,1.0))
m1 += 3
m1 = ((4.0,3.0,3.0,3.0)(3.0,4.0,3.0,3.0)(3.0,3.0,4.0,3.0)(3.0,3.0,3.0,4.0))
m1 *= I(2)
m1 = ((8.0,6.0,6.0,6.0)(6.0,8.0,6.0,6.0)(6.0,6.0,8.0,6.0)(6.0,6.0,6.0,8.0))
m1 = iota(1)
m1 = ((1.0,2.0,3.0,4.0)(5.0,6.0,7.0,8.0)(9.0,10.0,11.0,12.0)(13.0,14.0,15.0,16.0))
m1 row [1] = (5.0,6.0,7.0,8.0)
m1 column [2] = (3.0,7.0,11.0,15.0)
m1 *= I(2)
m1 = ((2.0,4.0,6.0,8.0)(10.0,12.0,14.0,16.0)(18.0,20.0,22.0,24.0)(26.0,28.0,30.0,32.0))
v = iota(1)
v = (1.0,2.0,3.0,4.0)
m2 = I(2) + T(1)
m2 = ((2.0,0.0,0.0,0.0)(0.0,2.0,0.0,0.0)(0.0,0.0,2.0,0.0)(1.0,1.0,1.0,2.0))
vt = v * m2
vt = (6.0,8.0,10.0,8.0)

121
extern/ustl/1.5/bvt/bvt23.cc vendored Normal file
View File

@@ -0,0 +1,121 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
using namespace ustl::simd;
template <typename Ctr>
void TestBitwiseOperations (Ctr op1, Ctr op2, const Ctr op3)
{
passign (op3, op2);
pand (op1, op2);
cout << "pand(op1,op2) = " << op2 << endl;
passign (op3, op2);
por (op1, op2);
cout << "por(op1,op2) = " << op2 << endl;
passign (op3, op2);
pxor (op1, op2);
cout << "pxor(op1,op2) = " << op2 << endl;
passign (op3, op2);
pshl (op1, op2);
cout << "pshl(op1,op2) = " << op2 << endl;
passign (op3, op2);
pshr (op1, op2);
cout << "pshr(op1,op2) = " << op2 << endl;
}
template <> inline void TestBitwiseOperations (tuple<2,float>, tuple<2,float>, const tuple<2,float>) {}
template <> inline void TestBitwiseOperations (tuple<4,float>, tuple<4,float>, const tuple<4,float>) {}
template <typename Ctr>
void TestCtr (const char* ctrType)
{
cout << "================================================" << endl;
cout << "Testing " << ctrType << endl;
cout << "================================================" << endl;
Ctr op1, op2, op3;
fill (op1, 2);
iota (op2.begin(), op2.end(), 1);
cout << "op1 = " << op1 << endl;
cout << "op2 = " << op2 << endl;
passign (op2, op3);
cout << "passign(op2,op3) = " << op3 << endl;
padd (op1, op2);
cout << "padd(op1,op2) = " << op2 << endl;
psub (op1, op2);
cout << "psub(op1,op2) = " << op2 << endl;
pmul (op1, op2);
cout << "pmul(op1,op2) = " << op2 << endl;
pdiv (op1, op2);
cout << "pdiv(op1,op2) = " << op2 << endl;
TestBitwiseOperations (op1, op2, op3);
passign (op3, op2);
reverse (op2);
pmin (op3, op2);
cout << "pmin(op3,op2) = " << op2 << endl;
passign (op3, op2);
reverse (op2);
pmax (op3, op2);
cout << "pmax(op3,op2) = " << op2 << endl;
passign (op3, op2);
reverse (op2);
reset_mmx();
pavg (op3, op2);
cout << "pavg(op3,op2) = " << op2 << endl;
reset_mmx();
}
template <typename SrcCtr, typename DstCtr, typename Operation>
void TestConversion (const char* ctrType)
{
cout << "================================================" << endl;
cout << "Testing " << ctrType << endl;
cout << "================================================" << endl;
SrcCtr src;
DstCtr dst;
typedef typename SrcCtr::value_type srcval_t;
iota (src.begin(), src.end(), srcval_t(-1.4));
pconvert (src, dst, Operation());
cout << src << " -> " << dst << endl;
iota (src.begin(), src.end(), srcval_t(-1.5));
pconvert (src, dst, Operation());
cout << src << " -> " << dst << endl;
iota (src.begin(), src.end(), srcval_t(-1.7));
pconvert (src, dst, Operation());
cout << src << " -> " << dst << endl;
}
void TestSimdAlgorithms (void)
{
TestCtr<tuple<8,uint8_t> >("uint8_t[8]");
TestCtr<tuple<8,int8_t> >("int8_t[8]");
TestCtr<tuple<4,uint16_t> >("uint16_t[4]");
TestCtr<tuple<4,int16_t> >("int16_t[4]");
TestCtr<tuple<2,uint32_t> >("uint32_t[2]");
TestCtr<tuple<2,int32_t> >("int32_t[2]");
#if HAVE_INT64_T
TestCtr<tuple<1,uint64_t> >("uint64_t[1]");
TestCtr<tuple<1,int64_t> >("int64_t[1]");
#else
cout << "No 64bit types available on this platform" << endl;
#endif
TestCtr<tuple<2,float> >("float[2]");
TestCtr<tuple<4,float> >("float[4]");
TestCtr<tuple<7,uint32_t> >("uint32_t[7]");
#if HAVE_MATH_H
#define CVT_TEST(size,src,dest,op) \
TestConversion<tuple<size,src>, tuple<size,dest>, op<src,dest> > (#op " " #src " -> " #dest)
CVT_TEST(4,int32_t,float,fround);
CVT_TEST(4,int32_t,double,fround);
CVT_TEST(4,float,int32_t,fround);
CVT_TEST(4,double,int32_t,fround);
CVT_TEST(4,float,int32_t,fcast);
#else
cout << "CAN'T TEST: math.h functions are not available on this platform." << endl;
#endif
}
StdBvtMain (TestSimdAlgorithms)

218
extern/ustl/1.5/bvt/bvt23.std vendored Normal file
View File

@@ -0,0 +1,218 @@
================================================
Testing uint8_t[8]
================================================
op1 = (2,2,2,2,2,2,2,2)
op2 = (1,2,3,4,5,6,7,8)
passign(op2,op3) = (1,2,3,4,5,6,7,8)
padd(op1,op2) = (3,4,5,6,7,8,9,10)
psub(op1,op2) = (1,2,3,4,5,6,7,8)
pmul(op1,op2) = (2,4,6,8,10,12,14,16)
pdiv(op1,op2) = (1,2,3,4,5,6,7,8)
pand(op1,op2) = (0,2,2,0,0,2,2,0)
por(op1,op2) = (3,2,3,6,7,6,7,10)
pxor(op1,op2) = (3,0,1,6,7,4,5,10)
pshl(op1,op2) = (4,8,12,16,20,24,28,' ')
pshr(op1,op2) = (0,0,0,1,1,1,1,2)
pmin(op3,op2) = (1,2,3,4,4,3,2,1)
pmax(op3,op2) = (8,7,6,5,5,6,7,8)
pavg(op3,op2) = (5,5,5,5,5,5,5,5)
================================================
Testing int8_t[8]
================================================
op1 = (2,2,2,2,2,2,2,2)
op2 = (1,2,3,4,5,6,7,8)
passign(op2,op3) = (1,2,3,4,5,6,7,8)
padd(op1,op2) = (3,4,5,6,7,8,9,10)
psub(op1,op2) = (1,2,3,4,5,6,7,8)
pmul(op1,op2) = (2,4,6,8,10,12,14,16)
pdiv(op1,op2) = (1,2,3,4,5,6,7,8)
pand(op1,op2) = (0,2,2,0,0,2,2,0)
por(op1,op2) = (3,2,3,6,7,6,7,10)
pxor(op1,op2) = (3,0,1,6,7,4,5,10)
pshl(op1,op2) = (4,8,12,16,20,24,28,' ')
pshr(op1,op2) = (0,0,0,1,1,1,1,2)
pmin(op3,op2) = (1,2,3,4,4,3,2,1)
pmax(op3,op2) = (8,7,6,5,5,6,7,8)
pavg(op3,op2) = (5,5,5,5,5,5,5,5)
================================================
Testing uint16_t[4]
================================================
op1 = (2,2,2,2)
op2 = (1,2,3,4)
passign(op2,op3) = (1,2,3,4)
padd(op1,op2) = (3,4,5,6)
psub(op1,op2) = (1,2,3,4)
pmul(op1,op2) = (2,4,6,8)
pdiv(op1,op2) = (1,2,3,4)
pand(op1,op2) = (0,2,2,0)
por(op1,op2) = (3,2,3,6)
pxor(op1,op2) = (3,0,1,6)
pshl(op1,op2) = (4,8,12,16)
pshr(op1,op2) = (0,0,0,1)
pmin(op3,op2) = (1,2,2,1)
pmax(op3,op2) = (4,3,3,4)
pavg(op3,op2) = (3,3,3,3)
================================================
Testing int16_t[4]
================================================
op1 = (2,2,2,2)
op2 = (1,2,3,4)
passign(op2,op3) = (1,2,3,4)
padd(op1,op2) = (3,4,5,6)
psub(op1,op2) = (1,2,3,4)
pmul(op1,op2) = (2,4,6,8)
pdiv(op1,op2) = (1,2,3,4)
pand(op1,op2) = (0,2,2,0)
por(op1,op2) = (3,2,3,6)
pxor(op1,op2) = (3,0,1,6)
pshl(op1,op2) = (4,8,12,16)
pshr(op1,op2) = (0,0,0,1)
pmin(op3,op2) = (1,2,2,1)
pmax(op3,op2) = (4,3,3,4)
pavg(op3,op2) = (3,3,3,3)
================================================
Testing uint32_t[2]
================================================
op1 = (2,2)
op2 = (1,2)
passign(op2,op3) = (1,2)
padd(op1,op2) = (3,4)
psub(op1,op2) = (1,2)
pmul(op1,op2) = (2,4)
pdiv(op1,op2) = (1,2)
pand(op1,op2) = (0,2)
por(op1,op2) = (3,2)
pxor(op1,op2) = (3,0)
pshl(op1,op2) = (4,8)
pshr(op1,op2) = (0,0)
pmin(op3,op2) = (1,1)
pmax(op3,op2) = (2,2)
pavg(op3,op2) = (2,2)
================================================
Testing int32_t[2]
================================================
op1 = (2,2)
op2 = (1,2)
passign(op2,op3) = (1,2)
padd(op1,op2) = (3,4)
psub(op1,op2) = (1,2)
pmul(op1,op2) = (2,4)
pdiv(op1,op2) = (1,2)
pand(op1,op2) = (0,2)
por(op1,op2) = (3,2)
pxor(op1,op2) = (3,0)
pshl(op1,op2) = (4,8)
pshr(op1,op2) = (0,0)
pmin(op3,op2) = (1,1)
pmax(op3,op2) = (2,2)
pavg(op3,op2) = (2,2)
================================================
Testing uint64_t[1]
================================================
op1 = (2)
op2 = (1)
passign(op2,op3) = (1)
padd(op1,op2) = (3)
psub(op1,op2) = (1)
pmul(op1,op2) = (2)
pdiv(op1,op2) = (1)
pand(op1,op2) = (0)
por(op1,op2) = (3)
pxor(op1,op2) = (3)
pshl(op1,op2) = (4)
pshr(op1,op2) = (0)
pmin(op3,op2) = (1)
pmax(op3,op2) = (1)
pavg(op3,op2) = (1)
================================================
Testing int64_t[1]
================================================
op1 = (2)
op2 = (1)
passign(op2,op3) = (1)
padd(op1,op2) = (3)
psub(op1,op2) = (1)
pmul(op1,op2) = (2)
pdiv(op1,op2) = (1)
pand(op1,op2) = (0)
por(op1,op2) = (3)
pxor(op1,op2) = (3)
pshl(op1,op2) = (4)
pshr(op1,op2) = (0)
pmin(op3,op2) = (1)
pmax(op3,op2) = (1)
pavg(op3,op2) = (1)
================================================
Testing float[2]
================================================
op1 = (2.00,2.00)
op2 = (1.00,2.00)
passign(op2,op3) = (1.00,2.00)
padd(op1,op2) = (3.00,4.00)
psub(op1,op2) = (1.00,2.00)
pmul(op1,op2) = (2.00,4.00)
pdiv(op1,op2) = (1.00,2.00)
pmin(op3,op2) = (1.00,1.00)
pmax(op3,op2) = (2.00,2.00)
pavg(op3,op2) = (1.50,1.50)
================================================
Testing float[4]
================================================
op1 = (2.00,2.00,2.00,2.00)
op2 = (1.00,2.00,3.00,4.00)
passign(op2,op3) = (1.00,2.00,3.00,4.00)
padd(op1,op2) = (3.00,4.00,5.00,6.00)
psub(op1,op2) = (1.00,2.00,3.00,4.00)
pmul(op1,op2) = (2.00,4.00,6.00,8.00)
pdiv(op1,op2) = (1.00,2.00,3.00,4.00)
pmin(op3,op2) = (1.00,2.00,2.00,1.00)
pmax(op3,op2) = (4.00,3.00,3.00,4.00)
pavg(op3,op2) = (2.50,2.50,2.50,2.50)
================================================
Testing uint32_t[7]
================================================
op1 = (2,2,2,2,2,2,2)
op2 = (1,2,3,4,5,6,7)
passign(op2,op3) = (1,2,3,4,5,6,7)
padd(op1,op2) = (3,4,5,6,7,8,9)
psub(op1,op2) = (1,2,3,4,5,6,7)
pmul(op1,op2) = (2,4,6,8,10,12,14)
pdiv(op1,op2) = (1,2,3,4,5,6,7)
pand(op1,op2) = (0,2,2,0,0,2,2)
por(op1,op2) = (3,2,3,6,7,6,7)
pxor(op1,op2) = (3,0,1,6,7,4,5)
pshl(op1,op2) = (4,8,12,16,20,24,28)
pshr(op1,op2) = (0,0,0,1,1,1,1)
pmin(op3,op2) = (1,2,3,4,3,2,1)
pmax(op3,op2) = (7,6,5,4,5,6,7)
pavg(op3,op2) = (4,4,4,4,4,4,4)
================================================
Testing fround int32_t -> float
================================================
(-1,0,1,2) -> (-1.00,0.00,1.00,2.00)
(-1,0,1,2) -> (-1.00,0.00,1.00,2.00)
(-1,0,1,2) -> (-1.00,0.00,1.00,2.00)
================================================
Testing fround int32_t -> double
================================================
(-1,0,1,2) -> (-1.00,0.00,1.00,2.00)
(-1,0,1,2) -> (-1.00,0.00,1.00,2.00)
(-1,0,1,2) -> (-1.00,0.00,1.00,2.00)
================================================
Testing fround float -> int32_t
================================================
(-1.40,-0.40,0.60,1.60) -> (-1,0,1,2)
(-1.50,-0.50,0.50,1.50) -> (-2,0,0,2)
(-1.70,-0.70,0.30,1.30) -> (-2,-1,0,1)
================================================
Testing fround double -> int32_t
================================================
(-1.40,-0.40,0.60,1.60) -> (-1,0,1,2)
(-1.50,-0.50,0.50,1.50) -> (-2,0,0,2)
(-1.70,-0.70,0.30,1.30) -> (-2,-1,0,1)
================================================
Testing fcast float -> int32_t
================================================
(-1.40,-0.40,0.60,1.60) -> (-1,0,0,1)
(-1.50,-0.50,0.50,1.50) -> (-1,0,0,1)
(-1.70,-0.70,0.30,1.30) -> (-1,0,0,1)

100
extern/ustl/1.5/bvt/bvt24.cc vendored Normal file
View File

@@ -0,0 +1,100 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
static void HeapSize (size_t nElements, size_t& layerWidth, size_t& nLayers)
{
layerWidth = 0;
nLayers = 0;
for (size_t fts = 0; nElements > fts; fts += layerWidth) {
layerWidth *= 2;
if (!layerWidth)
++ layerWidth;
++ nLayers;
}
}
static void PrintSpace (size_t n)
{
for (uoff_t s = 0; s < n; ++ s)
cout << ' ';
}
static void PrintHeap (const vector<int>& v)
{
size_t maxWidth, nLayers;
HeapSize (v.size(), maxWidth, nLayers);
vector<int>::const_iterator src (v.begin());
cout << ios::width(3);
maxWidth *= 3;
for (uoff_t i = 0; i < nLayers; ++ i) {
const size_t w = 1 << i;
const size_t spacing = max (0, int(maxWidth / w) - 3);
PrintSpace (spacing / 2);
for (uoff_t j = 0; j < w && src != v.end(); ++ j) {
cout << *src++;
if (j < w - 1 && src != v.end() - 1)
PrintSpace (spacing);
}
cout << endl;
}
}
void TestHeapOperations (void)
{
static const int c_Values [31] = { // 31 values make a full 4-layer tree
93, 92, 90, 86, 83, 86, 77, 40, 72, 36, 68, 82, 62, 67, 63, 15,
26, 26, 49, 21, 11, 62, 67, 27, 29, 30, 35, 23, 59, 35, 29
};
vector<int> v;
v.reserve (VectorSize(c_Values));
for (uoff_t i = 0; i < VectorSize(c_Values); ++ i) {
v.push_back (c_Values[i]);
push_heap (v.begin(), v.end());
cout << "------------------------------------------------\n";
if (!is_heap (v.begin(), v.end()))
cout << "Is NOT a heap\n";
PrintHeap (v);
}
cout << "------------------------------------------------\n";
cout << "make_heap on the full range:\n";
v.resize (VectorSize (c_Values));
copy (VectorRange(c_Values), v.begin());
make_heap (v.begin(), v.end());
PrintHeap (v);
if (!is_heap (v.begin(), v.end()))
cout << "Is NOT a heap\n";
cout << "------------------------------------------------\n";
cout << "pop_heap:\n";
pop_heap (v.begin(), v.end());
v.pop_back();
PrintHeap (v);
if (!is_heap (v.begin(), v.end()))
cout << "Is NOT a heap\n";
cout << "------------------------------------------------\n";
cout << "sort_heap:\n";
v.resize (VectorSize (c_Values));
copy (VectorRange(c_Values), v.begin());
make_heap (v.begin(), v.end());
sort_heap (v.begin(), v.end());
foreach (vector<int>::const_iterator, i, v)
cout << *i;
cout << endl;
cout << "------------------------------------------------\n";
cout << "priority_queue push and pop:\n";
priority_queue<int> q;
for (uoff_t i = 0; i < VectorSize(c_Values); ++ i)
q.push (c_Values[i]);
while (!q.empty()) {
cout << q.top();
q.pop();
}
cout << endl;
}
StdBvtMain (TestHeapOperations)

180
extern/ustl/1.5/bvt/bvt24.std vendored Normal file
View File

@@ -0,0 +1,180 @@
------------------------------------------------
93
------------------------------------------------
93
92
------------------------------------------------
93
92 90
------------------------------------------------
93
92 90
86
------------------------------------------------
93
92 90
86 83
------------------------------------------------
93
92 90
86 83 86
------------------------------------------------
93
92 90
86 83 86 77
------------------------------------------------
93
92 90
86 83 86 77
40
------------------------------------------------
93
92 90
86 83 86 77
40 72
------------------------------------------------
93
92 90
86 83 86 77
40 72 36
------------------------------------------------
93
92 90
86 83 86 77
40 72 36 68
------------------------------------------------
93
92 90
86 83 86 77
40 72 36 68 82
------------------------------------------------
93
92 90
86 83 86 77
40 72 36 68 82 62
------------------------------------------------
93
92 90
86 83 86 77
40 72 36 68 82 62 67
------------------------------------------------
93
92 90
86 83 86 77
40 72 36 68 82 62 67 63
------------------------------------------------
93
92 90
86 83 86 77
40 72 36 68 82 62 67 63
15
------------------------------------------------
93
92 90
86 83 86 77
40 72 36 68 82 62 67 63
15 26
------------------------------------------------
93
92 90
86 83 86 77
40 72 36 68 82 62 67 63
15 26 26
------------------------------------------------
93
92 90
86 83 86 77
40 72 36 68 82 62 67 63
15 26 26 49
------------------------------------------------
93
92 90
86 83 86 77
40 72 36 68 82 62 67 63
15 26 26 49 21
------------------------------------------------
93
92 90
86 83 86 77
40 72 36 68 82 62 67 63
15 26 26 49 21 11
------------------------------------------------
93
92 90
86 83 86 77
40 72 36 68 82 62 67 63
15 26 26 49 21 11 62
------------------------------------------------
93
92 90
86 83 86 77
40 72 36 68 82 62 67 63
15 26 26 49 21 11 62 67
------------------------------------------------
93
92 90
86 83 86 77
40 72 36 68 82 62 67 63
15 26 26 49 21 11 62 67 27
------------------------------------------------
93
92 90
86 83 86 77
40 72 36 68 82 62 67 63
15 26 26 49 21 11 62 67 27 29
------------------------------------------------
93
92 90
86 83 86 77
40 72 36 68 82 62 67 63
15 26 26 49 21 11 62 67 27 29 30
------------------------------------------------
93
92 90
86 83 86 77
40 72 36 68 82 62 67 63
15 26 26 49 21 11 62 67 27 29 30 35
------------------------------------------------
93
92 90
86 83 86 77
40 72 36 68 82 62 67 63
15 26 26 49 21 11 62 67 27 29 30 35 23
------------------------------------------------
93
92 90
86 83 86 77
40 72 36 68 82 62 67 63
15 26 26 49 21 11 62 67 27 29 30 35 23 59
------------------------------------------------
93
92 90
86 83 86 77
40 72 36 68 82 62 67 63
15 26 26 49 21 11 62 67 27 29 30 35 23 59 35
------------------------------------------------
93
92 90
86 83 86 77
40 72 36 68 82 62 67 63
15 26 26 49 21 11 62 67 27 29 30 35 23 59 35 29
------------------------------------------------
make_heap on the full range:
93
92 90
86 83 86 77
40 72 36 68 82 62 67 63
15 26 26 49 21 11 62 67 27 29 30 35 23 59 35 29
------------------------------------------------
pop_heap:
92
86 90
72 83 86 77
40 49 36 68 82 62 67 63
15 26 26 29 21 11 62 67 27 29 30 35 23 59 35
------------------------------------------------
sort_heap:
11 15 21 23 26 26 27 29 29 30 35 35 36 40 49 59 62 62 63 67 67 68 72 77 82 83 86 86 90 92 93
------------------------------------------------
priority_queue push and pop:
93 92 90 86 86 83 82 77 72 68 67 67 63 62 62 59 49 40 36 35 35 30 29 29 27 26 26 23 21 15 11

22
extern/ustl/1.5/bvt/bvt25.cc vendored Normal file
View File

@@ -0,0 +1,22 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
void TestFStream (void)
{
fstream fs ("bvt/bvt25.std", ios::in | ios::nocreate);
if (!fs && !(fs.open("bvt25.std", ios::in | ios::nocreate),fs))
cout << "Failed to open bvt25.std" << endl;
string buf;
buf.resize (fs.size());
if (buf.size() != 71)
cout << "fstream.size() returned " << buf.size() << endl;
fs.read (buf.begin(), buf.size());
cout << buf;
fs.close();
}
StdBvtMain (TestFStream)

5
extern/ustl/1.5/bvt/bvt25.std vendored Normal file
View File

@@ -0,0 +1,5 @@
Hello world!
123 456 789
two words
and three words
and even four words

19
extern/ustl/1.5/bvt/bvt26.cc vendored Normal file
View File

@@ -0,0 +1,19 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
void TestMacros (void)
{
#define VARNAME(n) LARG_NUMBER(v,n)
#define VARDECL(n) VARNAME(n) = n
int COMMA_LIST (9, VARDECL);
cout << LIST(9, VARNAME, <<) << endl;
#define TO_STRING(n) #n
#define PRINT_N(n) REPEAT(n, TO_STRING) "\n"
cout << LIST(9, PRINT_N, <<);
}
StdBvtMain (TestMacros)

10
extern/ustl/1.5/bvt/bvt26.std vendored Normal file
View File

@@ -0,0 +1,10 @@
123456789
1
12
123
1234
12345
123456
1234567
12345678
123456789

57
extern/ustl/1.5/bvt/bvt27.cc vendored Normal file
View File

@@ -0,0 +1,57 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "stdtest.h"
using namespace tm;
void Print (int v)
{ cout.format ("PrintInt %d\n", v); }
void Print (short v)
{ cout.format ("PrintShort %d\n", v); }
void Print (float v)
{ cout.format ("PrintFloat %.2f\n", v); }
class Base { };
class Derived : public Base { };
void TestTypelists (void)
{
cout << "----------------------------------------------------------------------\n"
" Testing functionality from typet.h\n"
"----------------------------------------------------------------------\n";
NullType nullType;
cout.format ("sizeof(NullType) = %zu\n", sizeof(nullType));
cout.format ("Int2Type(42)::value = %d\n", Int2Type<42>::value);
Type2Type<int>::OriginalType t2tiv = 56;
cout.format ("Type2Type type value = %d\n", t2tiv);
cout << "int == int is " << bool(IsSameType<int, int>::value) << endl;
cout << "float == int is " << bool(IsSameType<float, int>::value) << endl;
Print (Select<Conversion<long,int>::exists2Way, int, float>::Result(567));
cout << "Base is SuperSubclass from Derived is " << bool(SuperSubclass<Base,Derived>::value) << endl;
cout << "Base is SuperSubclass from Base is " << bool(SuperSubclass<Base,Base>::value) << endl;
cout << "Base is SuperSubclassStrict from Derived is " << bool(SuperSubclassStrict<Base,Derived>::value) << endl;
cout << "Base is SuperSubclassStrict from Base is " << bool(SuperSubclassStrict<Base,Base>::value) << endl;
cout << "\n----------------------------------------------------------------------\n"
" Testing functionality from typelist.h\n"
"----------------------------------------------------------------------\n";
typedef tl::Seq<char, int, short, long>::Type IntTypesList;
typedef tl::Seq<float, double>::Type FloatTypesList;
cout.format ("Length of IntTypesList is %d\n", tl::Length<IntTypesList>::value);
Print (tl::TypeAt<IntTypesList, 2>::Result(1234));
Print (tl::TypeAtNonStrict<FloatTypesList, 0, int>::Result(1235));
Print (tl::TypeAtNonStrict<FloatTypesList, 2, short>::Result(1236));
typedef tl::Append<IntTypesList, FloatTypesList>::Result AllTypesList;
cout.format ("Index of double in AllTypesList is %d\n", tl::IndexOf<AllTypesList,double>::value);
typedef tl::Erase<AllTypesList, float>::Result NoFloatList;
cout.format ("Index of float in NoFloatList is %d\n", tl::IndexOf<NoFloatList,float>::value);
cout.format ("Index of double in NoFloatList is %d\n", tl::IndexOf<NoFloatList,double>::value);
typedef tl::Reverse<AllTypesList>::Result ReversedList;
cout.format ("Index of double in ReversedList is %d\n", tl::IndexOf<ReversedList,double>::value);
}
StdBvtMain (TestTypelists)

25
extern/ustl/1.5/bvt/bvt27.std vendored Normal file
View File

@@ -0,0 +1,25 @@
----------------------------------------------------------------------
Testing functionality from typet.h
----------------------------------------------------------------------
sizeof(NullType) = 1
Int2Type(42)::value = 42
Type2Type type value = 56
int == int is true
float == int is false
PrintInt 567
Base is SuperSubclass from Derived is true
Base is SuperSubclass from Base is true
Base is SuperSubclassStrict from Derived is true
Base is SuperSubclassStrict from Base is false
----------------------------------------------------------------------
Testing functionality from typelist.h
----------------------------------------------------------------------
Length of IntTypesList is 4
PrintShort 1234
PrintFloat 1235.00
PrintShort 1236
Index of double in AllTypesList is 5
Index of float in NoFloatList is -1
Index of double in NoFloatList is 4
Index of double in ReversedList is 0

72
extern/ustl/1.5/bvt/stdtest.cc vendored Normal file
View File

@@ -0,0 +1,72 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#define _GNU_SOURCE 1
#include "stdtest.h"
#include <signal.h>
#include <unistd.h>
/// Called when a signal is received.
static void OnSignal (int sig)
{
static int doubleSignal = false;
if (!TestAndSet (&doubleSignal))
abort();
alarm (1);
cout.flush();
#if HAVE_STRSIGNAL
cerr.format ("Fatal error: %s received.\n", strsignal(sig));
#else
cerr.format ("Fatal error: system signal %d received.\n", sig);
#endif
cerr.flush();
exit (sig);
}
/// Called by the framework on unrecoverable exception handling errors.
static void Terminate (void)
{
assert (!"Unrecoverable exception handling error detected.");
raise (SIGABRT);
exit (EXIT_FAILURE);
}
/// Called when an exception violates a throw specification.
static void OnUnexpected (void)
{
cerr << "Fatal internal error: unexpected exception caught.\n";
Terminate();
}
/// Installs OnSignal as handler for signals.
static void InstallCleanupHandlers (void)
{
static const uint8_t c_Signals[] = {
SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGABRT,
SIGIOT, SIGBUS, SIGFPE, SIGSEGV, SIGTERM,
SIGIO, SIGCHLD
};
for (uoff_t i = 0; i < VectorSize(c_Signals); ++i)
signal (c_Signals[i], OnSignal);
std::set_terminate (Terminate);
std::set_unexpected (OnUnexpected);
}
int StdTestHarness (stdtestfunc_t testFunction)
{
InstallCleanupHandlers();
int rv = EXIT_FAILURE;
try {
(*testFunction)();
rv = EXIT_SUCCESS;
} catch (ustl::exception& e) {
cout.flush();
cerr << "Error: " << e << endl;
} catch (...) {
cout.flush();
cerr << "Unexpected error." << endl;
}
return (rv);
}

18
extern/ustl/1.5/bvt/stdtest.h vendored Normal file
View File

@@ -0,0 +1,18 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#ifndef STDTEST_H_4980DC406FEEBBDF2235E42C4EFF1A4E
#define STDTEST_H_4980DC406FEEBBDF2235E42C4EFF1A4E
#include <ustl.h>
using namespace ustl;
typedef void (*stdtestfunc_t)(void);
int StdTestHarness (stdtestfunc_t testFunction);
#define StdBvtMain(function) int main (void) { return (StdTestHarness (&function)); }
#endif

71
extern/ustl/1.5/cmemlink.cc vendored Normal file
View File

@@ -0,0 +1,71 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "cmemlink.h"
#include "ofstream.h"
#include "strmsize.h"
#include "ualgo.h"
namespace ustl {
/// \brief Attaches the object to pointer \p p of size \p n.
///
/// If \p p is NULL and \p n is non-zero, bad_alloc is thrown and current
/// state remains unchanged.
///
void cmemlink::link (const void* p, size_type n)
{
if (!p && n)
throw bad_alloc (n);
unlink();
relink (p, n);
}
void cmemlink::unlink (void) throw()
{
m_Data = NULL; m_Size = 0;
}
/// Writes the object to stream \p os
void cmemlink::write (ostream& os) const
{
const written_size_type sz (size());
assert (sz == size() && "No support for writing memblocks larger than 4G");
os << sz;
os.write (cdata(), sz);
os.align (alignof (sz));
}
/// Writes the object to stream \p os
void cmemlink::text_write (ostringstream& os) const
{
os.write (begin(), readable_size());
}
/// Returns the number of bytes required to write this object to a stream.
cmemlink::size_type cmemlink::stream_size (void) const
{
const written_size_type sz (size());
return (Align (stream_size_of (sz) + sz, alignof(sz)));
}
/// Writes the data to file \p "filename".
void cmemlink::write_file (const char* filename, int mode) const
{
fstream f;
f.exceptions (fstream::allbadbits);
f.open (filename, fstream::out | fstream::trunc, mode);
f.write (cdata(), readable_size());
f.close();
}
/// Compares to memory block pointed by l. Size is compared first.
bool cmemlink::operator== (const cmemlink& l) const
{
return (l.m_Size == m_Size &&
(l.m_Data == m_Data || 0 == memcmp (l.m_Data, m_Data, m_Size)));
}
} // namespace ustl

100
extern/ustl/1.5/cmemlink.h vendored Normal file
View File

@@ -0,0 +1,100 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 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"
/// 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;
void write_file (const char* filename, int mode = 0644) const;
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

250
extern/ustl/1.5/config.h.in vendored Normal file
View File

@@ -0,0 +1,250 @@
// config.h - Generated from config.h.in by configure.
#ifndef CONFIG_H_01E33670634DAAC779EE5FF41CCBB36F
#define CONFIG_H_01E33670634DAAC779EE5FF41CCBB36F
// Define to the one symbol short name of this package.
#define USTL_NAME "@PKG_NAME@"
// Define to the full name and version of this package.
#define USTL_STRING "@PKG_NAME@ @PKG_VERSTR@"
// Define to the version of this package.
#define USTL_VERSION @PKG_VERSION@
// Define to the address where bug reports for this package should be sent.
#define USTL_BUGREPORT "@PKG_BUGREPORT@"
/// 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 is your decision. By default only debug builds throw.
///
#define WANT_STREAM_BOUNDS_CHECKING 1
#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 only the debug build does this.
#undef WANT_NAME_DEMANGLING
#if !defined(WANT_NAME_DEMANGLING) && !defined(NDEBUG)
#define WANT_NAME_DEMANGLING 1
#endif
/// 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 DLL_EXPORT __attribute__((visibility("default")))
#define DLL_LOCAL __attribute__((visibility("hidden")))
#define INLINE __attribute__((always_inline))
#else
#define DLL_EXPORT
#define DLL_LOCAL
#define INLINE
#endif
#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 empty if 'const' does not conform to ANSI C.
#undef const
// Define as '__inline' if that is what the C compiler calls it
#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
/// gcc has lately decided that inline is just a suggestion
/// Define to 1 if when you say 'inline' you mean it!
#undef WANT_ALWAYS_INLINE
#if WANT_ALWAYS_INLINE
#define inline INLINE inline
#endif
/// Define to 1 if you have the <assert.h> header file.
#undef HAVE_ASSERT_H
/// Define to 1 if you have the <ctype.h> header file.
#undef HAVE_CTYPE_H
/// Define to 1 if you have the <errno.h> header file.
#undef HAVE_ERRNO_H
/// Define to 1 if you have the <fcntl.h> header file.
#undef HAVE_FCNTL_H
/// Define to 1 if you have the <float.h> header file.
#undef HAVE_FLOAT_H
/// Define to 1 if you have the <inttypes.h> header file.
#undef HAVE_INTTYPES_H
/// Define to 1 if you have the <limits.h> header file.
#undef HAVE_LIMITS_H
/// Define to 1 if you have the <locale.h> header file.
#undef HAVE_LOCALE_H
// Define to 1 if you have the <alloca.h> header file.
#undef HAVE_ALLOCA_H
// Define to 1 if you have the <signal.h> header file.
#undef HAVE_SIGNAL_H
// Define to 1 if you have the __va_copy function
#define HAVE_VA_COPY 1
// Define to 1 if you have the <stdarg.h> header file.
#undef HAVE_STDARG_H
// Define to 1 if you have the <stddef.h> header file.
#undef HAVE_STDDEF_H
// Define to 1 if you have the <stdint.h> header file.
#undef HAVE_STDINT_H
// Define to 1 if you have the <stdio.h> header file.
#undef HAVE_STDIO_H
// Define to 1 if you have the <stdlib.h> header file.
#undef HAVE_STDLIB_H
// Define to 1 if you have the <string.h> header file.
#undef HAVE_STRING_H
// Define to 1 if you have the 'strrchr' function.
#define HAVE_STRRCHR 1
// Define to 1 if you have the 'strsignal' function.
#define HAVE_STRSIGNAL 1
// Define to 1 if you have the <sys/stat.h> header file.
#undef HAVE_SYS_STAT_H
// Define to 1 if you have the <sys/types.h> header file.
#undef HAVE_SYS_TYPES_H
// Define to 1 if you have the <time.h> header file.
#undef HAVE_TIME_H
// Define to 1 if you have the <unistd.h> header file.
#undef HAVE_UNISTD_H
// Define to 1 if you have the <math.h> header file.
#undef HAVE_MATH_H
// 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
// 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 your compiler treats char as a separate type along with
// signed char and unsigned char. This will create overloads for char.
#undef HAVE_THREE_CHAR_TYPES
// Define to 1 if you have 64 bit types available
#undef HAVE_INT64_T
// Define to 1 if you have the long long type
#undef HAVE_LONG_LONG
// Define to 1 if you want unrolled specializations for fill and copy
#define WANT_UNROLLED_COPY 1
// Define to 1 if you want to use MMX/SSE/3dNow! processor instructions
#define WANT_MMX 1
// Define to byte sizes of types
#undef SIZE_OF_CHAR
#undef SIZE_OF_SHORT
#undef SIZE_OF_INT
#undef SIZE_OF_LONG
#undef SIZE_OF_LONG_LONG
#undef SIZE_OF_POINTER
#undef SIZE_OF_SIZE_T
#undef SIZE_OF_BOOL
#undef SIZE_T_IS_LONG
// Byte order macros, converted in utypes.h
#define USTL_LITTLE_ENDIAN 4321
#define USTL_BIG_ENDIAN 1234
#define USTL_BYTE_ORDER USTL_@BYTE_ORDER@
// 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 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)) && __GNUC__ >= 3
#undef HAVE_VECTOR_EXTENSIONS
#endif
#if CPU_HAS_SSE && defined(__GNUC__)
#define __sse_align __attribute__((aligned(16)))
#else
#define __sse_align
#endif
#endif

497
extern/ustl/1.5/configure vendored Normal file
View File

@@ -0,0 +1,497 @@
#! /bin/sh
#
# This file is free software, distributed under the MIT License.
######################################################################
#### Project Configuration ###########################################
######################################################################
PKG_NAME="ustl"
PKG_VERSTR="v1.5"
PKG_BUGREPORT="Mike Sharov <msharov@users.sourceforge.net>"
# Files that get created by this script
FILES="Config.mk config.h"
# Package options
COMPONENTS='
{
name=[without-shared]
desc=[Builds the shared library (if supported by the OS)]
seds=[s/^\(BUILD_SHARED\)/#\1/]
}{
name=[with-static]
desc=[ Builds the static library]
seds=[s/^#\(BUILD_STATIC\)/\1/]
}{
name=[with-debug]
desc=[ Compile for debugging]
seds=[s/^#\(DEBUG\)/\1/]
}{
name=[with-demangler]
desc=[Demangle C++ symbols in backtrace]
seds=[s/#undef \(WANT_NAME_DEMANGLING\)/#define \1 1/]
}{
name=[without-bounds]
desc=[Disable runtime bounds checking on stream reads/writes]
seds=[s/#define \(WANT_STREAM_BOUNDS_CHECKING\) 1/#undef \1/]
}{
name=[without-fastcopy]
desc=[Disable specializations for copy/fill]
seds=[s/#define \(WANT_UNROLLED_COPY\) 1/#undef \1/]
}{
name=[without-mmx]
desc=[ Disable use of MMX/SSE/3dNow! instructions]
seds=[s/#define \(WANT_MMX\) 1/#undef \1/]
}{
name=[force-inline]
desc=[ Make inline keyword mean always inline, not just a hint]
seds=[s/#undef \(WANT_ALWAYS_INLINE\)/#define \1 1/]
}{
name=[with-libstdc++]
desc=[Link with libstdc++]
seds=[s/#define \(WITHOUT_LIBSTDCPP\) 1/#undef \1/;s/\(NOLIBSTDCPP\)/#\1/]
}';
# Header files
HEADERS="assert.h ctype.h errno.h fcntl.h float.h inttypes.h limits.h stdio.h
locale.h alloca.h signal.h stdarg.h stddef.h sys/stat.h sys/types.h stdint.h
stdlib.h string.h time.h unistd.h math.h stdlib.h";
# Libraries
LIBS="supc++ gcc_eh SystemStubs"
# First pair is used if nothing matches
PROGS="CC=gcc CC=cc CXX=g++ CXX=c++ DOXYGEN=doxygen LD=ld AR=ar RANLIB=ranlib RANLIB=touch INSTALL=install"
# Environment variables
ENVIRONS="CXXFLAGS LDFLAGS"
# Automatic vars
[ -d .git ] && PKG_VERSTR=`git describe`
PKG_MAJOR=`expr "$PKG_VERSTR" : 'v\([0-9]*\)\.[0-9]*'`
PKG_MINOR=`expr "$PKG_VERSTR" : 'v[0-9]*\.\([0-9]*\)'`
PKG_STRING="$PKG_NAME $PKG_VERSTR"
# Miscellaneous substitutions
CUSTSUBS="s/@PKG_NAME@/$PKG_NAME/g
s/@PKG_VERSION@/"0x$PKG_MAJOR${PKG_MINOR}0"/g
s/@PKG_VERSTR@/$PKG_VERSTR/g
s/@PKG_TARNAME@/$PKG_NAME/g
s/@PKG_STRING@/$PKG_STRING/g
s/@PKG_UNAME@/`echo $PKG_NAME|tr a-z A-Z`/g
s/@PKG_BUGREPORT@/$PKG_BUGREPORT/g
s/@PKG_MAJOR@/$PKG_MAJOR/g
s/@PKG_MINOR@/$PKG_MINOR/g"
######################################################################
#### The rest of the file is configuration code. Leave it alone. #####
######################################################################
die() { rm -f config.sed config.cpu config.cpu.c; exit; }
#### Compile the configurator and generate initial config.sed ########
if [ -z "$CC" ]; then
for i in gcc g++ cc c++ c89 c99; do
CC=`which $i 2> /dev/null` && break
done
fi
[ -z "$CC" ] && "No C compiler found" && die
# Determine gcc private directory
PSTDDEF=`echo "#include <stddef.h>"|$CC -E -|grep stddef.h|head -n1|cut -d' ' -f3|cut -d'"' -f2`
PINCDIR=`dirname $PSTDDEF`
PLIBDIR=`dirname $PINCDIR`
if [ -d $PLIBDIR/lib ]; then PLIBDIR=$PLIBDIR/lib; fi
# Create and build the C configurator
cat>config.cpu.c<<\SRC
#include <stdio.h>
#include <sys/types.h>
#include <sys/param.h>
#if defined(__GNUC__) && (__i386__ || __x86_64) && !defined(__PIC__)
static uint cpuid_supported (void)
{
unsigned long forig, fnew;
asm ("pushf\n\tpop\t%0\n\t"
"mov\t%0, %1\n\txor\t$0x200000, %0\n\t"
"push\t%0\n\tpopf\n\tpushf\n\tpop\t%0"
: "=r"(fnew), "=r"(forig));
return (fnew != forig);
}
static uint cpuid (void)
{
#define i_cpuid(a,r,c,d) asm("cpuid":"=a"(r),"=c"(c),"=d"(d):"0"(a):"ebx")
const uint amdBits = 0xC9480000, extFeatures = 0x80000000, amdExtensions = 0x80000001;
uint r, c, d, caps;
if (!cpuid_supported()) return (0);
i_cpuid (0, r, c, d);
if (!r) return (0);
i_cpuid (1, r, c, d);
caps = (d & ~amdBits);
i_cpuid (extFeatures, r, c, d);
if (r != extFeatures) {
i_cpuid (amdExtensions, r, c, d);
caps |= d & amdBits;
}
return (caps);
}
#else
static uint cpuid (void) { return (0); }
#endif
#define SET(c,v) "s/#undef \\(" #c "\\)/#define \\1 " #v "/g\n"
int main (void)
{
typedef struct { char bit, name[11]; } SCpuCaps;
static const short int boCheck=0x0001;
static const char boNames[2][16]={"BIG","LITTLE"};
static const SCpuCaps s_CpuCaps[]={
{ 0, "FPU" },
{ 2, "EXT_DEBUG" },
{ 4, "TIMESTAMPC" },
{ 5, "MSR" },
{ 8, "CMPXCHG8" },
{ 9, "APIC" },
{ 11, "SYSCALL" },
{ 12, "MTRR" },
{ 15, "CMOV" },
{ 16, "FCMOV" },
{ 22, "SSE " },
{ 23, "MMX" },
{ 24, "FXSAVE" },
{ 25, "SSE " },
{ 26, "SSE2" },
{ 30, "EXT_3DNOW" },
{ 31, "3DNOW" }
};
uint i, caps;
printf ("s/ \\?@INLINE_OPTS@/");
#if __GNUC__ >= 3
#if __GNUC__ >= 4
printf (" -fvisibility-inlines-hidden -fno-threadsafe-statics -fno-enforce-eh-specs");
#elif __GNUC_MINOR__ >= 4
printf (" --param max-inline-insns-single=1024"
" \\\\\\n\\t\\t--param large-function-growth=65535"
" \\\\\\n\\t\\t--param inline-unit-growth=1024");
#else
printf (" -finline-limit=65535");
#endif
#else
printf ("/g\ns/-Wredundant-decls/-Wno-redundant-decls");
#endif
printf ("/g\n");
#if __GNUC__ != 3
printf ("s/ \\?@libgcc_eh@//g\n");
#endif
#if __i386__
printf ("s/ \\?-fPIC//g\n");
#endif
#if defined(__GNUC__) || defined(__GLIBC_HAVE_LONG_LONG)
printf (SET(HAVE_LONG_LONG,1) SET(SIZE_OF_LONG_LONG,%zd), sizeof(long long));
#endif
#if defined(__GNUC__) || (__WORDSIZE == 64) || defined(__ia64__)
#ifndef BSD
printf (SET(HAVE_INT64_T,1));
#endif
#endif
#ifndef __APPLE__
if (sizeof(size_t) == sizeof(unsigned long) && sizeof(size_t) != sizeof(uint))
#endif
printf (SET(SIZE_T_IS_LONG,1));
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
printf (SET(HAVE_VECTOR_EXTENSIONS,1));
#else
printf ("s/ \\?-Wshadow//g\n");
#endif
printf ("s/@BYTE_ORDER@/%s_ENDIAN/g\n"
SET(RETSIGTYPE,void)
"s/#undef const/\\/\\* #define const \\*\\//g\n"
"s/#undef inline/\\/\\* #define inline __inline \\*\\//g\n"
"s/#undef off_t/\\/\\* typedef long off_t; \\*\\//g\n"
"s/#undef size_t/\\/\\* typedef long size_t; \\*\\//g\n"
SET(SIZE_OF_CHAR,%zd)
SET(SIZE_OF_SHORT,%zd)
SET(SIZE_OF_INT,%zd)
SET(SIZE_OF_LONG,%zd)
SET(SIZE_OF_POINTER,%zd)
SET(SIZE_OF_SIZE_T,%zd)
SET(LSTAT_FOLLOWS_SLASHED_SYMLINK,1),
boNames [(uint)(*((const char*)&boCheck))], sizeof(char),
sizeof(short), sizeof(int), sizeof(long), sizeof(void*), sizeof(size_t));
caps = cpuid();
for (i = 0; i < sizeof(s_CpuCaps)/sizeof(SCpuCaps); ++i)
if (caps & (1 << s_CpuCaps[i].bit))
printf (SET(CPU_HAS_%s,1), s_CpuCaps[i].name);
#if __GNUC__ >= 3
printf ("s/ \\?@PROCESSOR_OPTS@/");
if (caps & (1<<23))
printf (" -mmmx");
if (caps & ((1<<22)|(1<<25)))
printf (" -msse -mfpmath=sse");
if (caps & (1<<26))
printf (" -msse2");
if (caps & ((1<<30)|(1<<31)))
printf (" -m3dnow");
printf ("/g\n");
#else
printf ("s/ \\?@PROCESSOR_OPTS@//g\n");
#endif
return (0);
}
SRC
$CC -o config.cpu config.cpu.c
[ ! -x config.cpu ] && echo "Configurator build failed" && die
./config.cpu > config.sed
#### Set host-dependent options ######################################
SYSNAME=`uname|tr A-Z a-z`
[ "`uname -m|tr A-Z a-z`" = "alpha" ] && SYSNAME="alpha"
case "$SYSNAME" in
*solaris*| *sun*) SYSNAME="sun";;
*darwin*| *osx*) SYSNAME="mac";;
*alpha*) SYSNAME="alpha";;
*bsd*) SYSNAME="bsd";;
*) SYSNAME="linux";;
esac
if [ "$SYSNAME" = "sun" ]; then
echo "s/-Wredundant-decls/-Wno-redundant-decls/g
s/@SHBLDFL@/-G/g" >>config.sed
else
echo 's/#undef \(HAVE_THREE_CHAR_TYPES\)/#define \1 1/g' >>config.sed
fi
if [ "$SYSNAME" = "bsd" ]; then
echo 's/ \?@libgcc_eh@//g
s/#define WITHOUT_LIBSTDCPP 1/#undef WITHOUT_LIBSTDCPP/g
s/NOLIBSTDCPP = -nodefaultlibs /#NOLIBSTDCPP = -nodefaultlibs/g
s/-Wredundant-decls/-Wno-redundant-decls/g
s/-Winline/-Wno-inline/g
s/#define HAVE_VA_COPY 1/#undef HAVE_VA_COPY/g' >>config.sed
fi
if [ "$SYSNAME" = "linux" -o "$SYSNAME" = "bsd" ]; then
echo 's/@SHBLDFL@/-shared -Wl,-soname=$1/g' >>config.sed
elif [ "$SYSNAME" = "alpha" ]; then
echo "s/BUILD_SHARED = 1 /#BUILD_SHARED = 1/g
s/#BUILD_STATIC = 1/BUILD_STATIC = 1 /g" >>config.sed
fi
if [ "$SYSNAME" = "mac" ]; then
echo 's/ \?@libgcc_eh@//g
s/@SYSWARNS@/-Wno-long-double/g
s/lib$1.so/lib$1.dylib/g
s/lib$1.so.${MAJOR}.${MINOR}.${BUILD}/lib$1.${MAJOR}.${MINOR}.${BUILD}.dylib/g
s/lib$1.so.${MAJOR}.${MINOR}/lib$1.${MAJOR}.${MINOR}.dylib/g
s/lib$1.so.${MAJOR}/lib$1.${MAJOR}.dylib/g
s/@SHBLDFL@/-Wl,-single_module -compatibility_version 1 -current_version 1 -install_name $1 -Wl,-Y,1455 -dynamiclib -mmacosx-version-min=10.4/g' >>config.sed
else
echo 's/ \?@SYSWARNS@//g' >>config.sed
fi
if [ "$SYSNAME" = "alpha" -o "$SYSNAME" = "mac" ]; then
echo 's/#undef \(SIZE_OF_BOOL\)/#define \1 SIZE_OF_LONG/g' >>config.sed
else
echo 's/#undef \(SIZE_OF_BOOL\)/#define \1 SIZE_OF_CHAR/g' >>config.sed
fi
if [ "$SYSNAME" = "linux" ]; then
echo 's/#undef \(HAVE_RINTF\)/#define \1 1/g' >>config.sed
else
echo 's/ \?-mfpmath=sse//g' >>config.sed
fi
if [ "$SYSNAME" = "mac" -o "$SYSNAME" = "bsd" ]; then
echo 's/#define \(HAVE_STRSIGNAL\) 1/#undef \1/g' >>config.sed
fi
#### Printing helper functions #######################################
PrintComponents() {
local cc name desc
cc=$COMPONENTS
echo "Options:"
while [ ! -z "$cc" ]; do
name=`expr "$cc" : '[^}]*name=\[\([^]]*\)\]'`
desc=`expr "$cc" : '[^}]*desc=\[\([^]]*\)\]'`
echo " --$name $desc"
cc=`expr "$cc" : '[^}]*}\(.*\)'`
done
echo
}
PrintHelp() {
echo "This program configures $PKG_STRING to adapt to many kinds of systems.
Usage: configure [OPTION]...
Configuration:
-h, --help display this help and exit
-V, --version display version information and exit
Installation directories:
--prefix=PREFIX architecture-independent files [/usr/local]
--exec-prefix=EPREFIX architecture-dependent files [PREFIX]
--bindir=DIR user executables [EPREFIX/bin]
--sbindir=DIR system admin executables [EPREFIX/sbin]
--libexecdir=DIR program executables [EPREFIX/libexec]
--datadir=DIR read-only architecture-independent data [PREFIX/share]
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
--gccincludedir=DIR GCC internal header files [PREFIX/include]
--infodir=DIR info documentation [PREFIX/info]
--mandir=DIR man documentation [PREFIX/man]
System types:
--build=BUILD configure for building on BUILD [guessed]
--host=HOST cross-compile to build programs to run on HOST [BUILD]
"
PrintComponents
echo "Report bugs to $PKG_BUGREPORT."
}
PrintVersion() {
echo "$PKG_NAME configure $PKG_VERSTR"
}
SubVar() {
local esc2
esc2=`echo $2 | sed 's/\//\\\&/g'`
eval ac_var_$1='$esc2';
echo "s/@$1@/$esc2/g" >>config.sed
}
SubComp() {
local cc name seds
cc=$COMPONENTS
while [ ! -z "$cc" ]; do
name=`expr "$cc" : '[^}]*name=\[\([^]]*\)\]'`
seds=`expr "$cc" : '[^}]*seds=\[\([^]]*\)\]'`
[ "$name" = "$1" ] && echo $seds >>config.sed
cc=`expr "$cc" : '[^}]*}\(.*\)'`
done
}
for i in $*; do
case $i in
--) break;;
--version |-V) PrintVersion && die;;
--help |-h |-?) PrintHelp && die;;
--*=*) SubVar `expr "$i" : '--\([^=]*\)='` `expr "$i" : '[^=]*=\(.*\)'`;;
--*) SubComp `expr "$i" : '--\(.*\)'`;;
*) echo "Error: unrecognized option \"$i\"" && die;;
esac
done
#### Set directory prefixes ##########################################
echo "s/@prefix@/${ac_var_prefix:=\/usr\/local}/g
s/@exec_prefix@/${ac_var_exec_prefix:=$ac_var_prefix}/g
s/@bindir@/$ac_var_exec_prefix\/bin/g
s/@sbindir@/$ac_var_exec_prefix\/sbin/g
s/@libexecdir@/$ac_var_exec_prefix\/libexec/g
s/@datarootdir@/${ac_var_datarootdir:=$ac_var_prefix\/share}/g
s/@datadir@/$ac_var_datarootdir/g
s/@sysconfdir@/$ac_var_prefix\/etc/g
s/@sharedstatedir@/$ac_var_prefix\/com/g
s/@localstatedir@/$ac_var_prefix\/var/g
s/@includedir@/${ac_var_includedir:=$ac_var_prefix\/include}/g
s/@oldincludedir@/${ac_var_oldincludedir:=\/usr\/include}/g
s/@docdir@/${ac_var_docdir:=$ac_var_datarootdir\/doc\/$PKG_NAME}/g
s/@infodir@/$ac_var_datarootdir\/info/g
s/@htmldir@/$ac_var_docdir/g
s/@dvidir@/$ac_var_docdir/g
s/@pdfdir@/$ac_var_docdir/g
s/@psdir@/$ac_var_docdir/g
s/@libdir@/${ac_var_libdir:=$ac_var_exec_prefix\/lib}/g
s/@localedir@/$ac_var_datarootdir\/locale/g
s/@mandir@/$ac_var_datarootdir\/man/g
s/@gccincludedir@/${ac_var_gccincludedir:=`echo $PINCDIR | sed 's/\//\\\&/g'`}/g
s/@gcclibdir@/${ac_var_gcclibdir:=`echo $PLIBDIR | sed 's/\//\\\&/g'`}/g
s/@customincdir@/${ac_var_customincdir:=$ac_var_prefix\/include}/g
s/@customlibdir@/${ac_var_customlibdir:=$ac_var_prefix\/lib}/g" >>config.sed
if [ "$ac_var_prefix" != "\/usr\/local" -a "$ac_var_prefix" != "\/usr" ]; then
echo "s/ \?@CUSTOMINCDIR@/ -I$ac_var_customincdir/g
s/ \?@CUSTOMLIBDIR@/ -L$ac_var_customlibdir/g" >>config.sed
else
echo "s/ \?@CUSTOMINCDIR@//g
s/ \?@CUSTOMLIBDIR@//g" >>config.sed
fi
#### Find headers, libs, programs, and subs ##########################
SubHeadLibsProgs() {
local INCPATH LIBPATH LIBSUFFIX found pname pcall esciv
INCPATH="$ac_var_oldincludedir $ac_var_includedir $ac_var_gccincludedir $ac_var_customincdir"
INCPATH=`echo $INCPATH | sed 's/\\\\//g'`
for i in $HEADERS; do
for p in $INCPATH; do
if [ -r "$p/$i" ]; then
echo 's/#undef \(HAVE_'`echo $i|tr a-z/.- A-Z___`'\)/#define \1 1/' >>config.sed
break
fi
done
done
LIBPATH="`echo $LD_LIBRARY_PATH | tr ':' ' '` $ac_var_libdir $ac_var_gcclibdir $ac_var_customlibdir /usr/lib /usr/local/lib /lib"
LIBPATH=`echo $LIBPATH | sed 's/\\\\//g'`
LIBSUFFIX="so a la dylib"
for i in $LIBS; do
found=
for p in $LIBPATH; do
for s in $LIBSUFFIX; do
if [ -r "$p/lib$i.$s" ]; then
found=" -l$i"
break
fi
done
[ -z "$found" ] || break
done
echo "s/ \?@lib$i@/$found/g" >>config.sed
done
for i in $PROGS; do
pname=`expr "$i" : '\([^=]*\)=[^=]*'`
pcall=`expr "$i" : '[^=]*=\([^=]*\)'`
esciv="`eval echo \$\{$pname\}|sed 's/\//\\\\\//g'`"
# First check if an environment variable is set
[ ! -z "$esciv" ] && echo "s/@$pname@/$esciv/g" >>config.sed
# Check if the program exists
[ -x `which $pcall` ] && echo "s/@$pname@/$pcall/g" >>config.sed
done
# If nothing found in first loop, set the first pair anyway.
for i in $PROGS; do
pname=`expr "$i" : '\([^=]*\)=[^=]*'`
pcall=`expr "$i" : '[^=]*=\([^=]*\)'`
echo "s/@$pname@/$pcall/g" >>config.sed
done
# And, finally, the environment variables
for i in $ENVIRONS; do
esciv="`eval echo '"'\$\{$i\}'"'|sed 's/\//\\\&/g'`"
[ ! -z "$esciv" ] && esciv=" $esciv"
echo "s/ \?@$i@/$esciv/g" >>config.sed
done
echo "$CUSTSUBS" >>config.sed
}
SubHeadLibsProgs
#### Apply substitutions to all files ################################
for i in $FILES; do
sed -f config.sed $i.in > $i
done
touch config.status
echo "#! /bin/sh
$0 $*
`tail -n+3 config.status`" > config.status.new
chmod u+x config.status.new
mv config.status.new config.status
die

368
extern/ustl/1.5/docs/ChangeLog vendored Normal file
View File

@@ -0,0 +1,368 @@
2011-03-16 Release 1.5
* Updated set, map, and multimap with full set of insert, erase, and search overloads
* Added public lower_bound, upper_bound, and equal_range to map, as per standard
* Added comparator parameter to set, multiset, map, and multimap.
* Implemented FirstBit, Rol, Ror, and a generic NextPow2
* Remove memlink copy because it conflicts with string copy
* Operators returning a new value should be const
* Added char* + string operator, and a noarg erase
* Added --force-inline configure option
* Removed all references to stdc++ headers when not using libstdc++
* Fixed minor glitches compiling with clang++
* Other small fixes
2010-03-21 Release 1.4
* Fixed crash in destructor of empty vector, introduced by 1.3
* Fixed list merge, which previously did not compile
* Some portability changes to configure so it will work with dash
when escape char processing bug is fixed (Ubuntu bug #268929)
2009-08-04 Release 1.3
* Some API changes to comply with the current C++ standard
binary_search algo returns true, not the found iterator
stack and queue are now type templates, not container adaptors.
Correctly set eof and fail flags in all stream functions
This allows the use of the non-exception path in streams
verify_remaining will no longer throw unless exceptions are on in the stream
verify_remaining will return false if space is insufficient and set flags
exceptions are on by default in istream and ostream and off elsewhere
Updated return values of stream functions to match the standard
what() on message exceptions returns the text passed to the ctor
set insert also returns an iterator/bool pair
map insert now returns an iterator,bool pair
* streamsize and streamoff types defined
* Added string resize with a value arg
* Added standalone getline
* Added numeric_limits digits and digits10
* Name demangling is now an option, off by default, removing ~20k
* A new and improved nonrecursive make system
* Numerous small size and speed optimizations
* A few minor bugfixes
2008-02-17 Release 1.2
* Fixed ifstream readsome to work correctly on nonblocking fds.
* Yet another try at fixing noalias rearrangments.
Added a memory clobber and +g to noalias templates.
* Added dtors template which will embody range destructors for
destroy and vector dtor instead of vector deallocate. It is
called by destroy through a selector template, turning it off
completely for integral types. This removes empty deallocate
instantiations for integral type vectors.
* Fixed bitset stream_size (bits-words confusion)
* Added workaround for compile error when printing a char array.
* Added static_assert from Loki.
2007-09-02 Release 1.1
* Due to the demise of SourceForge compile farm, this and subsequent
releases are not as well tested the previous ones. So please
report compilation problems, if any, on non-x86_64 platforms.
* Fixed various aliasing problems complained about by gcc 4.2.
* Added noalias_cast<type>(v) to aid in working around the above
aliasing problem. The aliased variables also must be
explicitly touched by an empty asm statement or something.
* Reimplemented stream_size_of as a template stack because the old
implmentation is invalid in gcc 4.2+ due to a change in
overloaded set lookup scope. vector and tuple now have the
standard read/write/stream_size members.
* Reimplemented flow operators as templates.
* STD_STREAMABLE and TEXT_STREAMABLE are no longer necessary.
* Merged some template metaprogramming stuff from Alexandrescu's Loki
library, including typelists and type traits.
* Implemented generic macro list macros. See metamac.h.
* Fixed some bsconf warnings.
* memblock is_linked now correctly returns true when linked to NULL.
* Added back() to string.
* Fixed a memory leak in CBacktrace GetSymbols.
* Changed written exception data to look like an IFF chunk.
* Removed "memory" from some simd spec clobber lists.
* Reduced the amount of code generated by vector stream templates.
* talign will no longer generate a temp object when called with
non-trivial classes. Uses NullValue template to avoid.
* Linking with gcc instead of using -nodefaultlibs is simpler.
* Removed link number overloads. Sadly, I don't know what this will
break, if anything. On my machine the only case is link(p,0),
which generates an ambiguity error and is easily fixed by
explicitly casting the zero to a size_t. The benefit is
cleaner code and fewer problems for the Symbian port, so the
change stays until/unless somebody reports it as a problem.
* Added long4grain and ptr4grain wrappers to explicitly write long
values on 4-grain, even on 64bit platforms.
2006-10-27 Release 1.0 SVN 428
* API CHANGE: ostringstream now works like std::ostringstream, with
an internal buffer instead of writing to an external one
through a link. Instead of passing the buffer to the ctor,
write directly to a default-constructed stream object and
assign buf = os.str() when finished.
* Format change: containers will now write their size as a uint32_t
instead of size_t to allow binary compatibility with 64 bit
architectures. On 32 bit machines this makes no difference.
* Renamed fdostringstream to ofstream.
* Renamed fdistringstream to ifstream.
* Renamed iterator_swap to iter_swap, as in the standard.
* file.h/cc was removed; fstream replaces its functionality.
* Added most remaining i/ostringstream functions that make sense in
this implementation: str, put, get, getline, ignore, peek,
readsome, putback, unget, tellg, seekg, sync, flush, seekp,
tellp, good. The rest will probably not be implemented at
all, since they reference streambufs which don't exist in uSTL.
* Implemented fstream and used it in ifstream/ofstream.
* Added remaining algorithms: find_end, find_first_of, includes,
is_sorted, lexicographical_compare, max_element, min_element,
partial_sort, partial_sort_copy, partition, next_permutation,
prev_permutation, reverse_copy, rotate_copy, search, search_n,
set_difference, set_intersection, set_symmetric_difference,
set_union, and stable_partition. All the algorithms defined by
the C++ standard are now implemented.
* Made ios_base and ios classes instead of namespaces and derived
all stream objects from ios_base. Pulled up state and all
related functions into it. The only problem with this is that
end() conflicts with seekdir end, so you'll need to use
ios scope when you want the latter.
* Align container ends on 4 grain.
While this is not very friendly to 64bit architectures, it is
the only way to allow writing containers portably. It is
better to always align to an arbitrary value than to align to
a platform-dependent one.
* Removed non-const data pointer from memlink.
While enforcing const-correctness is a good thing, the errors
this catches are relatively rare and are all programmer errors.
I must concede that the benefits of having memblocks, strings,
and containers be 16 bytes in size is a great advantage in both
speed and codesize. As a result, one needs to be more mindful
to not modify memlink-derived objects that are linked to const
data; before this change it would have caused a crash, now it
might or might not do that, as with regular pointers.
* Added CBacktrace class for printing backtrace information.
* x86_64 cleanup and improvements, including MMX support.
* Micro-optimization pass for size. Saved 24% (32k)!
* exception now creates a backtrace when thrown.
* Do cout.flush() before read in cin, like std does.
* max_size() on linked objects should return size(), because it is.
* >=, <=, and compare templates no longer require == (>= is !<)
* Pulled rotate code into rotate_fast for memory blocks.
* stream_bounds_exception demangles type names.
* set,map,multiset,multimap now instantiate less crud.
* Abandoned any attempt to use the goddamned byteswap.h.
* Implemented bitset any, none, and count.
* New popcount algorithms.
* Implemented compose1 and compose2 extensions.
* Support building as a .dylib on MacOS.
* Removed --without-cout configure option.
2005-11-10 Release 0.8
* API CHANGE: changed all string's find members to return offsets
instead of iterators. That's what the STL standard requires.
Also added standard-required replace/inserts with offset
arguments. Yes, this is a bit painful. I was using it a lot...
But it's all for the better. I promise!
* Removed char_at and ichar from string; use utf8_begin/end instead.
* Iterator-based string insert now return an iterator, like vector.
* Added more wchar_t overloads to string, include append and assign.
* Updated bsconf to use malloc instead of static buffers.
* construct/destruct will now disappear for integral types.
Integral types have no destructors/constructors.
* Fixed istream_iterator to read on construction and in operator++
as the standard says. Unfortunately, this makes it almost
totally useless, since using it as a source for copy will
always overread by one because copy will call ++ past the
end, which will read one element past the end. This behaviour
is understandable when reading to EOF (which is the only
example ever shown for using it), but worthless when you
have a fixed number of elements you want to read. I'm only
using it to implement utf8 from streams, so, having fixed
that to not overread, I'll chalk it up to standard
compliance.
* Made istream_iterator default constructible and implemented the
EOF check during reading. This should make read-to-EOF
scenario possible.
* Made streams runtime bounds checking on by default.
* Added operator-- to istream_iterator to do unputs.
This works only once for variable-length types because there
is no way to know the length to back up to get the element
before the currently cached one. Constant-length types can
be unput multiple times, and can use -= and - operators.
* fdistringstream underflow will no longer erase the entire buffer.
This helps to keep ungetc working most of the time.
* Similarly fixed utf8in_iterator to read on construction.
This fixed the double-advance bug in utf8in_iterator.
* Fixed utf8in_iterator to not read ahead (except in constructor)
before operator++ is called. This ensures that it does not
read past the end of the string if it isn't 0-terminated.
(Although it will still do so if you call ++)
* Field width should be padded with spaces, not zeroes.
* Implemented some heap algorithms.
* Added VectorRange macro.
* Added relink() call to memlinks for faster resizing.
relink does the work of link, but without calling unlink.
* Added to string substr and like functions.
* Moved simd fill into ualgobase.cc
* configure now recompiles bsconf if its sources change.
* Fixed a rare off-by-one error in ostringstream vprintf.
* Removed fdostringstream printf, since ostringstream has it already.
* Fixed bsconf crash when all inline options are enabled.
* Fixed crash when NULL filename given to file_exception.
* Corrected potential buffer overflow in file_exception and sistream.
* Fixed string rfind for strings; was returning a wrong value sometimes.
* Added copy_link call to memblock to make a copy of linked data.
* Added assert to memlink begin() to warn when writing to a const block.
* Makefile now correctly uses ${MAKE} to recurse.
* Removed all usage of "y" in SIMD asm blocks; gcc<4-> movd, not movq.
This fixes problems with MMX fround on some platforms.
* Removed SSE3 detection from bsconf; it just doesn't work!
* Added BYTE_ORDER detection in bsconf.
* Made BYTE_ORDER and bswap always defined.
2005-06-28 Release 0.7-1
* Now compiles with gcc 4.0.0
* Standard exception constructors now take const char* instead
of string&; this generates much less code.
* Fixed reversed conditional ostringstream.format
This was causing a seek exception sometimes.
* Added ostringstream.vformat
* Added FPU registers to reset_mmx modlist; apparently gcc doesn't
know that they are shared with MMX registers.
* Moved simd copy into ualgobase.cc; they are not inlined anyway.
* Added workaround for BSD which has no __va_copy.
I wonder why nobody reported this as a bug. Is anyone running
BSD out there? Anyone? Anyone at all? Is the damn thing dead?
* So it now compiles on BSD again... Whoohoo...
2005-04-16 Release 0.7
* Removed vector inheritance from memblock.
There are just too many problems with treating a vector
this way. You can still do it explicitly by linking a
memblock to the vector. Removing the inheritance causes
vector to be non-virtual, which drastically reduces
instantiation cost.
* Removed elementSize, elementBytes member functions from cmemlink.
Only vector inheritance needed elementSize.
* Restricted vector link calls to T* instead of void*.
This way there would be explicit casts to warn of weirdness.
* Optimized vector push_back
* ostream will now zero bytes skipped by align.
* memblock will no longer zero newly allocated storage.
* Inlined empty constructors on map,multimap,set,multiset.
* NUMERIC_LIMITS macros to facilitate specialization.
* Fixed string vformat problem crashing on x86_64
Because vsnprintf is called twice, need to copy arglist.
* Added an rm before ln in install to avoid "already exists" errors.
SunOS still doesn't know about the -f flag...
* Split the distribution into ustl and ustl-docs
* New SIZE_OF_BOOL system substitution in bsconf
Only Alpha and Mac have bool as a long, so a define is better.
* Fixed configure being confused with multiple gcc versions.
* Reduced Align code for nonstandard values.
* Pulled up vector/tuple stream operators into generic container
templates in uctrstm.h and made use of resulting macros.
* New TEMPLATE_TYPE macros to allow template building with macros.
* Fixed SSE3 detection in bsconf; thanks to Aloysius Indrayanto.
* Fixed get_temporary_buffer to return size in elements, not in bytes.
This is the proper behaviour as specified in the C++ standard.
* Now using libc qsort in the sort algorithm.
This may give you trouble if you are using a custom comparator
that requires initialization outside the constructor. You can
write a wrapper class that does the initialization in the
constructor. Or, you can use stable_sort.
I'm doing this to both speed up the common case and to reuse
the functionality already linked to in libc. If you really
need to have a sort with a parametrized comparator and don't
want to change your code, file a bug report and I'll change
it back. I just don't think anyone is using this type of
construction.
* Finished heap algorithms.
* Added priority_queue.
* Added deque as a define to list.
* Added noalias template to circumvent the type-punned pointer
dereference warning given by gcc 4.1.0+
2005-01-17 Release 0.6
* The library is relicensed under the MIT License (was LGPL)
* Dropped support for locale due to its great complexity and ugliness.
You can include <locale> from libstdc++ if you still want it.
* ostringstream now uses snprintf for all integer types, so the output
will be localized according to libc locale settings. As a side
effect of this, you will not be able to print negative hex
numbers any more (as in -6AD4), not that it was a good idea...
* tuple will no longer align at the end:
This affects you if you write tuples with small elements
off default grain. For example, writing tuple<2,int16>
on grain 2 would have aligned prior to this change, causing
sub-optimal packing if you wrote an array of such tuples,
since each one only needs grain 2 alignment.
* Fixed incorrect use of __alignof__ in pair stream operators.
* Added size_t ul-or-ui detection code to bsconf and fixed the
size_t/pointer overload in uutility to use it.
* Added erase(iterator,const_iterator) overload for string
* Added alloca_link macro.
* cmemlink will now throw bad_alloc if linking to !p && n.
* multiset and multimap will insert equal elements in order.
I wasn't able to find any guidance concerning the order of
equal elements; it appears to be unspecified. Prior to this
change equal elements were inserted in reverse order, which
is bad idea because it causes a larger copy to make space.
(Note that multimap only compares the key, since the mapped
value is not required to have an operator<. If you want them
sorted, you can use sort() on it.)
* Fixed remove_copy algorithms to not require value operator !=.
* bool will now be written as a byte regardless of the type size.
* sistream now handles 64bit types correctly.
2004-11-11 Release 0.5
* configure will now properly enable mmx compiler flags.
* configure has a --with-profile option.
* Fixed a bug in ostringstream format inserting extra '\0'
* Fixed a bug in string find which sometimes did not match at the
beginning of the text.
* ostringstream will now use faster paged allocation.
* New alignof specializations for cmemlink(size_t) and string(1)
* Fixed tuple's value constructors to zero unspecified values.
* Added parentheses around ctr argument in foreach for computed vars.
* General simd interface for tuple optimization.
* Proper link interface in vector, that takes element count.
* set_terminate and set_unxpected prototypes are now available.
* LOOKUP_TEXT_STREAMABLE macro for printing through name arrays.
* Fixed iterator_swap to take iterators by value (reference& swap bad)
* Container random_shuffle.
* vformat method for string to allow implementation of custom printfs.
* TestAndSet inline utility function with the cmpxchg instruction.
* Fixed tuple stream_size_of to add up the elements if nonintegral.
* Added is_integral member to numeric_limits for specialization aid.
* Changed limits is_signed from a function to a bool like SGI does it.
2004-07-28 Release 0.4-3
* A ChangeLog! After all these years...
* SIMD instruction support for fill and copy
* matrix template (on top of tuple)
3dNow! instructions are supported for vector transforms.
* New utility templates
absv - absolute value.
sign - -1 for negative, 0 for 0, 1 for positive
abs_distance - returns an absolute value of the difference.
distance - now returns ptrdiff_t, as in SGI STL.
size_of_elements - useful for working with static arrays in
templates; returns sizeof(T) * n.
pack_type - useful for unrolling loops, packs a small
type into a big one.
alignof - recommended alignment for a type (uses GCC
__alignof__ extension, if available)
eachfor - same as foreach, but for reverse_iterator
* get_temporary_buffer implemented using alloca and macros
* Updated rotate to use alloca for small moves.
This should speed up vector operations, like insert and erase.
* Fixed copy_backward to actually copy backward rather than reverse.
* Made resize virtual in memblock to properly handle strings.
* sostream/sistream will handle wchar_t properly (as utf8 read/write)
* ustring.cc: fixed multiple wchar_t insert
* ustring.cc: changed allocation strategy to simply reserve the space
for the null terminator instead of tweaking size() all the
time. It's cleaner and saner this way.
* benchmarking tool in bvt
* More functions implemented in bitset.
* Added --with-static and --without-shared flags to configure.
2004-05-22 Release 0.4-2
* ostringstreams will now correctly resize the buffer as needed.
* Fixed floating point output
(well, not really, just switched to using snprintf)

750
extern/ustl/1.5/docs/index.html vendored Normal file
View File

@@ -0,0 +1,750 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>uSTL - the small STL library</title>
<link rel="stylesheet" type="text/css" href="style/default.css" />
<meta http-equiv="Content-Type" content="text/xhtml+xml; charset=ISO-8859-1" />
<meta name="Description" content="API and usage description for uSTL, a size-optimized STL implementation" />
<meta name="Keywords" content="C++, STL, template, bloat, optimization" />
<meta name="author" content="Mike Sharov" />
<meta name="date" content="2011-03-16" />
</head>
<body>
<div class="banner">
<h1>uSTL</h1>
<div class="motto">Candy for the optimization nut in you</div>
</div>
<hr class="banner" />
<h2><a name="Introduction">Introduction</a></h2>
<p>
The C++ standard template library (STL) is a collection of common
containers and algorithms in template form. Unfortunately its standard
incarnation shipped with gcc is implemented without much concern for code
size. Not only is the library itself large, the current version being
over a megabyte in size, but with all the code you instantiate by using a
vector for each of your containers, it is easy to become fearful and opt
for using static arrays instead or, worse yet, abandon C++ altogether
for C. This is especially painful to former DOS assembly programmers
like myself, who fret endlessly when the size of the executable crosses
the magic 64k boundary, forgetting that nobody cares about memory anymore.
</p><p>
Of course, these days everyone has gigabytes of RAM and has no compunction
about loading up OpenOffice, whose source tree is over a gigabyte in
size. Why then bother with saving a kilobyte of code here and there? I
can't really say. Maybe it's that warm fuzzy knowledge that you are making
maximum possible use of your computer's resources. Maybe it's that thrill
you get after expressing your program's functionality in the fewest
possible instructions and the minimum imaginable overhead. Or maybe it
really is of no importance and any code bloat will be easily overcome
by faster processors in some near future. I just know what I like, and
it's the sight of clean, concise, and fast code. Therefore this library.
</p>
<h2>Contents</h2>
<ul>
<li><a href="#Installation">Installation</a></li>
<li><a href="#Containers">Containers and Iterators</a></li>
<li><a href="#Strings">Strings</a></li>
<li><a href="#Algorithms">Algorithms</a></li>
<li><a href="#Memblocks">Memblock and Memlink</a></li>
<li><a href="#Streams">Streams</a></li>
<li><a href="#Tuples">Tuples</a></li>
<li><a href="#Exceptions">Exceptions</a></li>
<li><a href="#Savings">Template Bloat Be Gone</a></li>
<li><a href="#Contact">Bug reporting</a></li>
<li><a href="html/index.html">Doxygen reference</a></li>
</ul>
<h2><a name="Installation">Installation</a></h2>
<p>
To start with you'll need a decent compiler. Although uSTL will compile
under gcc 2.95, some features require at least gcc 3.4 and are simply
turned off with an older version. C++ support is vastly improved in
the recent compiler versions, and I strongly recommend gcc 4 for best
possible code.
</p><p>
The latest version of uSTL can always be downloaded from its SourceForge
<a href="https://sourceforge.net/project/showfiles.php?group_id=76798">project files page</a>.
If you like living dangerously, you can pull the working branch directly from
<a href="http://ustl.git.sourceforge.net/git/gitweb.cgi?p=ustl">git://ustl.git.sourceforge.net/gitroot/ustl/ustl</a>.
The mainline source should build on any unix-based system, including Linux,
BSD, MacOS, SunOS, and Solaris. A separate port for Symbian OS is maintained by
<a href="http://www.penrillian.com/index.php?option=com_content&amp;task=view&amp;id=82&amp;Itemid=73">Penrillian</a>.
Windows-based systems and weird embedded platforms, are not, and will
not be supported by the mainline. However, if you make a port, I'll be
happy to mention it here. After unpacking:
</p><pre>
./configure
make install
</pre><p>
<kbd>./configure --help</kbd> lists available build options.
You might want to specify a different installation prefix with
<kbd>--prefix=/usr</kbd>; the default destination is /usr/local.
Developers will want to build with <kbd>--with-debug</kbd> to get a
lot of assert error checking, which I highly recommend. If you have
gcc 4.4 or later, you may want to also use <kbd>--force-inline</kbd>
(see the bottom of this page for a fuller explanation). If you are the
type to edit configuration manually, it's in Config.mk and config.h. When
it's built, you can run the included tests with <kbd>make check</kbd>.
Finally, here's a simple hello world application:
</p><pre>
#include &lt;ustl.h&gt;
using namespace ustl;
int main (void)
{
cout &lt;&lt; "Hello world!\n";
return (EXIT_SUCCESS);
}
</pre><p>
If you have at least gcc 3.4, uSTL is built as a standalone library,
without linking to libstdc++ (except on BSD platforms where gcc does not
support it) Because g++ links to it by default, you'll need to link your
applications with gcc, or to pass <kbd>-nodefaultlibs -lc</kbd> to g++
if you want to use uSTL to completely replace libstdc++. This is where
the actual space savings happen. (If you want to see just how much you can
save, skip to the <a href="#Savings">Template Bloat Be Gone</a> section)
</p>
<h2><a name="Containers">Containers and Iterators</a></h2>
<p>
STL containers provide a generic abstraction to arrays, linked lists,
and other methods of memory allocation. They offer the advantages
of type-safety, the peace of mind that comes from never having to
malloc anything again, and a standard access API called iterators. Each
container's API is equivalent to that of a simple array, with iterators
being the equivalent of pointers into the array. The uniform access
API allows creation of standardized algorithms, discussed futher down,
that work on any container. Here are some examples of using vector,
the container representing a simple array:
</p><pre>
vector&lt;int&gt; v;
v.push_back (1);
v.push_back (2);
v[1] = 0;
v.erase (v.begin() + 1);
v.pop_back();
v.insert (v.begin(), 4);
v.resize (15);
</pre><p>
As you can see, a vector is basically the same thing as the arrays
you use now, except that it is resizable. The function names
ought to be self-explanatory with the exception of the addressing
arguments. You can do index addressing and get free bounds checking
with asserts. Incidentally, I highly recommend you work with a debug
build when writing code; uSTL is chock full of various asserts checking
for error conditions. In the optimized build, most such errors will be
silently ignored where possible and will cause crashes where not. That
is so because they are programmer errors, existing because you have a
bug in your code, not because the user did something wrong, or because
of some system failure. Programmer errors assert. User or system errors
throw exceptions.
</p><p>
Vectors are addressed with iterators, which are just like pointers (and
usually are). Calling begin() gives you the pointer to the first element,
calling end() gives you the pointer to the end of the last element. No,
not the last element, the end of it, or, more accurately, the end of the
array. It's that way so you can keep incrementing an iterator until it
is equal to the end() value, at which point you know you have processed
all the elements in the list. This brings me to demonstrate how you
ought to do that:
</p><pre>
foreach (vector&lt;int&gt;::iterator, i, v)
if (*i &lt; 5 || *i &gt; 10)
*i = 99;
</pre><p>
Although the foreach macro is a uSTL-only extension, it is a one-liner
you can easily copy out of uutility.h if you ever want to switch back to
regular STL. It is a great way to ensure you don't forget to increment
the counter or run past the end of the vector. The only catch to be aware
of, when inside an iterator loop, is that if you modify the container,
by adding or removing entries, you have to update the iterator, since the
container memory storage may have moved when resized. So, for example,
if you wish to remove certain types of elements, you'd need to do use
an index loop or something like:
</p><pre>
foreach (vector&lt;CEmployee&gt;::iterator, i, employees)
if (i-&gt;m_Salary &gt; 50000 || i-&gt;m_Performance &lt; 100)
--(i = employees.erase (i));
</pre><p>
This is pretty much all there is to say about containers. Create them,
use them, resize them, that's what they are for. There are other
container types, but you will probably not use them much. There's
<code>set</code>, which is a perpetually sorted vector, useful when you
want to binary_search a large collection. There's <code>map</code> which
is an associative container where you can look up entries by key. Its
utility goes down drastically when you have complex objects that need to
be searched with more than one parameter, in which cast you are better
off with vector and foreach. I have never needed the others, and do
not recommend their use. Their implementations are fully functional,
but do not conform to STL complexity guarantees and are implemented as
aliases to vector, which naturally changes their performance parameters.
</p>
<h2><a name="Strings">Strings</a></h2>
<p>
Every program uses strings, and STL was kind enough to provide a
specification. uSTL deviates a bit from the standard by not implementing
wchar strings. There is only one <code>string</code> class, which assumes
all your strings will be UTF8-encoded, and provides some additional
functionality to make working with those easier. I did that for the same
reason I dropped the locale classes; bloat. It is simply too expensive to
implement the standard locale classes, as the enormous size of libstdc++
illustrates. If you need them, you can still include them from libstdc++,
but it may be just as simple to use the locale support provided by libc
through printf, which may be called through <code>format</code> functions
in string and ostringstream.
</p><p>
Anyway, back to strings. You can think of the string object as a
char vector with some additional operations built-in, like searching,
concatenation, etc.
</p><pre>
string s ("Hello");
s += ' ';
s += "world?";
s.replace (s.find ('?'), 1, "!");
s[3] = s[s.find_first_of("lxy")];
s[s.rfind('w')] = 'W';
s.format ("A long %zd number of 0x%08lX\n", 345u, 0x12345);
cout &lt;&lt; s &lt;&lt; endl;
</pre><p>
A nonstandard behaviour you may encounter is from linked strings created
by the string constructor when given a null-terminated const string. In
the above example, the constructor links when given a const string and
stays as a const link until the space is added. If you try to write to it,
you'll get an assert telling you to use copy_link first to convert the
link into a copy. Resizing the linked object automatically does that for
you, so most of the time it is transparent. You may also encounter another
instance of this if you try getting iterators from such an object. The
compiler uses the non-const accessors by default for local objects,
so you may need to declare it as a const string if you don't wish to
copy_link. Why does uSTL string link instead of copying? To save space
and time. All those strings are already in memory, so why waste heap
space and processor time to copy them if you just want to read them? I
thought it a good tradeoff, considering that it is trasparent for the
most common uses.
</p><p>
Other nonstandard extensions include a <code>format</code> function to
give you the functionality of sprintf for string objects. Another is
the UTF8 stuff. Differing a bit from the standard, <code>size</code>
returns the string length in bytes, <code>length</code> in characters.
You can iterate by characters instead of bytes with a special utf8
iterator:
</p><pre>
for (string::utf8_iterator i = s.utf8_begin(); i &lt; s.utf8_end(); ++ i)
DrawChar (*i);
</pre><p>
or just copy all the chars into an array and iterate over that:
</p><pre>
vector&lt;wchar_t&gt; result (s.length());
copy (s.utf8_begin(), s.utf8_end(), result.begin());
</pre><p>
To write wide characters to the string, wchar_t values can be directly
given to push_back, insert, append, or assign, in the same way as the
char ones.
</p><p>
A few words must be said regarding reading wide characters. The shortest
possible rule to follow is "don't!" I have received a few complaints about
the fact that all offsets given to and returned by string functions are
byte offsets and not character offsets. The problem with modifying or even
looking for specific wide characters is that you are not supposed to know
what they are. Your strings will be localized into many languages and it
is impossible for you to know how the translation will be accomplished.
As a result, whenever you are hardcoding a specific character value,
or a specific character length (like a three-character extension),
you are effectively hardcoding yourself into a locale. The only valid
operation on localized strings is parsing it via standard delimiters,
treating anything between those delimiters as opaque blocks. For this
reason, whenever you think you need to do something at a particular
character offset, you should recognize it as a mistake and find the
offset by the content that is supposed to be there.
</p><p>
If this philosophy is consistently followed, it becomes clear that
actual character boundaries are entirely irrelevant. There are only
two exceptions to this: first occurs if you are writing a text editor
and want to insert user data at a character position, the second occurs
if you are writing a font renderer and want to translate characters to
glyphs. In both cases you should make use of the utf8_iterator to find
character boundaries and values. Given that these two cases apply to
just a handful of people who are involved in implementing user interface
frameworks, I believe that the opacity restriction is well justified by
the amount of code space it saves for the vast majority of library users.
</p>
<h2><a name="Algorithms">Algorithms</a></h2>
<p>
Algorithms are the other half of STL. They are simply templated common
tasks that take iterator arguments, and as a result, work with any
container. Most will take an iterator range, like (v.begin(), v.end()),
but you can, of course operate on a subset of a container by giving a
different one. Because the usual operation is to use the whole container,
uSTL provides versions of most algorithms that take container arguments
instead of the iterator range. Here are the algorithms you will actually
find useful:
</p><pre>
copy (v1, v2.begin()); // Copies vector v1 to vector v2.
fill (v, 5); // Fills v with fives.
copy_n (v1, 5, v2.begin()); // Copies first five elements only.
fill_n (v.begin() + 5, 10, 5); // Fills elements 5-15 with fives.
sort (v); // Sorts v.
find (v, 14); // Finds 14 in v, returning its iterator.
binary_search (v, 13); // Looks up 13 with binary search in a sorted vector.
lower_bound (v, 13); // Returns the iterator to where you want to insert 13.
iota (v.begin(), v.end(), 0); // Puts 0,1,2,3,4,... into v.
reverse (v); // Reverses all the elements in v.
</pre><p>
The rest you can discover for yourself. There are obscure mathematical
operations, like inner_product, set operations, heap operations, and
lots and lots of predicate algorithms. The latter are algorithms that
take a functor (an object that can be called like a function) and were
supposed to help promote code reuse by encapsulating common operations.
For example, STL expects you to use the <code>for_each</code> algorithm and
write a little functor for all your iterative tasks:
</p><pre>
class CCompareAndReplace {
public:
CCompareAndReplace (int minValue, int maxValue, int badValue)
: m_MinValue (minValue), m_MaxValue (maxValue), m_BadValue (badValue) {}
void operator (int&amp; v) {
if (v &lt; m_MinValue || v &gt; m_MaxValue)
v = m_BadValue;
}
private:
int m_MinValue;
int m_MaxValue;
int m_BadValue;
};
for_each (v.begin(), v.end(), CCompareAndReplace (5, 10, 99));
</pre><p>
And yes, it really does work. Doesn't always generate much bloat either,
since the compiler can often see right through all this trickery and
expand the for_each into a loop without actually creating the functor
object. However, the compiler has a much harder time when you start
using containers of complex objects or operating on member variables
and member functions. Since that is what you will most likely have in
any real code outside the academic world, the utility of predicate
algorithms is questionable. Their readability is even more so,
considering that the above fifteen line example can be written as a
three line iterative foreach loop. Finally, there is the problem of
where to put the functor. It just doesn't seem to "belong" anywhere in
the object-oriented world. (C++0x changes that somewhat with lambda
functions) Sorry, Stepanov, I just don't see how these things can be
anything but an ugly, bloated hindrance.
</p>
<h2><a name="Memblocks">Memblocks and Memlinks</a></h2>
<p>
The STL specification is only about containers and algorithms, the stuff
described from here on is totally non-standard, so by using them you'll
have to stick with uSTL as your STL implementation. I think it's worth
it, but, of course, the choice is up to you.
</p><p>
The major difference between the standart STL implementation and uSTL is
that the former has memory management stuff all over the place, while
the latter keeps it all together in the <code>memblock</code> class. Normally
STL containers are resized by calling <code>new</code> to create more storage
and then copying the elements there from the old one. This method wastes
space by fragmenting memory, wastes time by copying all the existing data
to the new location, and wastes codespace by having to instantiate all
the resizing code for each and every container type you have. This method
is also absolutely necessary to do this resizing in a perfectly object-safe
way. The uSTL way is to manage memory as an opaque, typeless block, and
then use the container templates to cast it to an appropriate pointer type.
</p><p>
This works just fine, except for one little catch: there is one type
of object you can't store in uSTL containers -- the kind that has pointers
to itself. In other implementations, resizing actually creates new objects
in the new location and destroys them in the old location. uSTL simply
memcpys them there without calling the copy constructor. In other words,
the object can not rely on staying at the same address. Most objects really
don't care. Note that this is not the same thing as doing a bitwise copy,
that you were rightly warned against before! It's a bitwise <em>move</em>
that doesn't create a new object, but simply relocates an existing one.
</p><p>
What this one small concession does is allow aggregation of all memory
management in one place, namely, the <code>memblock</code> class. All the
containers are thus converted mostly into typecasting wrappers that
exist to ensure type safety. Look at the assembly code and you'll see
mostly calls to memblock's functions. This is precisely the feature
that allows reduction in code instantiated by container templates.
</p><p>
However, memblock's usefulness doesn't end there! It can now replace
all your dynamically allocated buffers that you use for unstructured
data. Need to read a file? Don't use new to allocate memory; use a
memblock! It even has a friendly read_file member function for just
that purpose. Need to write a file? Use the write_file call! Unless
you are working with a database or some really large archive, you
should be able to load all your files this way. Imagine, not having
to worry about file I/O again! It's much nicer to work with data in
memory; you know how long it is, so you know when to stop. You can
seek with impunity, and any operations have the cost of a memcpy.
</p><p>
Memblock is derived from memlink, an object for linking to a memory
block. Now you get to store a pointer and the size of whatever it
points to, but with uSTL you can use a memlink object to keep them
together, reducing source clutter and making your code easier to
read and maintain. You can link to constant blocks too with cmemlink,
from which memlink is derived. Because all three are in a single
hierarchy, you never need to care whether you're working on an
allocated block or on somebody else's allocated block. Pointers are
kept together with block sizes, memory is freed when necessary,
and you never have to call new or delete again. Who needs garbage
collection? Memblocks give you the same functionality at a fraction
of the cost.
</p><p>
Linking is not limited to memlink. You can link memblock objects.
You can link string objects. You can even link containers! Now
you can use alloca to create a vector on the stack; use the
<code>typed_alloca_link(v,int,99)</code> macro. All linked objects
will allocate memory and copy the linked data when you increase their
size. You can also do it explicitly by calling <code>copy_link</code>.
Why link? It's cheaper than copying and easier than keeping track
of pointers. For example, here's a line parser:
</p><pre>
string buf, line;
buf.read_file ("some_config_file.txt");
for (uoff_t i = 0; i &lt; buf.size(); i += line.size() + 1) {
line.link (buf.iat(i), buf.iat (buf.find ('\n',i)));
process_line (line);
}
</pre><p>
This way process_line gets a string object instead of a pointer and
a size. If you don't rely on the string being null-terminated, which
basically means not using libc functions on it, this is all you need.
Otherwise buf will have to be writable and you can replace the newline
with a null. In either case you are using no extra heap. The overhead
of link is negligible in most cases, but if you really want to do this
in a tight loop, you can use relink call, which expands completely
inline into one or two instructions, avoiding the virtual unlink() call.
</p>
<h2><a name="Streams">Streams</a></h2>
<p>
The C++ standard library provides global stream objects called cin,
cout, and cerr to replace printf and friends for accessing stdin, stdout,
and stderr, respectively. uSTL versions work mostly the same as the
standard ones (yes, the <code>format</code> call is a uSTL extension). Most
calls use snprintf for output and thus use whatever locale libc uses.
</p><pre>
cout &lt;&lt; "Hello world!" &lt;&lt; endl;
cout &lt;&lt; 456 &lt;&lt; ios::hex &lt;&lt; 0x1234 &lt;&lt; endl;
cerr.format ("You objects are at 0x%08X\n", &amp;o);
</pre><p>
String-writing streams are also available:
</p><pre>
ostringstream os;
os &lt;&lt; "Writing " &lt;&lt; n &lt;&lt; " objects somewhere" &lt;&lt; endl;
cout &lt;&lt; os.str() &lt;&lt; endl;
</pre><p>
fstream is a file access interface with exception handling for errors:
</p><pre>
fstream f;
// C++ standard says that fstream does not throw by default,
f.exceptions (fstream::allbadbits); // so this enables throwing.
f.open ("file.dat", ios::in | ios::out); // throws file_exception
f.read (buf, bufSize); // let's read something
f.seek (334455); // go somewhere
f.write (buf2, buf2Size); // and write something
f.fnctl (FCNTLID(F_SETFL), O_NONBLOCK); // yup, ALL file operations
memlink l = f.mmap (bufSize, offset); // even mmap
fill (l, 0);
f.msync (l);
f.munmap (l);
f.close(); // also throws file_exception (with filename!)
</pre><p>
istream and ostream, which are not really usable by themselves in the
standard implementation, are hijacked by uSTL to implement binary data
input and output:
</p><pre>
const size_t writtenSize =
Align (stream_size_of(number) +
stream_size_of(ctr)) +
stream_size_of(n) +
stream_size_of(v);
memblock buf (writtenSize);
ostream os (buf);
os &lt;&lt; number &lt;&lt; ctr;
os.align();
os &lt;&lt; n &lt;&lt; v;
</pre><p>
These operations are all very efficient, approaching a straight memcpy
in performance. ostream will not resize the buffer, hence the necessity
to estimate the final size. Most stream_size_of calls are computed at
compile time and thus produce no code. Because the data is written as
is, it is necessary to consider proper data alignment; for example,
a 4 byte int can not be written at stream offset 2. Some architectures
(Macs) actually crash when doing it; Intel processors just do it slowly.
Hence the need to pack the data to a proper "grain". The default align
call will pack to the maximum necessary grain, but can be given an
argument to change that. In case you're wondering, the reason for all
these idiosyncracies is optimization. The smallest and fastest possible
code to dump your stuff into a binary file is produced by this method.
uSTL defines flow operators to write integral values, strings, and
containers, but you can custom-serialize your objects like this:
</p><pre>
namespace myns {
/// Some class I want to serialize
class CMyClass {
public:
void read (istream&amp; is);
void write (ostream&amp; os) const;
size_t stream_size (void) const;
private:
vector&lt;int&gt; m_Elements; ///&lt; A bunch of elements.
size_t m_SomeSize; ///&lt; Some integral value.
MyObject m_SomeObject; ///&lt; Some other streamable object.
}
/// Reads the object from stream \p is.
void CMyClass::read (istream&amp; is)
{
is &gt;&gt; m_Elements &gt;&gt; m_SomeSize &gt;&gt; m_SomeObject;
}
/// Writes the object to stream \p os.
void CMyClass::write (ostream&amp; os) const
{
os &lt;&lt; m_Elements &lt;&lt; m_SomeSize &lt;&lt; m_SomeObject;
}
/// Returns the size of the written object.
size_t CMyClass::stream_size (void) const
{
return (stream_size_of (m_Elements) +
stream_size_of (m_SomeSize) +
stream_size_of (m_SomeObject));
}
} // namespace myns
</pre>
<h2><a name="Tuples">Tuples</a></h2>
<p>
One last container I'll mention is a <code>tuple</code>, which is a
fixed-size array of identical elements. No, it's not the same as the tuple
in boost, which is more like a template-defined struct. This one should
have been named "array", which is what it will be called in the next STL
standard, but I guess I'm stuck with the name now. What are they good
for? Graphical objects. Points, sizes, rectangles, triangles, etc. As a
bonus, operations on tuples can automatically use SIMD instructions if
they are available. Any fixed size-array also works better as a tuple,
since it becomes a standard STL container, which you can use with any
algorithm, copy by assignment, initialize in the constructor, etc.
</p><pre>
typedef int32_t coord_t;
typedef tuple&lt;2, coord_t&gt; Point2d;
typedef tuple&lt;2, coord_t&gt; Size2d;
typedef tuple&lt;2, Point2d&gt; Rect;
Rect r (Point2d (1,2), Point2d (3,4));
r += Size2d (4, 4);
r[1] -= Size2d (1, 1);
foreach (Rect::iterator, i, r)
TransformPoint (*i);
Point2d pt (1, 2);
pt += r[0];
pt *= 2;
</pre>
<h2><a name="Exceptions">Exceptions</a></h2>
<p>
uSTL implements all the standard exception classes defined by the
C++ standard. The exception tree is standalone, but is derived
from std::exception when compiling with libstdc++ for ease of
catching everything. uSTL exceptions implement some additional useful
features. First, they are completely serializable. You can write them
as a binary blob into a file, send them over a network, and handle them
somewhere else. Each exception will print an informative error message
directly to a text stream, reducing your try/catch block to:
</p><pre>
try {
DoSomething();
} catch (exception&amp; e) {
cerr &lt;&lt; "Error: " &lt;&lt; e &lt;&lt; endl;
#ifndef NDEBUG
cerr &lt;&lt; e.backtrace();
#endif
} catch (...) {
cerr &lt;&lt; "Unexpected fatal error has occured.\n";
}
</pre><p>
Second, each exception stores a backtrace (callstack) at the time
of throwing and can print that backtrace as easily as the above
example illustrates. While it is indeed a good practice to design
your exceptions so that you should not care where it was thrown from,
situations occasionally arise while debugging where knowing the thrower
is useful to fix the bug a little faster than otherwise.
</p><p>
Finally, there are additional exception classes for dealing with libc
function errors, file errors, and stream classes. libc_exception can
be thrown whenever a libc function fails, immediately telling you
what the function call was and the errno description of the failure.
file_exception, thrown by fstream operations, also contains the file name,
which can be pretty darn useful. stream_bounds_exception is extremely
useful in debugging corrupted data, as it tells you exactly where the
corruption starts and what you were trying to read there.
</p>
<h2><a name="Savings">Template Bloat Be Gone</a></h2>
<p>
So how much space are you going to save and where? Allow me to demonstrate with
the following small program. I'm basically creating a vector and exercise the
most common operations. Those are resize, push_back, insert, and erase, which
you use pretty much every time you have a vector.
</p><pre>
#if USING_USTL
#include &lt;ustl.h&gt;
using namespace ustl;
#else
#include &lt;vector&gt;
using namespace std;
#endif
int main (void)
{
vector&lt;int&gt; v;
v.resize (30);
for (size_t i = 0; i &lt; v.size(); ++ i)
v[i] = i;
v.push_back (57);
v.insert (v.begin() + 20, 555);
v.erase (v.begin() + 3);
return (EXIT_SUCCESS);
}
</pre><p>
Feel free to compile it and see for yourself. I'm compiling on a Core
i7 with gcc 4.5.2 and <kbd>-Os -DNDEBUG=1</kbd>. The libstdc++ version
is linked implicitly with it, and uSTL version is linked with gcc
(instead of g++) and <kbd>-lustl</kbd>. Both executables are stripped.
The libstdc++ version looks like this:
</p><pre>
% ls -l std/tes
7096 tes
% size std/tes
text data bss dec hex filename
3780 632 16 4428 114c std/tes
% size -A std/tes.o
std/tes.o :
section size
.group 8
.group 8
.group 8
.group 8
.group 8
.group 8
.group 8
.group 8
.group 8
.group 8
.group 8
.text 256
.data 0
.bss 0
.text._ZNSt6vectorIiSaIiEED2Ev 8
.text._ZNKSt6vectorIiSaIiEE12_M_check_lenEmPKc 68
.text._ZNSt11__copy_moveILb0ELb1ESt26random_access_iterator_tagE8__copy_mIiEEPT_PKS3_S6_S4_ 51
.text._ZSt14__copy_move_a2ILb0EN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEES6_ET1_T0_S8_S7_ 14
.text._ZSt4copyIN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEES6_ET0_T_S8_S7_ 14
.text._ZNSt20__copy_move_backwardILb0ELb1ESt26random_access_iterator_tagE13__copy_move_bIiEEPT_PKS3_S6_S4_ 63
.rodata.str1.1 45
.text._ZNSt6vectorIiSaIiEE14_M_fill_insertEN9__gnu_cxx17__normal_iteratorIPiS1_EEmRKi 355
.text._ZNSt6vectorIiSaIiEE6resizeEmi 64
.text._ZNSt6vectorIiSaIiEE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi 195
.text._ZNSt6vectorIiSaIiEE9push_backERKi 46
.text._ZNSt6vectorIiSaIiEE6insertEN9__gnu_cxx17__normal_iteratorIPiS1_EERKi 79
.gcc_except_table 14
.comment 40
.note.GNU-stack 0
.eh_frame 576
Total 1976
</pre><p>
The uSTL version looks like this:
</p><pre>
% ls -l ustl/tes
5720 tes
% size ustl/tes
text data bss dec hex filename
2435 616 16 3067 bfb ustl/tes
% size -A ustl/tes.o
ustl/tes.o :
section size addr
.text 327 0
.data 0 0
.bss 0 0
.gcc_except_table 19 0
.comment 40 0
.note.GNU-stack 0 0
.eh_frame 88 0
Total 474
</pre><p>
Let's see what's going on here. The .text size in the std version is
smaller, indicating less inlined functionality. This version of gcc
libstdc++ instantiates additional eleven functions totalling 953 bytes
just for this one vector type. These functions will become larger for
containers with objects, but about 1k in savings that you see as the
difference in execuable size is a good measure. The uSTL version inlines
everything and calls memblock functions instead.
</p><p>
1k doesn't seem like much, but consider that you get it for <em>every
type of container you instantiate</em>! An int vector here, a float
vector here, a bunch of object containers there, and before you know it
you are using half your executable just for container overhead.
</p><p>
But wait, there is more! Let's look at the total memory footprint:
</p><pre>
% footprint std/tes
text data bss dec hex filename
3780 632 16 4428 114c tes
84445 928 632 86005 14ff5 libgcc_s.so.1
527390 720 72 528182 80f36 libm.so.6
962481 34816 84664 1081961 108269 libstdc++.so.6
1404487 18024 20032 1442543 1602ef libc.so.6
2982583 55120 105416 3143119 2ff5cf (TOTALS)
% footprint ustl/tes
text data bss dec hex filename
2435 616 16 3067 bfb tes
84445 928 632 86005 14ff5 libgcc_s.so.1
152800 10408 73248 236456 39ba8 libustl.so.1.5
1404487 18024 20032 1442543 1602ef libc.so.6
1644167 29976 93928 1768071 1afa87 (TOTALS)
</pre><p>
As you can see, the footprint for the uSTL version is 44% smaller,
saving 1375048 bytes. If you don't count libc, measuring only the
C++-specific overhead, libstdc++ loads 1696148 while libustl only 322461,
<em>five times less</em>! Finally, most of uSTL's size comes from gcc's
support libraries; if you compile uSTL configured <kbd>--with-libstdc++</kbd>
option, then you'll see that it only takes up 72322 bytes, of which only
23350 are used by .text, meaning that only about a third of the library
size is my fault. gcc developers will have to reduce the size of libsupc++
before any further size reduction would be practical.
</p><p>
One final note concerns the current gcc versions, 4.4 and later. gcc
developers have decided, for various reasons, to treat the inline keyword
as nothing more than a hint to the optimizer, resulting in a lot less
inlining for uSTL-using code. You can see which functions fail to inline
if you turn on -Winline warning. Back in gcc 3 days there were various
parameters that could be tweaked to get the inlining to happen. These no
longer seem to work. Because it takes quite a bit of code to make these
failures happen, I am unable to submit a gcc bug for it. Simple examples
don't exhibit inlining failures and submitting the entire uSTL codebase
seems inappropriate. Therefore I've pretty much given up on it. The only
solution I can come up with is to just clobber the optimizer over the head
with <code>#define inline __attribute__((always_inline)) inline</code>. It
is enabled if you configure with <kbd>--force-inline</kbd>. The above
examples are compiled with this option.
</p>
<h2><a name="Contact">Bug reporting</a></h2>
<p>
Report bugs through the SourceForge.net
<a href="http://sourceforge.net/projects/ustl">uSTL project page</a> with the
standard bugtracker.
</p>
<hr />
<div class="sffooter">
<a href="http://validator.w3.org/check?uri=referer">
<img src="style/valid-xhtml10.png"
height="31" width="88" alt="Valid XHTML 1.0!" />
</a>
<a href="http://sourceforge.net">
<img src="http://sourceforge.net/sflogo.php?group_id=76798&amp;type=4"
width="127" height="37" alt="Hosted on SourceForge.net" />
</a>
</div>
</body>
</html>

3
extern/ustl/1.5/docs/robots.txt vendored Normal file
View File

@@ -0,0 +1,3 @@
User-agent: *
Disallow: /style/
Sitemap: /sitemap.xml

15
extern/ustl/1.5/docs/sitemap.xml vendored Normal file
View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://ustl.sourceforge.net/</loc>
<changefreq>yearly</changefreq>
<lastmod>2011-03-16</lastmod>
<priority>1.0</priority>
</url>
<url>
<loc>http://ustl.sourceforge.net/html/</loc>
<changefreq>yearly</changefreq>
<lastmod>2011-03-16</lastmod>
<priority>0.2</priority>
</url>
</urlset>

27
extern/ustl/1.5/docs/style/default.css vendored Normal file
View File

@@ -0,0 +1,27 @@
body {
font-family: sans-serif;
color: black;
background-color: #59C;
margin: 5mm
}
div.banner {
color: black;
background-color: #48B;
text-align: center;
font-size: 1cm;
padding: 1mm;
margin-top: -5mm;
margin-left: -5mm;
margin-right: -5mm;
margin-bottom: 5mm
}
div.motto {
color: #159;
font-style: italic;
font-size: 2mm;
margin-top: -5mm
}
div.sffooter { text-align: right }
a:link { color: #238 }
a:visited { color: #632 }
hr.banner { display: none }

View File

@@ -0,0 +1,28 @@
h1 { text-align: center; }
a.elRef, a.el, caption { font-weight: bold }
a.code, a.el { text-decoration: none }
a.code, a.codeRef { color: #4444ee }
dl.el { margin-left: -1cm }
div.fragment { width: 100%; border: none; background-color: #eeeeee }
div.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px }
div.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold }
div.groupText { margin-left: 16px; font-style: italic; font-size: smaller }
td.md, td.mdname1, td.mdname, td.indexkey { font-weight: bold }
td.indexvalue { font-style: italic }
td.indexkey, td.indexvalue {
padding-right : 10px;
padding-top : 2px;
padding-left : 10px;
padding-bottom : 2px;
margin-left : 0px;
margin-right : 0px;
margin-top : 2px;
margin-bottom : 2px
}
span.keyword { color: #008000 }
span.keywordtype { color: #604020 }
span.keywordflow { color: #e08000 }
span.comment { color: #800000 }
span.preprocessor { color: #806020 }
span.stringliteral { color: #002080 }
span.charliteral { color: #008080 }

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

18
extern/ustl/1.5/docs/ustl.lsm vendored Normal file
View File

@@ -0,0 +1,18 @@
Begin4
Title: uSTL
Version: @version@
Entered-date: @date@
Description: A size-optimized implementation of the C++ STL.
This implementation of the standard template library
reduces template bloat by factoring out memory
management functionality from STL containers
and using templates for type safety only.
Keywords: C++ STL standard template library size optimized bloat
Author: msharov@users.sourceforge.net (Mike Sharov)
Maintained-by: msharov@users.sourceforge.net (Mike Sharov)
Primary-site: ibiblio.org /pub/linux/devel/lang/c++
@disttar@
Alternate-site: http://ustl.sourceforge.net
Platforms: POSIX
Copying-policy: MIT
End

15
extern/ustl/1.5/docs/ustlfooter.html vendored Normal file
View File

@@ -0,0 +1,15 @@
<hr>
<address style="align: right;">
<small>
Generated on $datetime for $projectname by $doxygenversion
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="Doxygen" align="middle" border=0 width=110 height=53>
</a>
<a href="http://sourceforge.net">
<img src="http://sourceforge.net/sflogo.php?group_id=76798&amp;type=4"
width="127" height="37" border="0" alt="Hosted on SourceForge.net">
</A>
</small>
</address>
</body>
</html>

12
extern/ustl/1.5/docs/ustlheader.html vendored Normal file
View File

@@ -0,0 +1,12 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>$title</title>
<link href="../style/default.css" rel="stylesheet" type="text/css" />
<link href="../style/ustlstyle.css" rel="stylesheet" type="text/css" />
<meta http-equiv="Content-Type" content="text/xhtml+xml; charset=ISO-8859-1" />
<meta name="Description" content="API and usage description for uSTL, a size-optimized STL implementation" />
<meta name="Keywords" content="C++, STL, template, bloat, optimization" />
</head>
<body>

259
extern/ustl/1.5/fstream.cc vendored Normal file
View File

@@ -0,0 +1,259 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "fstream.h"
#include "uexception.h"
#include "uutility.h"
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
namespace ustl {
/// Default constructor.
fstream::fstream (void)
: ios_base (),
m_fd (-1),
m_Filename ()
{
exceptions (goodbit);
}
/// Opens \p filename in \p mode.
fstream::fstream (const char* filename, openmode mode)
: ios_base (),
m_fd (-1),
m_Filename ()
{
exceptions (goodbit);
open (filename, mode);
}
/// Attaches to \p nfd of \p filename.
fstream::fstream (int nfd, const char* filename)
: ios_base (),
m_fd (-1),
m_Filename ()
{
exceptions (goodbit);
attach (nfd, filename);
}
/// Destructor. Closes if still open, but without throwing.
fstream::~fstream (void) throw()
{
clear (goodbit);
exceptions (goodbit);
close();
assert (!(rdstate() & badbit) && "close failed in the destructor! This may lead to loss of user data. Please call close() manually and either enable exceptions or check the badbit.");
}
/// Sets state \p s and throws depending on the exception setting.
void fstream::set_and_throw (iostate s, const char* op)
{
if (ios_base::set_and_throw (s))
throw file_exception (op, name());
}
/// Attaches to the given \p nfd.
void fstream::attach (int nfd, const char* filename)
{
assert (filename && "Don't do that");
m_Filename = filename;
clear (goodbit);
if (nfd < 0)
set_and_throw (badbit, "open");
close();
m_fd = nfd;
}
/// Detaches from the current fd.
void fstream::detach (void)
{
m_fd = -1;
m_Filename.clear();
}
/// Converts openmode bits into libc open flags.
/*static*/ int fstream::om_to_flags (openmode m)
{
static const int s_OMFlags [nombits] = {
0, // in
O_CREAT, // out
O_APPEND, // app
O_APPEND, // ate
0, // binary
O_TRUNC, // trunc
O_NONBLOCK, // nonblock
0, // nocreate
O_NOCTTY // noctty
};
int flags = (m - 1) & O_ACCMODE; // in and out
for (uoff_t i = 0; i < VectorSize(s_OMFlags); ++ i)
flags |= s_OMFlags[i] & (!(m & (1 << i)) - 1);
if (m & nocreate)
flags &= ~O_CREAT;
return (flags);
}
/// \brief Opens \p filename in the given mode.
/// \warning The string at \p filename must exist until the object is closed.
void fstream::open (const char* filename, openmode mode, mode_t perms)
{
int nfd = ::open (filename, om_to_flags(mode), perms);
attach (nfd, filename);
}
/// Closes the file and throws on error.
void fstream::close (void)
{
if (m_fd < 0)
return; // already closed
while (::close(m_fd)) {
if (errno != EINTR) {
set_and_throw (badbit | failbit, "close");
break;
}
}
detach();
}
/// Moves the current file position to \p n.
off_t fstream::seek (off_t n, seekdir whence)
{
off_t p = lseek (m_fd, n, whence);
if (p < 0)
set_and_throw (failbit, "seek");
return (p);
}
/// Returns the current file position.
off_t fstream::pos (void) const
{
return (lseek (m_fd, 0, SEEK_CUR));
}
/// Reads \p n bytes into \p p.
off_t fstream::read (void* p, off_t n)
{
off_t br (0);
while ((br < n) & good())
br += readsome (advance (p, br), n - br);
return (br);
}
/// Reads at most \p n bytes into \p p, stopping when it feels like it.
off_t fstream::readsome (void* p, off_t n)
{
ssize_t brn;
do { brn = ::read (m_fd, p, n); } while ((brn < 0) & (errno == EINTR));
if (brn > 0)
return (brn);
else if ((brn < 0) & (errno != EAGAIN))
set_and_throw (failbit, "read");
else if (!brn && ios_base::set_and_throw (eofbit | failbit))
throw stream_bounds_exception ("read", name(), pos(), n, 0);
return (0);
}
/// Writes \p n bytes from \p p.
off_t fstream::write (const void* p, off_t n)
{
off_t btw (n);
while (btw) {
const off_t bw (n - btw);
ssize_t bwn = ::write (m_fd, advance(p,bw), btw);
if (bwn > 0)
btw -= bwn;
else if (!bwn) {
if (ios_base::set_and_throw (eofbit | failbit))
throw stream_bounds_exception ("write", name(), pos() - bw, n, bw);
break;
} else if (errno != EINTR) {
if (errno != EAGAIN)
set_and_throw (failbit, "write");
break;
}
}
return (n - btw);
}
/// Returns the file size.
off_t fstream::size (void) const
{
struct stat st;
st.st_size = 0;
stat (st);
return (st.st_size);
}
/// Synchronizes the file's data and status with the disk.
void fstream::sync (void)
{
if (fsync (m_fd))
set_and_throw (badbit | failbit, "sync");
}
/// Get the stat structure.
void fstream::stat (struct stat& rs) const
{
if (fstat (m_fd, &rs))
throw file_exception ("stat", name());
}
/// Calls the given ioctl. Use IOCTLID macro to pass in both \p name and \p request.
int fstream::ioctl (const char* rname, int request, long argument)
{
int rv = ::ioctl (m_fd, request, argument);
if (rv < 0)
set_and_throw (failbit, rname);
return (rv);
}
/// Calls the given fcntl. Use FCNTLID macro to pass in both \p name and \p request.
int fstream::fcntl (const char* rname, int request, long argument)
{
int rv = ::fcntl (m_fd, request, argument);
if (rv < 0)
set_and_throw (failbit, rname);
return (rv);
}
/// Memory-maps the file and returns a link to it.
memlink fstream::mmap (off_t n, off_t offset)
{
void* result = ::mmap (NULL, n, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, offset);
if (result == MAP_FAILED)
set_and_throw (failbit, "mmap");
return (memlink (result, n));
}
/// Unmaps a memory-mapped area.
void fstream::munmap (memlink& l)
{
if (::munmap (l.data(), l.size()))
set_and_throw (failbit, "munmap");
l.unlink();
}
/// Synchronizes a memory-mapped area.
void fstream::msync (memlink& l)
{
if (::msync (l.data(), l.size(), MS_ASYNC | MS_INVALIDATE))
set_and_throw (failbit, "msync");
}
void fstream::set_nonblock (bool v)
{
int curf = max (0, fcntl (FCNTLID (F_GETFL)));
if (v) curf |= O_NONBLOCK;
else curf &= ~O_NONBLOCK;
fcntl (FCNTLID (F_SETFL), curf);
}
} // namespace ustl

75
extern/ustl/1.5/fstream.h vendored Normal file
View File

@@ -0,0 +1,75 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 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))); }
memlink mmap (off_t n, off_t offset = 0);
void munmap (memlink& l);
void msync (memlink& l);
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

150
extern/ustl/1.5/memblock.cc vendored Normal file
View File

@@ -0,0 +1,150 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "mistream.h"
#include "memblock.h"
#include "ualgo.h"
#include "umemory.h"
#include "fstream.h"
#include <errno.h>
namespace ustl {
memblock::memblock (void) : memlink (), m_Capacity (0) { }
memblock::memblock (const void* p, size_type n) : memlink (), m_Capacity (0) { assign (p, n); }
memblock::memblock (size_type n) : memlink (), m_Capacity (0) { resize (n); }
memblock::memblock (const cmemlink& b) : memlink (), m_Capacity (0) { assign (b); }
memblock::memblock (const memlink& b) : memlink (), m_Capacity (0) { assign (b); }
memblock::memblock (const memblock& b) : memlink (), m_Capacity (0) { assign (b); }
memblock::~memblock (void) throw() { deallocate(); }
void memblock::unlink (void) throw()
{
m_Capacity = 0;
memlink::unlink();
}
/// resizes the block to \p newSize bytes, reallocating if necessary.
void memblock::resize (size_type newSize, bool bExact)
{
if (m_Capacity < newSize + minimumFreeCapacity())
reserve (newSize, bExact);
memlink::resize (newSize);
}
/// Frees internal data.
void memblock::deallocate (void) throw()
{
if (m_Capacity) {
assert (cdata() && "Internal error: space allocated, but the pointer is NULL");
assert (data() && "Internal error: read-only block is marked as allocated space");
free (data());
}
unlink();
}
/// Assumes control of the memory block \p p of size \p n.
/// The block assigned using this function will be freed in the destructor.
void memblock::manage (void* p, size_type n)
{
assert (p || !n);
assert (!m_Capacity && "Already managing something. deallocate or unlink first.");
link (p, n);
m_Capacity = n;
}
/// "Instantiate" a linked block by allocating and copying the linked data.
void memblock::copy_link (void)
{
const pointer p (begin());
const size_t sz (size());
if (is_linked())
unlink();
assign (p, sz);
}
/// Copies data from \p p, \p n.
void memblock::assign (const void* p, size_type n)
{
assert ((p != (const void*) cdata() || size() == n) && "Self-assignment can not resize");
resize (n);
copy_n (pointer(p), n, begin());
}
/// \brief Reallocates internal block to hold at least \p newSize bytes.
///
/// Additional memory may be allocated, but for efficiency it is a very
/// good idea to call reserve before doing byte-by-byte edit operations.
/// The block size as returned by size() is not altered. reserve will not
/// reduce allocated memory. If you think you are wasting space, call
/// deallocate and start over. To avoid wasting space, use the block for
/// only one purpose, and try to get that purpose to use similar amounts
/// of memory on each iteration.
///
void memblock::reserve (size_type newSize, bool bExact)
{
if ((newSize += minimumFreeCapacity()) <= m_Capacity)
return;
pointer oldBlock (is_linked() ? NULL : data());
const size_t alignedSize (Align (newSize, 64));
if (!bExact)
newSize = alignedSize;
pointer newBlock = (pointer) realloc (oldBlock, newSize);
if (!newBlock)
throw bad_alloc (newSize);
if (!oldBlock & (cdata() != NULL))
copy_n (cdata(), min (size() + 1, newSize), newBlock);
link (newBlock, size());
m_Capacity = newSize;
}
/// Shifts the data in the linked block from \p start to \p start + \p n.
memblock::iterator memblock::insert (iterator start, size_type n)
{
const uoff_t ip = start - begin();
assert (ip <= size());
resize (size() + n, false);
memlink::insert (iat(ip), n);
return (iat (ip));
}
/// Shifts the data in the linked block from \p start + \p n to \p start.
memblock::iterator memblock::erase (iterator start, size_type n)
{
const uoff_t ep = start - begin();
assert (ep + n <= size());
memlink::erase (start, n);
memlink::resize (size() - n);
return (iat (ep));
}
/// Reads the object from stream \p s
void memblock::read (istream& is)
{
written_size_type n = 0;
is >> n;
if (!is.verify_remaining ("read", "ustl::memblock", n))
return;
resize (n);
is.read (data(), writable_size());
is.align (alignof (n));
}
/// Reads the entire file \p "filename".
void memblock::read_file (const char* filename)
{
fstream f;
f.exceptions (fstream::allbadbits);
f.open (filename, fstream::in);
const off_t fsize (f.size());
reserve (fsize);
f.read (data(), fsize);
f.close();
resize (fsize);
}
memblock::size_type memblock::minimumFreeCapacity (void) const throw() { return (0); }
} // namespace ustl

61
extern/ustl/1.5/memblock.h vendored Normal file
View File

@@ -0,0 +1,61 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 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"
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);
void read_file (const char* filename);
protected:
virtual size_type minimumFreeCapacity (void) const throw() __attribute__((const));
private:
size_type m_Capacity; ///< Number of bytes allocated by Resize.
};
} // namespace ustl
#endif

42
extern/ustl/1.5/memlink.cc vendored Normal file
View File

@@ -0,0 +1,42 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "mistream.h"
#include "ustdxept.h"
namespace ustl {
/// Reads the object from stream \p s
void memlink::read (istream& is)
{
written_size_type n = 0;
is >> n;
if (!is.verify_remaining ("read", "ustl::memlink", n))
return;
if (n > size())
throw length_error ("memlink can not increase the size of the linked storage for reading");
resize (n);
is.read (data(), n);
is.align (alignof (n));
}
/// Fills the linked block with the given pattern.
/// \arg start Offset at which to start filling the linked block
/// \arg p Pointer to the pattern.
/// \arg elSize Size of the pattern.
/// \arg elCount Number of times to write the pattern.
/// Total number of bytes written is \p elSize * \p elCount.
///
void memlink::fill (iterator start, const void* p, size_type elSize, size_type elCount)
{
assert (data() || !elCount || !elSize);
assert (start >= begin() && start + elSize * elCount <= end());
if (elSize == 1)
fill_n (start, elCount, *reinterpret_cast<const uint8_t*>(p));
else while (elCount--)
start = copy_n (const_iterator(p), elSize, start);
}
} // namespace ustl

99
extern/ustl/1.5/memlink.h vendored Normal file
View File

@@ -0,0 +1,99 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 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 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

92
extern/ustl/1.5/metamac.h vendored Normal file
View File

@@ -0,0 +1,92 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 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

121
extern/ustl/1.5/mistream.cc vendored Normal file
View File

@@ -0,0 +1,121 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "mistream.h"
#include "sostream.h"
#include "ustring.h"
#include "ualgo.h"
namespace ustl {
//--------------------------------------------------------------------
/// Checks that \p n bytes are available in the stream, or else throws.
void ios_base::overrun (const char* op, const char* type, uint32_t n, uint32_t pos, uint32_t rem)
{
if (set_and_throw (rem ? failbit : (failbit | eofbit)))
throw stream_bounds_exception (op, type, pos, n, rem);
}
//--------------------------------------------------------------------
/// Attaches to the block pointed to by source of size source.pos()
istream::istream (const ostream& source)
: cmemlink (source.begin(), source.pos()),
m_Pos (0)
{
}
void istream::unlink (void) throw() { cmemlink::unlink(); m_Pos = 0; }
void ostream::unlink (void) throw() { memlink::unlink(); m_Pos = 0; }
/// Writes all unread bytes into \p os.
void istream::write (ostream& os) const
{
os.write (ipos(), remaining());
}
/// Writes the object to stream \p os.
void istream::text_write (ostringstream& os) const
{
os.write (ipos(), remaining());
}
/// Reads a null-terminated string into \p str.
void istream::read_strz (string& str)
{
const_iterator zp = find (ipos(), end(), '\0');
if (zp == end())
zp = ipos();
const size_type strl = distance (ipos(), zp);
str.assign (ipos(), strl);
m_Pos += strl + 1;
}
/// Reads at most \p n bytes into \p s.
istream::size_type istream::readsome (void* s, size_type n)
{
if (remaining() < n)
underflow (n);
const size_type ntr (min (n, remaining()));
read (s, ntr);
return (ntr);
}
//--------------------------------------------------------------------
/// Aligns the write pointer on \p grain. The skipped bytes are zeroed.
void ostream::align (size_type grain)
{
assert (!((grain-1)&grain) && "grain must be a power of 2");
iterator ip = ipos();
iterator ipa = iterator((uintptr_t(ip) + (grain-1)) & ~(grain-1));
size_t nb = distance (ip, ipa);
#if WANT_STREAM_BOUNDS_CHECKING
if (!verify_remaining ("align", "padding", nb))
return;
#else
assert (remaining() >= nb && "Buffer overrun. Check your stream size calculations.");
#endif
memset (ip, '\x0', nb);
m_Pos += nb;
}
/// Writes \p str as a null-terminated string.
void ostream::write_strz (const char* str)
{
write (str, strlen(str)+1);
}
/// Writes all available data from \p is.
void ostream::read (istream& is)
{
write (is.ipos(), is.remaining());
is.seek (is.size());
}
/// Writes all written data to \p os.
void ostream::text_write (ostringstream& os) const
{
os.write (begin(), pos());
}
/// Inserts an empty area of \p size, at \p start.
void ostream::insert (iterator start, size_type s)
{
m_Pos += s;
memlink::insert (start, s);
}
/// Erases an area of \p size, at \p start.
void ostream::erase (iterator start, size_type s)
{
m_Pos -= s;
memlink::erase (start, s);
}
//--------------------------------------------------------------------
} // namespace ustl

324
extern/ustl/1.5/mistream.h vendored Normal file
View File

@@ -0,0 +1,324 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 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"
#if WANT_STREAM_BOUNDS_CHECKING
#include "typeinfo.h"
#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())
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", typeid(v).name(), 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

293
extern/ustl/1.5/mostream.h vendored Normal file
View File

@@ -0,0 +1,293 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 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"
#if WANT_STREAM_BOUNDS_CHECKING
#include "typeinfo.h"
#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 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())
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", typeid(v).name(), 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

169
extern/ustl/1.5/ofstream.cc vendored Normal file
View File

@@ -0,0 +1,169 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "ofstream.h"
#include "ustring.h"
#include "uexception.h"
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
namespace ustl {
//----------------------------------------------------------------------
ifstream cin (STDIN_FILENO);
ofstream cout (STDOUT_FILENO);
ofstream cerr (STDERR_FILENO);
//----------------------------------------------------------------------
/// Default constructor.
ofstream::ofstream (void)
: ostringstream (),
m_File ()
{
reserve (255);
}
/// Constructs a stream for writing to \p Fd.
ofstream::ofstream (int Fd)
: ostringstream (),
m_File (Fd)
{
clear (m_File.rdstate());
reserve (255);
}
/// Constructs a stream for writing to \p filename.
ofstream::ofstream (const char* filename, openmode mode)
: ostringstream (),
m_File (filename, mode)
{
clear (m_File.rdstate());
}
/// Default destructor.
ofstream::~ofstream (void) throw()
{
try { flush(); } catch (...) {}
}
/// Flushes the buffer and closes the file.
void ofstream::close (void)
{
clear (m_File.rdstate());
flush();
m_File.close();
}
/// Flushes the buffer to the file.
ofstream& ofstream::flush (void)
{
clear();
while (good() && pos() && overflow (remaining())) ;
m_File.sync();
clear (m_File.rdstate());
return (*this);
}
/// Seeks to \p p based on \p d.
ofstream& ofstream::seekp (off_t p, seekdir d)
{
flush();
m_File.seekp (p, d);
clear (m_File.rdstate());
return (*this);
}
/// Called when more buffer space (\p n bytes) is needed.
ofstream::size_type ofstream::overflow (size_type n)
{
if (eof() || (n > remaining() && n < capacity() - pos()))
return (ostringstream::overflow (n));
size_type bw = m_File.write (cdata(), pos());
clear (m_File.rdstate());
erase (begin(), bw);
if (remaining() < n)
ostringstream::overflow (n);
return (remaining());
}
//----------------------------------------------------------------------
/// Constructs a stream to read from \p Fd.
ifstream::ifstream (int Fd)
: istringstream (),
m_Buffer (255),
m_File (Fd)
{
link (m_Buffer.data(), streamsize(0));
}
/// Constructs a stream to read from \p filename.
ifstream::ifstream (const char* filename, openmode mode)
: istringstream (),
m_Buffer (255),
m_File (filename, mode)
{
clear (m_File.rdstate());
link (m_Buffer.data(), streamsize(0));
}
/// Reads at least \p n more bytes and returns available bytes.
ifstream::size_type ifstream::underflow (size_type n)
{
if (eof())
return (istringstream::underflow (n));
const ssize_t freeSpace = m_Buffer.size() - pos();
const ssize_t neededFreeSpace = max (n, m_Buffer.size() / 2);
const size_t oughtToErase = Align (max (0, neededFreeSpace - freeSpace));
const size_type nToErase = min (pos(), oughtToErase);
m_Buffer.memlink::erase (m_Buffer.begin(), nToErase);
const uoff_t oldPos (pos() - nToErase);
size_type br = oldPos;
if (m_Buffer.size() - br < n) {
m_Buffer.resize (br + neededFreeSpace);
link (m_Buffer.data(), streamsize(0));
}
cout.flush();
size_type brn = 1;
for (; br < oldPos + n && brn && m_File.good(); br += brn)
brn = m_File.readsome (m_Buffer.begin() + br, m_Buffer.size() - br);
clear (m_File.rdstate());
m_Buffer[br] = 0;
link (m_Buffer.data(), br);
seek (oldPos);
return (remaining());
}
/// Flushes the input.
int ifstream::sync (void)
{
istringstream::sync();
underflow (0U);
m_File.sync();
clear (m_File.rdstate());
return (-good());
}
/// Seeks to \p p based on \p d.
ifstream& ifstream::seekg (off_t p, seekdir d)
{
m_Buffer.clear();
link (m_Buffer);
m_File.seekg (p, d);
clear (m_File.rdstate());
return (*this);
}
//----------------------------------------------------------------------
} // namespace ustl

78
extern/ustl/1.5/ofstream.h vendored Normal file
View File

@@ -0,0 +1,78 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 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"
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;
};
extern ofstream cout, cerr;
extern ifstream cin;
} // namespace ustl
#endif

466
extern/ustl/1.5/simd.h vendored Normal file
View File

@@ -0,0 +1,466 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 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);
op (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

216
extern/ustl/1.5/sistream.cc vendored Normal file
View File

@@ -0,0 +1,216 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "sistream.h"
#include "sostream.h"
#include "ustring.h"
namespace ustl {
#define DEFAULT_DELIMITERS " \t\n\r;:,.?"
const char ios_base::c_DefaultDelimiters [istringstream::c_MaxDelimiters] = DEFAULT_DELIMITERS;
/// Default constructor.
istringstream::istringstream (void)
: istream (),
m_Base (0)
{
exceptions (goodbit);
set_delimiters (DEFAULT_DELIMITERS);
}
istringstream::istringstream (const void* p, size_type n)
: istream (),
m_Base (0)
{
exceptions (goodbit);
relink (p, n);
set_delimiters (DEFAULT_DELIMITERS);
}
istringstream::istringstream (const cmemlink& source)
: istream (),
m_Base (0)
{
exceptions (goodbit);
relink (source);
set_delimiters (DEFAULT_DELIMITERS);
}
inline bool istringstream::is_delimiter (char c) const
{
return (memchr (m_Delimiters, c, VectorSize(m_Delimiters)-1));
}
char istringstream::skip_delimiters (void)
{
char c = m_Delimiters[0];
while (is_delimiter(c)) {
if (!remaining() && !underflow()) {
verify_remaining ("read", "", 1);
return (0);
}
istream::iread (c);
}
return (c);
}
typedef istringstream::iterator issiter_t;
template <typename T>
inline void str_to_num (issiter_t i, issiter_t* iend, uint8_t base, T& v)
{ v = strtol (i, const_cast<char**>(iend), base); }
template <> inline void str_to_num (issiter_t i, issiter_t* iend, uint8_t, double& v)
{ v = strtod (i, const_cast<char**>(iend)); }
#if HAVE_LONG_LONG
template <> inline void str_to_num (issiter_t i, issiter_t* iend, uint8_t base, long long& v)
{ v = strtoll (i, const_cast<char**>(iend), base); }
#endif
template <typename T>
inline void istringstream::read_number (T& v)
{
v = 0;
if (!skip_delimiters())
return;
ungetc();
iterator ilast;
do {
str_to_num<T> (ipos(), &ilast, m_Base, v);
} while (ilast == end() && underflow());
skip (distance (ipos(), ilast));
}
void istringstream::iread (int32_t& v) { read_number (v); }
void istringstream::iread (double& v) { read_number (v); }
#if HAVE_INT64_T
void istringstream::iread (int64_t& v) { read_number (v); }
#endif
#if HAVE_LONG_LONG && (!HAVE_INT64_T || SIZE_OF_LONG_LONG > 8)
void istringstream::iread (long long& v) { read_number (v); }
#endif
void istringstream::iread (wchar_t& v)
{
if (!(v = skip_delimiters()))
return;
ungetc();
size_t cs = Utf8SequenceBytes (v);
if (remaining() < cs && underflow(cs) < cs)
verify_remaining ("read", "wchar_t", cs);
else {
v = *utf8in (ipos());
skip (cs);
}
}
void istringstream::iread (bool& v)
{
static const char tf[2][8] = { "false", "true" };
char c = skip_delimiters();
v = (c == 't' || c == '1');
if (c != tf[v][0])
return;
for (const char* tv = tf[v]; c == *tv && (remaining() || underflow()); ++tv)
istream::iread (c);
ungetc();
}
void istringstream::iread (string& v)
{
v.clear();
char prevc, quoteChar = 0, c = skip_delimiters();
if (!c)
return;
if (c == '\"' || c == '\'')
quoteChar = c;
else
v += c;
while (remaining() || underflow()) {
prevc = c;
istream::iread (c);
if (!quoteChar && is_delimiter(c))
break;
if (prevc == '\\') {
switch (c) {
case 't': c = '\t'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 'b': c = '\b'; break;
case 'E': c = 27; break; // ESC sequence
case '\"': c = '\"'; break;
case '\'': c = '\''; break;
case '\\': c = '\\'; break;
};
v.end()[-1] = c;
} else {
if (c == quoteChar)
break;
v += c;
}
}
}
istringstream& istringstream::read (void* buffer, size_type sz)
{
if (remaining() < sz && underflow(sz) < sz)
verify_remaining ("read", "", sz);
else
istream::read (buffer, sz);
return (*this);
}
/// Reads characters into \p s until \p delim is found (but not stored or extracted)
istringstream& istringstream::get (string& s, char delim)
{
getline (s, delim);
if (!s.empty() && pos() > 0 && ipos()[-1] == delim)
ungetc();
return (*this);
}
/// Reads characters into \p p,n until \p delim is found (but not stored or extracted)
istringstream& istringstream::get (char* p, size_type n, char delim)
{
assert (p && !n && "A non-empty buffer is required by this implementation");
string s;
get (s, delim);
const size_t ntc (min (n - 1, s.size()));
memcpy (p, s.data(), ntc);
p[ntc] = 0;
return (*this);
}
/// Reads characters into \p s until \p delim is extracted (but not stored)
istringstream& istringstream::getline (string& s, char delim)
{
char oldDelim [VectorSize(m_Delimiters)];
copy (VectorRange (m_Delimiters), oldDelim);
fill (VectorRange (m_Delimiters), '\0');
m_Delimiters[0] = delim;
iread (s);
copy (VectorRange (oldDelim), m_Delimiters);
return (*this);
}
/// Reads characters into \p p,n until \p delim is extracted (but not stored)
istringstream& istringstream::getline (char* p, size_type n, char delim)
{
assert (p && !n && "A non-empty buffer is required by this implementation");
string s;
getline (s, delim);
const size_t ntc (min (n - 1, s.size()));
memcpy (p, s.data(), ntc);
p[ntc] = 0;
return (*this);
}
/// Extract until \p delim or \p n chars have been read.
istringstream& istringstream::ignore (size_type n, char delim)
{
while (n-- && (remaining() || underflow()) && get() != delim) ;
return (*this);
}
} // namespace ustl

153
extern/ustl/1.5/sistream.h vendored Normal file
View File

@@ -0,0 +1,153 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 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"
#ifndef EOF
#define EOF (-1)
#endif
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 = EOF; 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
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

168
extern/ustl/1.5/sostream.cc vendored Normal file
View File

@@ -0,0 +1,168 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
#include "mistream.h" // for istream_iterator, referenced in utf8.h
#include "sostream.h"
#include "ustring.h"
#include "ulimits.h"
#include <stdio.h>
namespace ustl {
/// Creates an output string stream linked to the given memory area.
ostringstream::ostringstream (void* p, size_t n)
: ostream (),
m_Buffer (),
m_Flags (0),
m_Width (0),
m_Base (10),
m_Precision (2)
{
exceptions (goodbit);
link (p, n);
}
/// Creates an output string stream, initializing the buffer with v.
ostringstream::ostringstream (const string& v)
: ostream (),
m_Buffer (v),
m_Flags (0),
m_Width (0),
m_Base (10),
m_Precision (2)
{
exceptions (goodbit);
ostream::link (m_Buffer);
}
/// Copies \p s to the internal buffer.
void ostringstream::str (const string& s)
{
m_Buffer = s;
ostream::link (m_Buffer);
SetPos (m_Buffer.size());
}
/// Writes a single character into the stream.
void ostringstream::iwrite (uint8_t v)
{
if (remaining() >= 1 || overflow() >= 1)
ostream::iwrite (v);
}
/// Writes the contents of \p buffer of \p size into the stream.
ostringstream& ostringstream::write (const void* buffer, size_type sz)
{
const char* buf = (const char*) buffer;
for (size_type bw = 0; (bw = min(sz, remaining() ? remaining() : overflow(sz))); buf += bw, sz -= bw)
ostream::write (buf, bw);
return (*this);
}
/// Simple decimal encoding of \p n into \p fmt.
inline char* ostringstream::encode_dec (char* fmt, uint32_t n) const
{
do {
*fmt++ = '0' + n % 10;
} while (n /= 10);
return (fmt);
}
/// Generates a sprintf format string for the given type.
void ostringstream::fmtstring (char* fmt, const char* typestr, bool bInteger) const
{
*fmt++ = '%';
if (m_Width)
fmt = encode_dec (fmt, m_Width);
if (m_Flags & left)
*fmt++ = '-';
if (!bInteger) {
*fmt++ = '.';
fmt = encode_dec (fmt, m_Precision);
}
while (*typestr)
*fmt++ = *typestr++;
if (bInteger) {
if (m_Base == 16)
fmt[-1] = 'X';
else if (m_Base == 8)
fmt[-1] = 'o';
} else {
if (m_Flags & scientific)
fmt[-1] = 'E';
}
*fmt = 0;
}
/// Writes \p v into the stream as utf8
void ostringstream::iwrite (wchar_t v)
{
char buffer [8];
*utf8out(buffer) = v;
write (buffer, Utf8Bytes(v));
}
/// Writes value \p v into the stream as text.
void ostringstream::iwrite (bool v)
{
static const char tf[2][8] = { "false", "true" };
write (tf[v], 5 - v);
}
/// Equivalent to a vsprintf on the string.
int ostringstream::vformat (const char* fmt, va_list args)
{
#if HAVE_VA_COPY
va_list args2;
#else
#define args2 args
#undef __va_copy
#define __va_copy(x,y)
#endif
size_t rv, space;
do {
space = remaining();
__va_copy (args2, args);
rv = vsnprintf (ipos(), space, fmt, args2);
if (ssize_t(rv) < 0)
rv = space;
} while (rv >= space && rv < overflow(rv + 1));
SetPos (pos() + min (rv, space));
return (rv);
}
/// Equivalent to a sprintf on the string.
int ostringstream::format (const char* fmt, ...)
{
va_list args;
va_start (args, fmt);
const int rv = vformat (fmt, args);
va_end (args);
return (rv);
}
/// Links to string \p l as resizable.
void ostringstream::link (void* p, size_type n)
{
assert ((p || !n) && "The output string buffer must not be read-only");
ostream::link (p, n);
m_Buffer.link (p, n);
}
/// Attempts to create more output space. Returns remaining().
ostringstream::size_type ostringstream::overflow (size_type n)
{
if (n > remaining()) {
const uoff_t oldPos (pos());
m_Buffer.reserve (oldPos + n, false);
m_Buffer.resize (oldPos + n);
ostream::link (m_Buffer);
SetPos (oldPos);
}
verify_remaining ("write", "text", n);
return (remaining());
}
} // namespace ustl

161
extern/ustl/1.5/sostream.h vendored Normal file
View File

@@ -0,0 +1,161 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 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

82
extern/ustl/1.5/strmsize.h vendored Normal file
View File

@@ -0,0 +1,82 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 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

251
extern/ustl/1.5/traits.h vendored Normal file
View File

@@ -0,0 +1,251 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2007 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

40
extern/ustl/1.5/typeinfo.h vendored Normal file
View File

@@ -0,0 +1,40 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2005 by Mike Sharov <msharov@users.sourceforge.net>
// This file is free software, distributed under the MIT License.
//
#ifndef TYPEINFO_H_E67A267F0BBB5005
#define TYPEINFO_H_E67A267F0BBB5005
#ifndef WITHOUT_LIBSTDCPP
#include <typeinfo>
#else
#include "uexception.h"
namespace __cxxabiv1 { class __class_type_info; }
namespace std {
class type_info {
public:
inline virtual ~type_info (void) { }
inline const char* name (void) const { return (__name[0] == '*' ? __name + 1 : __name); }
inline bool before (const type_info& v) const { return (__name < v.__name); }
inline bool operator==(const type_info& v) const { return (__name == v.__name); }
inline bool operator!=(const type_info& v) const { return (!operator==(v)); }
virtual bool __is_pointer_p (void) const;
virtual bool __is_function_p (void) const;
virtual bool __do_catch (const type_info* __thr_type, void** __thr_obj, unsigned __outer) const;
virtual bool __do_upcast (const __cxxabiv1::__class_type_info* __target, void** __obj_ptr) const;
explicit inline type_info (const char* newname) : __name(newname) { }
private:
inline void operator= (const type_info&) { }
inline type_info (const type_info&) { }
protected:
const char* __name;
};
} // namespace std
#endif
#endif

223
extern/ustl/1.5/typelist.h vendored Normal file
View File

@@ -0,0 +1,223 @@
// This file is part of the uSTL library, an STL implementation.
//
// Copyright (c) 2007 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

Some files were not shown because too many files have changed in this diff Show More