first commit
This commit is contained in:
59
extern/ustl/1.5/Config.mk.in
vendored
Normal file
59
extern/ustl/1.5/Config.mk.in
vendored
Normal 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
22
extern/ustl/1.5/LICENSE
vendored
Normal 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
154
extern/ustl/1.5/Makefile
vendored
Normal 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
141
extern/ustl/1.5/bktrace.cc
vendored
Normal 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
52
extern/ustl/1.5/bktrace.h
vendored
Normal 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
52
extern/ustl/1.5/bvt/Module.mk
vendored
Normal 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
311
extern/ustl/1.5/bvt/bench.cc
vendored
Normal 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", ©_n<const char*, char*>);
|
||||
|
||||
return (EXIT_SUCCESS);
|
||||
}
|
||||
46
extern/ustl/1.5/bvt/bvt00.cc
vendored
Normal file
46
extern/ustl/1.5/bvt/bvt00.cc
vendored
Normal 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
3
extern/ustl/1.5/bvt/bvt00.std
vendored
Normal 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
60
extern/ustl/1.5/bvt/bvt01.cc
vendored
Normal 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
7
extern/ustl/1.5/bvt/bvt01.std
vendored
Normal 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
72
extern/ustl/1.5/bvt/bvt02.cc
vendored
Normal 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
9
extern/ustl/1.5/bvt/bvt02.std
vendored
Normal 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
117
extern/ustl/1.5/bvt/bvt03.cc
vendored
Normal 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
13
extern/ustl/1.5/bvt/bvt03.std
vendored
Normal 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
68
extern/ustl/1.5/bvt/bvt04.cc
vendored
Normal 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
25
extern/ustl/1.5/bvt/bvt04.std
vendored
Normal 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
399
extern/ustl/1.5/bvt/bvt05.cc
vendored
Normal 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
132
extern/ustl/1.5/bvt/bvt05.std
vendored
Normal 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
59
extern/ustl/1.5/bvt/bvt06.cc
vendored
Normal 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
29
extern/ustl/1.5/bvt/bvt06.std
vendored
Normal 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
135
extern/ustl/1.5/bvt/bvt07.cc
vendored
Normal 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
32
extern/ustl/1.5/bvt/bvt07.std
vendored
Normal 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
57
extern/ustl/1.5/bvt/bvt08.cc
vendored
Normal 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
30
extern/ustl/1.5/bvt/bvt08.std
vendored
Normal 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
84
extern/ustl/1.5/bvt/bvt09.cc
vendored
Normal 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
28
extern/ustl/1.5/bvt/bvt09.std
vendored
Normal 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
171
extern/ustl/1.5/bvt/bvt10.cc
vendored
Normal 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
27
extern/ustl/1.5/bvt/bvt10.std
vendored
Normal 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
36
extern/ustl/1.5/bvt/bvt11.cc
vendored
Normal 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
7
extern/ustl/1.5/bvt/bvt11.std
vendored
Normal 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
81
extern/ustl/1.5/bvt/bvt12.cc
vendored
Normal 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
12
extern/ustl/1.5/bvt/bvt12.std
vendored
Normal 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
36
extern/ustl/1.5/bvt/bvt13.cc
vendored
Normal 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
7
extern/ustl/1.5/bvt/bvt13.std
vendored
Normal 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
59
extern/ustl/1.5/bvt/bvt14.cc
vendored
Normal 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
23
extern/ustl/1.5/bvt/bvt14.std
vendored
Normal 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
57
extern/ustl/1.5/bvt/bvt15.cc
vendored
Normal 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
30
extern/ustl/1.5/bvt/bvt15.std
vendored
Normal 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
86
extern/ustl/1.5/bvt/bvt16.cc
vendored
Normal 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
11
extern/ustl/1.5/bvt/bvt16.std
vendored
Normal 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
98
extern/ustl/1.5/bvt/bvt17.cc
vendored
Normal 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
33
extern/ustl/1.5/bvt/bvt17.std
vendored
Normal 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
77
extern/ustl/1.5/bvt/bvt18.cc
vendored
Normal 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
184
extern/ustl/1.5/bvt/bvt18.std
vendored
Normal 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
33
extern/ustl/1.5/bvt/bvt19.cc
vendored
Normal 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
3
extern/ustl/1.5/bvt/bvt19.std
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
Testing operator+
|
||||
apple = apple
|
||||
peach = peach
|
||||
33
extern/ustl/1.5/bvt/bvt20.cc
vendored
Normal file
33
extern/ustl/1.5/bvt/bvt20.cc
vendored
Normal 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
2
extern/ustl/1.5/bvt/bvt20.std
vendored
Normal 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
108
extern/ustl/1.5/bvt/bvt21.cc
vendored
Normal 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
68
extern/ustl/1.5/bvt/bvt21.std
vendored
Normal 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
71
extern/ustl/1.5/bvt/bvt22.cc
vendored
Normal 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
58
extern/ustl/1.5/bvt/bvt22.std
vendored
Normal 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
121
extern/ustl/1.5/bvt/bvt23.cc
vendored
Normal 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
218
extern/ustl/1.5/bvt/bvt23.std
vendored
Normal 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
100
extern/ustl/1.5/bvt/bvt24.cc
vendored
Normal 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
180
extern/ustl/1.5/bvt/bvt24.std
vendored
Normal 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
22
extern/ustl/1.5/bvt/bvt25.cc
vendored
Normal 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
5
extern/ustl/1.5/bvt/bvt25.std
vendored
Normal 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
19
extern/ustl/1.5/bvt/bvt26.cc
vendored
Normal 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
10
extern/ustl/1.5/bvt/bvt26.std
vendored
Normal 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
57
extern/ustl/1.5/bvt/bvt27.cc
vendored
Normal 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
25
extern/ustl/1.5/bvt/bvt27.std
vendored
Normal 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
72
extern/ustl/1.5/bvt/stdtest.cc
vendored
Normal 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
18
extern/ustl/1.5/bvt/stdtest.h
vendored
Normal 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
71
extern/ustl/1.5/cmemlink.cc
vendored
Normal 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
100
extern/ustl/1.5/cmemlink.h
vendored
Normal 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
250
extern/ustl/1.5/config.h.in
vendored
Normal 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
497
extern/ustl/1.5/configure
vendored
Normal 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
368
extern/ustl/1.5/docs/ChangeLog
vendored
Normal 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
750
extern/ustl/1.5/docs/index.html
vendored
Normal 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&task=view&id=82&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 <ustl.h>
|
||||
using namespace ustl;
|
||||
|
||||
int main (void)
|
||||
{
|
||||
cout << "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<int> 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<int>::iterator, i, v)
|
||||
if (*i < 5 || *i > 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<CEmployee>::iterator, i, employees)
|
||||
if (i->m_Salary > 50000 || i->m_Performance < 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 << s << 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 < s.utf8_end(); ++ i)
|
||||
DrawChar (*i);
|
||||
</pre><p>
|
||||
or just copy all the chars into an array and iterate over that:
|
||||
</p><pre>
|
||||
vector<wchar_t> 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& v) {
|
||||
if (v < m_MinValue || v > 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 < 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 << "Hello world!" << endl;
|
||||
cout << 456 << ios::hex << 0x1234 << endl;
|
||||
cerr.format ("You objects are at 0x%08X\n", &o);
|
||||
</pre><p>
|
||||
String-writing streams are also available:
|
||||
</p><pre>
|
||||
ostringstream os;
|
||||
os << "Writing " << n << " objects somewhere" << endl;
|
||||
cout << os.str() << 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 << number << ctr;
|
||||
os.align();
|
||||
os << n << 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& is);
|
||||
void write (ostream& os) const;
|
||||
size_t stream_size (void) const;
|
||||
private:
|
||||
vector<int> m_Elements; ///< A bunch of elements.
|
||||
size_t m_SomeSize; ///< Some integral value.
|
||||
MyObject m_SomeObject; ///< Some other streamable object.
|
||||
}
|
||||
|
||||
/// Reads the object from stream \p is.
|
||||
void CMyClass::read (istream& is)
|
||||
{
|
||||
is >> m_Elements >> m_SomeSize >> m_SomeObject;
|
||||
}
|
||||
|
||||
/// Writes the object to stream \p os.
|
||||
void CMyClass::write (ostream& os) const
|
||||
{
|
||||
os << m_Elements << m_SomeSize << 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<2, coord_t> Point2d;
|
||||
typedef tuple<2, coord_t> Size2d;
|
||||
typedef tuple<2, Point2d> 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& e) {
|
||||
cerr << "Error: " << e << endl;
|
||||
#ifndef NDEBUG
|
||||
cerr << e.backtrace();
|
||||
#endif
|
||||
} catch (...) {
|
||||
cerr << "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 <ustl.h>
|
||||
using namespace ustl;
|
||||
#else
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
#endif
|
||||
|
||||
int main (void)
|
||||
{
|
||||
vector<int> v;
|
||||
v.resize (30);
|
||||
for (size_t i = 0; i < 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&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
3
extern/ustl/1.5/docs/robots.txt
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
User-agent: *
|
||||
Disallow: /style/
|
||||
Sitemap: /sitemap.xml
|
||||
15
extern/ustl/1.5/docs/sitemap.xml
vendored
Normal file
15
extern/ustl/1.5/docs/sitemap.xml
vendored
Normal 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
27
extern/ustl/1.5/docs/style/default.css
vendored
Normal 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 }
|
||||
28
extern/ustl/1.5/docs/style/ustlstyle.css
vendored
Normal file
28
extern/ustl/1.5/docs/style/ustlstyle.css
vendored
Normal 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 }
|
||||
BIN
extern/ustl/1.5/docs/style/valid-xhtml10.png
vendored
Normal file
BIN
extern/ustl/1.5/docs/style/valid-xhtml10.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
18
extern/ustl/1.5/docs/ustl.lsm
vendored
Normal file
18
extern/ustl/1.5/docs/ustl.lsm
vendored
Normal 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
15
extern/ustl/1.5/docs/ustlfooter.html
vendored
Normal 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&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
12
extern/ustl/1.5/docs/ustlheader.html
vendored
Normal 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
259
extern/ustl/1.5/fstream.cc
vendored
Normal 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
75
extern/ustl/1.5/fstream.h
vendored
Normal 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
150
extern/ustl/1.5/memblock.cc
vendored
Normal 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
61
extern/ustl/1.5/memblock.h
vendored
Normal 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
42
extern/ustl/1.5/memlink.cc
vendored
Normal 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
99
extern/ustl/1.5/memlink.h
vendored
Normal 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
92
extern/ustl/1.5/metamac.h
vendored
Normal 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
121
extern/ustl/1.5/mistream.cc
vendored
Normal 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
324
extern/ustl/1.5/mistream.h
vendored
Normal 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
293
extern/ustl/1.5/mostream.h
vendored
Normal 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
169
extern/ustl/1.5/ofstream.cc
vendored
Normal 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
78
extern/ustl/1.5/ofstream.h
vendored
Normal 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
466
extern/ustl/1.5/simd.h
vendored
Normal 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
216
extern/ustl/1.5/sistream.cc
vendored
Normal 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
153
extern/ustl/1.5/sistream.h
vendored
Normal 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
168
extern/ustl/1.5/sostream.cc
vendored
Normal 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
161
extern/ustl/1.5/sostream.h
vendored
Normal 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
82
extern/ustl/1.5/strmsize.h
vendored
Normal 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
251
extern/ustl/1.5/traits.h
vendored
Normal 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
40
extern/ustl/1.5/typeinfo.h
vendored
Normal 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
223
extern/ustl/1.5/typelist.h
vendored
Normal 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
Reference in New Issue
Block a user