// This file is part of the uSTL library, an STL implementation. // // Copyright (c) 2005 by Mike Sharov // This file is free software, distributed under the MIT License. #pragma once #include "uvector.h" #include "ustring.h" #include "uset.h" #include "umultiset.h" #include "ubitset.h" #include "ulaalgo.h" #include "uarray.h" #include "uctralgo.h" #include "ufunction.h" #include "uctrstrm.h" #include "sistream.h" #include "uchrono.h" namespace ustl { //---------------------------------------------------------------------- // Alogrithm specializations not in use by the library code. //---------------------------------------------------------------------- template <> inline void swap (cmemlink& a, cmemlink& b) { a.swap (b); } template <> inline void swap (memlink& a, memlink& b) { a.swap (b); } template <> inline void swap (memblock& a, memblock& b) { a.swap (b); } template <> inline void swap (string& a, string& b) { a.swap (b); } #define TEMPLATE_SWAP_PSPEC(type, template_decl) \ template_decl inline void swap (type& a, type& b) { a.swap (b); } TEMPLATE_SWAP_PSPEC (TEMPLATE_TYPE1 (vector,T), TEMPLATE_DECL1 (T)) TEMPLATE_SWAP_PSPEC (TEMPLATE_TYPE1 (set,T), TEMPLATE_DECL1 (T)) TEMPLATE_SWAP_PSPEC (TEMPLATE_TYPE1 (multiset,T), TEMPLATE_DECL1 (T)) TEMPLATE_SWAP_PSPEC (TEMPLATE_TYPE2 (tuple,N,T), TEMPLATE_FULL_DECL2 (size_t,N,typename,T)) //---------------------------------------------------------------------- // Streamable definitions. Not used in the library and require streams. //---------------------------------------------------------------------- //----{ pair }---------------------------------------------------------- /// \brief Reads pair \p p from stream \p is. template void pair::read (istream& is) { is >> first; is.align (stream_align_of(second)); is >> second; is.align (stream_align_of(first)); } /// Writes pair \p p to stream \p os. template void pair::write (ostream& os) const { os << first; os.align (stream_align_of(second)); os << second; os.align (stream_align_of(first)); } /// Returns the written size of the object. template size_t pair::stream_size (void) const { return Align (stream_size_of(first), stream_align_of(second)) + Align (stream_size_of(second), stream_align_of(first)); } /// Writes pair \p p to stream \p os. template void pair::text_write (ostringstream& os) const { os << '(' << first << ',' << second << ')'; } /// \brief Takes a pair and returns pair.first /// This is an extension, available in uSTL and the SGI STL. template struct select1st : public unary_function { typedef typename Pair::first_type result_type; inline const result_type& operator()(const Pair& a) const { return a.first; } inline result_type& operator()(Pair& a) const { return a.first; } }; /// \brief Takes a pair and returns pair.second /// This is an extension, available in uSTL and the SGI STL. template struct select2nd : public unary_function { typedef typename Pair::second_type result_type; inline const result_type& operator()(const Pair& a) const { return a.second; } inline result_type& operator()(Pair& a) const { return a.second; } }; /// \brief Converts a const_iterator pair into an iterator pair /// Useful for converting pair ranges returned by equal_range, for instance. /// This is an extension, available in uSTL. template inline pair unconst (const pair& i, Container&) { typedef pair unconst_pair_t; return *noalias_cast(&i); } //----{ vector }-------------------------------------------------------- template inline size_t stream_align_of (const vector&) { typedef typename vector::written_size_type written_size_type; return stream_align_of (written_size_type()); } //----{ bitset }-------------------------------------------------------- /// Writes bitset \p v into stream \p os. template void bitset::text_read (istringstream& is) { char c; for (int i = Size; --i >= 0 && (is >> c).good();) set (i, c == '1'); } //----{ tuple }--------------------------------------------------------- template struct numeric_limits > { typedef numeric_limits value_limits; static inline tuple min (void) { tuple v; fill (v, value_limits::min()); return v; } static inline tuple max (void) { tuple v; fill (v, value_limits::max()); return v; } static const bool is_signed = value_limits::is_signed; static const bool is_integer = value_limits::is_integer; static const bool is_integral = value_limits::is_integral; }; template inline size_t stream_align_of (const tuple&) { return stream_align_of (NullValue()); } template inline ostringstream& chartype_text_write (ostringstream& os, const T& v) { os.format (_FmtPrtChr[!isprint(v)], v); return os; } template <> inline ostringstream& container_element_text_write (ostringstream& os, const uint8_t& v) { return chartype_text_write (os, v); } template <> inline ostringstream& container_element_text_write (ostringstream& os, const int8_t& v) { return chartype_text_write (os, v); } //----{ matrix }-------------------------------------------------------- /// Writes matrix \p v into stream \p os. template void matrix::text_write (ostringstream& os) const { os << '('; for (uoff_t iRow = 0; iRow < NY; ++ iRow) { os << '('; for (uoff_t iColumn = 0; iColumn < NX; ++iColumn) os << at(iRow)[iColumn] << ",)"[iColumn == NX-1]; } os << ')'; } //----{ long4grain }---------------------------------------------------- #if SIZE_OF_LONG == 8 && HAVE_INT64_T // Helper class for long4grain and ptr4grain wrappers. class _long4grain { public: inline _long4grain (uint64_t v) : _v (v) {} #if __x86_64__ inline void read (istream& is) { assert (is.aligned(4)); #if WANT_STREAM_BOUNDS_CHECKING if (!is.verify_remaining ("read", "long4grain", sizeof(_v))) return; #else assert (is.remaining() >= sizeof(_v)); #endif _v = *reinterpret_cast(is.ipos()); is.skip (sizeof(_v)); } inline void write (ostream& os) const { assert (os.aligned(4)); #if WANT_STREAM_BOUNDS_CHECKING if (!os.verify_remaining ("write", "long4grain", sizeof(_v))) return; #else assert (os.remaining() >= sizeof(_v)); #endif *reinterpret_cast(os.ipos()) = _v; os.skip (sizeof(_v)); } #elif USTL_BYTE_ORDER == USTL_BIG_ENDIAN inline void read (istream& is) { uint32_t vl, vh; is >> vh >> vl; _v = (uint64_t(vh) << 32) | uint64_t(vl); } inline void write (ostream& os) const { os << uint32_t(_v >> 32) << uint32_t(_v); } #else inline void read (istream& is) { uint32_t vl, vh; is >> vl >> vh; _v = (uint64_t(vh) << 32) | uint64_t(vl); } inline void write (ostream& os) const { os << uint32_t(_v) << uint32_t(_v >> 32); } #endif inline size_t stream_size (void) const { return stream_size_of(_v); } private: uint64_t _v; }; /// Wrap long values to allow writing them on 4-grain even on 64bit platforms. inline _long4grain& long4grain (unsigned long& v) { asm("":"+m"(v)); return *noalias_cast<_long4grain*>(&v); } /// Wrap long values to allow writing them on 4-grain even on 64bit platforms. inline const _long4grain long4grain (const unsigned long& v) { return _long4grain(v); } /// Wrap pointer values to allow writing them on 4-grain even on 64bit platforms. template inline _long4grain& ptr4grain (T*& p) { asm("":"+m"(p)); return *noalias_cast<_long4grain*>(&p); } /// Wrap pointer values to allow writing them on 4-grain even on 64bit platforms. template inline const _long4grain ptr4grain (const T* const& p) { return _long4grain(uintptr_t(p)); } #else // if not SIZE_OF_LONG == 8 && HAVE_INT64_T inline unsigned long& long4grain (unsigned long& v) { return v; } inline const unsigned long& long4grain (const unsigned long& v) { return v; } template inline T*& ptr4grain (T*& p) { return p; } template inline const T* const& ptr4grain (const T* const& p) { return p; } #endif // SIZE_OF_LONG == 8 //---------------------------------------------------------------------- } // namespace ustl ALIGNOF (_long4grain, 4) ALIGNOF(ustl::CBacktrace, sizeof(void*)) ALIGNOF (ustl::string, stream_align_of (string::value_type())) // bool is a big type on some machines (like DEC Alpha), so it's written as a byte. ALIGNOF(bool, sizeof(uint8_t)) CAST_STREAMABLE(bool, uint8_t)