From: root Date: Thu, 2 Sep 2004 07:44:40 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://git.openbox.org/?a=commitdiff_plain;h=7bbd2afad2a16a3128006f7b9bd2d8ec009992be;p=dana%2Furxvt.git *** empty log message *** --- diff --git a/src/iom.C b/src/iom.C index 1b7313d3..486c38cb 100644 --- a/src/iom.C +++ b/src/iom.C @@ -17,6 +17,8 @@ Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "iom.h" + #include #include #include @@ -28,20 +30,50 @@ #if 1 // older unices need these includes for select (2) # include # include +# include +#endif + +// for IOM_SIG +#if IOM_SIG +# include +# include #endif // if the BSDs would at least be marginally POSIX-compatible.. *sigh* // until that happens, sys/select.h must come last #include -// for IOM_SIG -#include - -#include "iom.h" - // TSTAMP_MAX must still fit into a positive struct timeval #define TSTAMP_MAX (double)(1UL<<31) +#define TIMEVAL timeval +#define TV_FRAC tv_usec +#define TV_MULT 1000000L + +#if IOM_IO +static io_manager_vec iow; +#endif +#if IOM_CHECK +static io_manager_vec cw; +#endif +#if IOM_TIME +static io_manager_vec tw; +#endif +#if IOM_IDLE +static io_manager_vec iw; +#endif +#if IOM_SIG +static int sigpipe[2]; // signal signalling pipe +static sigset_t sigs; +struct sig_vec : io_manager_vec { + int pending; + sig_vec () + : pending (false) + { } +}; +static vector sw; +#endif + // this is a dummy time watcher to ensure that the first // time watcher is _always_ valid, this gets rid of a lot // of null-pointer-checks @@ -57,40 +89,89 @@ static struct tw0 : time_watcher } tw0 () - : time_watcher (this, &tw0::cb) - { } + : time_watcher (this, &tw0::cb) + { } } tw0; tstamp NOW; + +#if IOM_TIME +inline void set_now (void) +{ + struct timeval tv; + + gettimeofday (&tv, 0); + NOW = (tstamp)tv.tv_sec + (tstamp)tv.tv_usec / 1000000.; +} +#endif + static bool iom_valid; -io_manager iom; -template -void io_manager::reg (watcher *w, io_manager_vec &queue) +// used for initialisation only +static struct init { + init () + { +#if IOM_SIG + sigemptyset (&sigs); + + if (pipe (sigpipe)) + { + perror ("io_manager: unable to create signal pipe, aborting."); + abort (); + } + + fcntl (sigpipe[0], F_SETFL, O_NONBLOCK); + fcntl (sigpipe[1], F_SETFL, O_NONBLOCK); +#endif + + iom_valid = true; + +#if IOM_TIME + set_now (); + + tw0.start (TSTAMP_MAX); +#endif + } + + static void required (); +} init; + +void +init::required () { if (!iom_valid) - abort (); + { + write (2, "io_manager: early registration attempt, aborting.\n", + sizeof ("io_manager: early registration attempt, aborting.\n") - 1); + abort (); + } +} + +template +void io_manager::reg (watcher &w, io_manager_vec &queue) +{ + init::required (); - if (!w->active) + if (!w.active) { #if IOM_CHECK queue.activity = true; #endif - queue.push_back (w); - w->active = queue.size (); + queue.push_back (&w); + w.active = queue.size (); } } template -void io_manager::unreg (watcher *w, io_manager_vec &queue) +void io_manager::unreg (watcher &w, io_manager_vec &queue) { if (!iom_valid) return; - if (w->active) + if (w.active) { - queue [w->active - 1] = 0; - w->active = 0; + queue [w.active - 1] = 0; + w.active = 0; } } @@ -98,119 +179,114 @@ void io_manager::unreg (watcher *w, io_manager_vec &queue) void time_watcher::trigger () { call (*this); - - iom.reg (this); + io_manager::reg (*this); } -void io_manager::reg (time_watcher *w) { reg (w, tw); } -void io_manager::unreg (time_watcher *w) { unreg (w, tw); } +void io_manager::reg (time_watcher &w) { io_manager::reg (w, tw); } +void io_manager::unreg (time_watcher &w) { io_manager::unreg (w, tw); } #endif #if IOM_IO -void io_manager::reg (io_watcher *w) { reg (w, iow); } -void io_manager::unreg (io_watcher *w) { unreg (w, iow); } +void io_manager::reg (io_watcher &w) { io_manager::reg (w, iow); } +void io_manager::unreg (io_watcher &w) { io_manager::unreg (w, iow); } #endif #if IOM_CHECK -void io_manager::reg (check_watcher *w) { reg (w, cw); } -void io_manager::unreg (check_watcher *w) { unreg (w, cw); } +void io_manager::reg (check_watcher &w) { io_manager::reg (w, cw); } +void io_manager::unreg (check_watcher &w) { io_manager::unreg (w, cw); } #endif #if IOM_IDLE -void io_manager::reg (idle_watcher *w) { reg (w, iw); } -void io_manager::unreg (idle_watcher *w) { unreg (w, iw); } -#endif - -#if IOM_TIME -inline void set_now (void) -{ - struct timeval tv; - - gettimeofday (&tv, 0); - - NOW = (tstamp)tv.tv_sec + (tstamp)tv.tv_usec / 1000000; -} +void io_manager::reg (idle_watcher &w) { io_manager::reg (w, iw); } +void io_manager::unreg (idle_watcher &w) { io_manager::unreg (w, iw); } #endif #if IOM_SIG -// race conditions galore - -void io_manager::sighandler (int signum) +static void +sighandler (int signum) { - assert (0 < signum && signum <= iom.sw.size ()); - - sig_vec &sv = *iom.sw [signum - 1]; + sw [signum - 1]->pending = true; - for (int i = sv.size (); i--; ) - if (!sv[i]) - sv.erase_unordered (i); - else - sv[i]->call (*sv[i]); + // we use a pipe for signal notifications, as most current + // OSes (Linux...) do not implement pselect correctly. ugh. + char ch = signum; // actual content not used + write (sigpipe[1], &ch, 1); } -void io_manager::reg (sig_watcher *w) +void io_manager::reg (sig_watcher &w) { - assert (0 < w->signum); + assert (0 < w.signum); - sw.reserve (w->signum); + sw.reserve (w.signum); - sig_vec *&sv = sw [w->signum - 1]; + while (sw.size () < w.signum) // pathetic + sw.push_back (0); + + sig_vec *&sv = sw[w.signum - 1]; if (!sv) { sv = new sig_vec; + sigaddset (&sigs, w.signum); + sigprocmask (SIG_BLOCK, &sigs, NULL); + struct sigaction sa; - sa.sa_handler = io_manager::sighandler; + sa.sa_handler = sighandler; sigfillset (&sa.sa_mask); - sa.sa_flags = 0; + sa.sa_flags = SA_RESTART; - if (sigaction (w->signum, &sa, 0)) + if (sigaction (w.signum, &sa, 0)) { - perror ("Error while installing signal handler"); + perror ("io_manager: error while installing signal handler, ignoring."); abort (); } + } - reg (w, *sv); + io_manager::reg (w, *sv); } -void io_manager::unreg (sig_watcher *w) +void io_manager::unreg (sig_watcher &w) { - assert (0 < w->signum && w->signum <= sw.size ()); + if (!w.active) + return; + + assert (0 < w.signum && w.signum <= sw.size ()); - unreg (w, *sw [w->signum - 1]); + io_manager::unreg (w, *sw[w.signum - 1]); } void sig_watcher::start (int signum) { stop (); this->signum = signum; - iom.reg (this); + io_manager::reg (*this); } #endif - + void io_manager::loop () { + init::required (); + #if IOM_TIME set_now (); #endif for (;;) { - struct timeval *to = 0; - struct timeval tval; + struct TIMEVAL *to = 0; + struct TIMEVAL tval; #if IOM_IDLE if (iw.size ()) { tval.tv_sec = 0; - tval.tv_usec = 0; + tval.TV_FRAC = 0; to = &tval; } else #endif - { #if IOM_TIME time_watcher *next; @@ -231,19 +307,18 @@ void io_manager::loop () { double diff = next->at - NOW; tval.tv_sec = (int)diff; - tval.tv_usec = (int) ((diff - tval.tv_sec) * 1000000); + tval.TV_FRAC = (int) ((diff - tval.tv_sec) * TV_MULT); to = &tval; } break; } else { - unreg (next); + unreg (*next); next->call (*next); } } #endif - } #if IOM_CHECK @@ -258,12 +333,12 @@ void io_manager::loop () if (tw.activity) { tval.tv_sec = 0; - tval.tv_usec = 0; + tval.TV_FRAC = 0; to = &tval; } #endif -#if IOM_IO +#if IOM_IO || IOM_SIG fd_set rfd, wfd; FD_ZERO (&rfd); @@ -271,6 +346,7 @@ void io_manager::loop () int fds = 0; +# if IOM_IO for (io_manager_vec::iterator i = iow.end (); i-- > iow.begin (); ) if (*i) { @@ -279,32 +355,74 @@ void io_manager::loop () if ((*i)->fd >= fds) fds = (*i)->fd + 1; } +# endif if (!to && !fds) //TODO: also check idle_watchers and check_watchers break; // no events +# if IOM_SIG + FD_SET (sigpipe[0], &rfd); + if (sigpipe[0] >= fds) fds = sigpipe[0] + 1; +# endif + +# if IOM_SIG + // there is no race, as we use a pipe for signals, so select + // will return if a signal is caught. + sigprocmask (SIG_UNBLOCK, &sigs, NULL); +# endif fds = select (fds, &rfd, &wfd, NULL, to); +# if IOM_SIG + sigprocmask (SIG_BLOCK, &sigs, NULL); +# endif + # if IOM_TIME set_now (); # endif if (fds > 0) - for (int i = iow.size (); i--; ) - if (!iow[i]) - iow.erase_unordered (i); - else + { +# if IOM_SIG + if (FD_ISSET (sigpipe[0], &rfd)) { - short revents = iow[i]->events; + char ch; + + while (read (sigpipe[0], &ch, 1) > 0) + ; + + for (sig_vec **svp = sw.end (); svp-- > sw.begin (); ) + if (*svp && (*svp)->pending) + { + sig_vec &sv = **svp; + for (int i = sv.size (); i--; ) + if (!sv[i]) + sv.erase_unordered (i); + else + sv[i]->call (*sv[i]); + + sv.pending = false; + } + } +# endif - if (!FD_ISSET (iow[i]->fd, &rfd)) revents &= ~EVENT_READ; - if (!FD_ISSET (iow[i]->fd, &wfd)) revents &= ~EVENT_WRITE; +# if IOM_IO + for (int i = iow.size (); i--; ) + if (!iow[i]) + iow.erase_unordered (i); + else + { + short revents = iow[i]->events; - if (revents) - iow[i]->call (*iow[i], revents); - } + if (!FD_ISSET (iow[i]->fd, &rfd)) revents &= ~EVENT_READ; + if (!FD_ISSET (iow[i]->fd, &wfd)) revents &= ~EVENT_WRITE; + + if (revents) + iow[i]->call (*iow[i], revents); + } +#endif + } else if (fds < 0 && errno != EINTR) { - perror ("Error while waiting for I/O or time event"); + perror ("io_manager: fatal error while waiting for I/O or time event, aborting."); abort (); } #if IOM_IDLE @@ -325,23 +443,6 @@ void io_manager::loop () #else break; #endif - } } -io_manager::io_manager () -{ - iom_valid = true; - -#if IOM_TIME - set_now (); - - tw0.start (TSTAMP_MAX); -#endif -} - -io_manager::~io_manager () -{ - iom_valid = false; -} - diff --git a/src/iom.h b/src/iom.h index ef7028f6..6c9702c7 100644 --- a/src/iom.h +++ b/src/iom.h @@ -81,57 +81,35 @@ struct io_manager_vec : vector { } }; +// only used as a namespace, and for initialisation purposes class io_manager { -#if IOM_IO - io_manager_vec iow; -#endif -#if IOM_CHECK - io_manager_vec cw; -#endif -#if IOM_TIME - io_manager_vec tw; -#endif -#if IOM_IDLE - io_manager_vec iw; -#endif -#if IOM_SIG - typedef io_manager_vec sig_vec; - vector sw; - static void sighandler (int signum); -#endif - template - void reg (watcher *w, io_manager_vec &queue); + static void reg (watcher &w, io_manager_vec &queue); template - void unreg (watcher *w, io_manager_vec &queue); + static void unreg (watcher &w, io_manager_vec &queue); public: // register a watcher #if IOM_IO - void reg (io_watcher *w); void unreg (io_watcher *w); + static void reg (io_watcher &w); static void unreg (io_watcher &w); #endif #if IOM_TIME - void reg (time_watcher *w); void unreg (time_watcher *w); + static void reg (time_watcher &w); static void unreg (time_watcher &w); #endif #if IOM_CHECK - void reg (check_watcher *w); void unreg (check_watcher *w); + static void reg (check_watcher &w); static void unreg (check_watcher &w); #endif #if IOM_IDLE - void reg (idle_watcher *w); void unreg (idle_watcher *w); + static void reg (idle_watcher &w); static void unreg (idle_watcher &w); #endif #if IOM_SIG - void reg (sig_watcher *w); void unreg (sig_watcher *w); + static void reg (sig_watcher &w); static void unreg (sig_watcher &w); #endif - void loop (); - - io_manager (); - ~io_manager (); + static void loop (); }; -extern io_manager iom; // a singleton, together with it's construction/destruction problems. - struct watcher { int active; /* 0 == inactive, else index into respective vector */ @@ -148,9 +126,9 @@ struct io_watcher : watcher, callback2 { void set (int fd_, short events_) { fd = fd_; events = events_; } void set (short events_) { set (fd, events_); } - void start () { iom.reg (this); } - void start (int fd_, short events_) { set (fd_, events_); iom.reg (this); } - void stop () { iom.unreg (this); } + void start () { io_manager::reg (*this); } + void start (int fd_, short events_) { set (fd_, events_); io_manager::reg (*this); } + void stop () { io_manager::unreg (*this); } template io_watcher (O1 *object, void (O2::*method) (io_watcher &, short)) @@ -168,9 +146,9 @@ struct time_watcher : watcher, callback1 { void set (tstamp when) { at = when; } void operator () () { trigger (); } - void start () { iom.reg (this); } - void start (tstamp when) { set (when); iom.reg (this); } - void stop () { iom.unreg (this); } + void start () { io_manager::reg (*this); } + void start (tstamp when) { set (when); io_manager::reg (*this); } + void stop () { io_manager::unreg (*this); } template time_watcher (O1 *object, void (O2::*method) (time_watcher &)) @@ -183,8 +161,8 @@ struct time_watcher : watcher, callback1 { #if IOM_CHECK // run before checking for new events struct check_watcher : watcher, callback1 { - void start () { iom.reg (this); } - void stop () { iom.unreg (this); } + void start () { io_manager::reg (*this); } + void stop () { io_manager::unreg (*this); } template check_watcher (O1 *object, void (O2::*method) (check_watcher &)) @@ -197,8 +175,8 @@ struct check_watcher : watcher, callback1 { #if IOM_IDLE // run after checking for any i/o, but before waiting struct idle_watcher : watcher, callback1 { - void start () { iom.reg (this); } - void stop () { iom.unreg (this); } + void start () { io_manager::reg (*this); } + void stop () { io_manager::unreg (*this); } template idle_watcher (O1 *object, void (O2::*method) (idle_watcher &)) @@ -213,7 +191,7 @@ struct sig_watcher : watcher, callback1 { int signum; void start (int signum); - void stop () { iom.unreg (this); } + void stop () { io_manager::unreg (*this); } template sig_watcher (O1 *object, void (O2::*method) (sig_watcher &)) diff --git a/src/rxvt.C b/src/rxvt.C index d4a5b13d..617c7c8e 100644 --- a/src/rxvt.C +++ b/src/rxvt.C @@ -34,7 +34,7 @@ try if (!t->init (argc, argv)) return EXIT_FAILURE; - iom.loop (); + io_manager::loop (); return EXIT_SUCCESS; } diff --git a/src/rxvtd.C b/src/rxvtd.C index 6fcec310..6d44441e 100644 --- a/src/rxvtd.C +++ b/src/rxvtd.C @@ -220,7 +220,7 @@ main (int argc, const char *const *argv) printf ("rxvt-unicode daemon listening on %s.\n", sockname); free (sockname); - iom.loop (); + io_manager::loop (); return EXIT_SUCCESS; } diff --git a/src/rxvtutil.h b/src/rxvtutil.h index 9d55c701..fd063ddb 100644 --- a/src/rxvtutil.h +++ b/src/rxvtutil.h @@ -1,6 +1,8 @@ #ifndef RXVT_UTIL_H #define RXVT_UTIL_H +#include + extern class byteorder { static unsigned int e; // at least 32 bits public: @@ -17,7 +19,259 @@ static inline T min (T a, U b) { return a < b ? a : (T)b; } template static inline T max (T a, U b) { return a > b ? a : (T)b; } -#include "simplevec.h" +struct zero_initialized { + void *operator new (size_t s); + void operator delete (void *p, size_t s); +}; + +/* simplevec taken (and heavily modified), from: + * + * MICO --- a free CORBA implementation + * Copyright (C) 1997-98 Kay Roemer & Arno Puder + */ +template +struct simplevec { + typedef T* iterator; + typedef const T* const_iterator; + typedef unsigned long size_type; + +private: + size_type _last, _size; + T *_buf; + +public: + const_iterator begin () const + { + return &_buf[0]; + } + iterator begin () + { + return &_buf[0]; + } + const_iterator end () const + { + return &_buf[_last]; + } + iterator end () + { + return &_buf[_last]; + } + size_type capacity () const + { + return _size; + } + size_type size () const + { + return _last; + } + +private: + static T *alloc (size_type n) + { + return (T *)::operator new ((size_t) (n * sizeof (T))); + } + static void dealloc (T *buf) + { + if (buf) + ::operator delete (buf); + } + + void reserve (iterator where, size_type n) + { + if (_last + n <= _size) { + memmove (where+n, where, (end ()-where)*sizeof (T)); + } else { + size_type sz = _last+n; + sz = (_size == 0) ? max (sz, 5) : max (sz, 2*_size); + T *nbuf = alloc (sz); + if (_buf) { + memcpy (nbuf, begin (), (where-begin ())*sizeof (T)); + memcpy (nbuf + (where-begin ()) + n, where, + (end ()-where)*sizeof (T)); + dealloc (_buf); + } + _buf = nbuf; + _size = sz; + } + } + +public: + void reserve (size_type sz) + { + if (_size < sz) { + sz = (_size == 0) ? max (sz, 5) : max (sz, 2*_size); + T *nbuf = alloc (sz); + if (_buf) { + memcpy (nbuf, begin (), size ()*sizeof (T)); + dealloc (_buf); + } + _buf = nbuf; + _size = sz; + } + } + simplevec () + : _last(0), _size(0), _buf(0) + { + } + simplevec (size_type n, const T& t = T ()) + : _last(0), _size(0), _buf(0) + { + insert (begin (), n, t); + } + simplevec (const_iterator first, const_iterator last) + : _last(0), _size(0), _buf(0) + { + insert (begin (), first, last); + } + simplevec (const simplevec &v) + : _last(0), _size(0), _buf(0) + { + reserve (v._last); + memcpy (_buf, v.begin (), v.size ()*sizeof (T)); + _last = v._last; + } + simplevec &operator= (const simplevec &v) + { + if (this != &v) { + _last = 0; + reserve (v._last); + memcpy (_buf, v.begin (), v.size ()*sizeof (T)); + _last = v._last; + } + return *this; + } + ~simplevec () + { + dealloc (_buf); + } + const T &front () const + { + //ministl_assert (size () > 0); + return _buf[0]; + } + T &front () + { + //ministl_assert (size () > 0); + return _buf[0]; + } + const T &back () const + { + //ministl_assert (size () > 0); + return _buf[_last-1]; + } + T &back () + { + //ministl_assert (size () > 0); + return _buf[_last-1]; + } + bool empty () const + { + return _last == 0; + } + void clear () + { + _last = 0; + } + void push_back (const T &t) + { + reserve (_last+1); + *end () = t; + ++_last; + } + void push_back (T &t) + { + reserve (_last+1); + *end () = t; + ++_last; + } + void pop_back () + { + //ministl_assert (size () > 0); + --_last; + } + const T &operator[] (size_type idx) const + { + //ministl_assert (idx < size ()); + return _buf[idx]; + } + T &operator[] (size_type idx) + { + //ministl_assert (idx < size ()); + return _buf[idx]; + } + iterator insert (iterator pos, const T &t) + { + //ministl_assert (pos <= end ()); + long at = pos - begin (); + reserve (pos, 1); + pos = begin ()+at; + *pos = t; + ++_last; + return pos; + } + iterator insert (iterator pos, const_iterator first, const_iterator last) + { + //ministl_assert (pos <= end ()); + long n = last - first; + long at = pos - begin (); + if (n > 0) { + reserve (pos, n); + pos = begin ()+at; + memcpy (pos, first, (last-first)*sizeof (T)); + _last += n; + } + return pos; + } + iterator insert (iterator pos, size_type n, const T &t) + { + //ministl_assert (pos <= end ()); + long at = pos - begin (); + if (n > 0) { + reserve (pos, n); + pos = begin ()+at; + for (int i = 0; i < n; ++i) + pos[i] = t; + _last += n; + } + return pos; + } + void erase (iterator first, iterator last) + { + if (last != first) { + memmove (first, last, (end ()-last)*sizeof (T)); + _last -= last - first; + } + } + void erase (iterator pos) + { + if (pos != end ()) { + memmove (pos, pos+1, (end ()- (pos+1))*sizeof (T)); + --_last; + } + } +}; + +template +bool operator== (const simplevec &v1, const simplevec &v2) +{ + if (v1.size () != v2.size ()) + return false; + return !v1.size () || !memcmp (&v1[0], &v2[0], v1.size ()*sizeof (T)); +} + +template +bool operator< (const simplevec &v1, const simplevec &v2) +{ + unsigned long minlast = min (v1.size (), v2.size ()); + for (unsigned long i = 0; i < minlast; ++i) { + if (v1[i] < v2[i]) + return true; + if (v2[i] < v1[i]) + return false; + } + return v1.size () < v2.size (); +} + template struct vector : simplevec @@ -117,10 +371,5 @@ struct stringvec : simplevec } }; -struct zero_initialized { - void *operator new (size_t s); - void operator delete (void *p, size_t s); -}; - #endif diff --git a/src/simplevec.h b/src/simplevec.h deleted file mode 100644 index 18806f6e..00000000 --- a/src/simplevec.h +++ /dev/null @@ -1,272 +0,0 @@ -// -*- c++ -*- -/* - * MICO --- a free CORBA implementation - * Copyright (C) 1997-98 Kay Roemer & Arno Puder - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Send comments and/or bug reports to: - * mico@informatik.uni-frankfurt.de - */ - -#ifndef __ministl_simplevec_h__ -#define __ministl_simplevec_h__ - -#include - -template -class simplevec { -public: - typedef T* iterator; - typedef const T* const_iterator; - typedef unsigned long size_type; -private: - size_type _last, _size; - T *_buf; - -public: - const_iterator begin () const - { - return &_buf[0]; - } - iterator begin () - { - return &_buf[0]; - } - const_iterator end () const - { - return &_buf[_last]; - } - iterator end () - { - return &_buf[_last]; - } - size_type capacity () const - { - return _size; - } - size_type size () const - { - return _last; - } - -private: - static T *alloc (size_type n) - { - return (T *)::operator new ((size_t) (n * sizeof (T))); - } - static void dealloc (T *buf) - { - if (buf) - ::operator delete (buf); - } - - void reserve (iterator where, size_type n) - { - if (_last + n <= _size) { - memmove (where+n, where, (end ()-where)*sizeof (T)); - } else { - size_type sz = _last+n; - sz = (_size == 0) ? max (sz, 5) : max (sz, 2*_size); - T *nbuf = alloc (sz); - if (_buf) { - memcpy (nbuf, begin (), (where-begin ())*sizeof (T)); - memcpy (nbuf + (where-begin ()) + n, where, - (end ()-where)*sizeof (T)); - dealloc (_buf); - } - _buf = nbuf; - _size = sz; - } - } -public: - void reserve (size_type sz) - { - if (_size < sz) { - sz = (_size == 0) ? max (sz, 5) : max (sz, 2*_size); - T *nbuf = alloc (sz); - if (_buf) { - memcpy (nbuf, begin (), size ()*sizeof (T)); - dealloc (_buf); - } - _buf = nbuf; - _size = sz; - } - } - simplevec () - : _last (0), _size (0), _buf (0) - { - } - simplevec (size_type n, const T& t = T ()) - : _last (0), _size (0), _buf (0) - { - insert (begin (), n, t); - } - simplevec (const_iterator first, const_iterator last) - : _last (0), _size (0), _buf (0) - { - insert (begin (), first, last); - } - simplevec (const simplevec &v) - : _last (0), _size (0), _buf (0) - { - reserve (v._last); - memcpy (_buf, v.begin (), v.size ()*sizeof (T)); - _last = v._last; - } - simplevec &operator= (const simplevec &v) - { - if (this != &v) { - _last = 0; - reserve (v._last); - memcpy (_buf, v.begin (), v.size ()*sizeof (T)); - _last = v._last; - } - return *this; - } - ~simplevec () - { - dealloc (_buf); - } - const T &front () const - { - //ministl_assert (size () > 0); - return _buf[0]; - } - T &front () - { - //ministl_assert (size () > 0); - return _buf[0]; - } - const T &back () const - { - //ministl_assert (size () > 0); - return _buf[_last-1]; - } - T &back () - { - //ministl_assert (size () > 0); - return _buf[_last-1]; - } - bool empty () const - { - return _last == 0; - } - void clear () - { - _last = 0; - } - void push_back (const T &t) - { - reserve (_last+1); - *end () = t; - ++_last; - } - void push_back (T &t) - { - reserve (_last+1); - *end () = t; - ++_last; - } - void pop_back () - { - //ministl_assert (size () > 0); - --_last; - } - const T &operator[] (size_type idx) const - { - //ministl_assert (idx < size ()); - return _buf[idx]; - } - T &operator[] (size_type idx) - { - //ministl_assert (idx < size ()); - return _buf[idx]; - } - iterator insert (iterator pos, const T &t) - { - //ministl_assert (pos <= end ()); - long at = pos - begin (); - reserve (pos, 1); - pos = begin ()+at; - *pos = t; - ++_last; - return pos; - } - iterator insert (iterator pos, const_iterator first, const_iterator last) - { - //ministl_assert (pos <= end ()); - long n = last - first; - long at = pos - begin (); - if (n > 0) { - reserve (pos, n); - pos = begin ()+at; - memcpy (pos, first, (last-first)*sizeof (T)); - _last += n; - } - return pos; - } - iterator insert (iterator pos, size_type n, const T &t) - { - //ministl_assert (pos <= end ()); - long at = pos - begin (); - if (n > 0) { - reserve (pos, n); - pos = begin ()+at; - for (int i = 0; i < n; ++i) - pos[i] = t; - _last += n; - } - return pos; - } - void erase (iterator first, iterator last) - { - if (last != first) { - memmove (first, last, (end ()-last)*sizeof (T)); - _last -= last - first; - } - } - void erase (iterator pos) - { - if (pos != end ()) { - memmove (pos, pos+1, (end ()- (pos+1))*sizeof (T)); - --_last; - } - } -}; - -template -bool operator== (const simplevec &v1, const simplevec &v2) -{ - if (v1.size () != v2.size ()) - return false; - return !v1.size () || !memcmp (&v1[0], &v2[0], v1.size ()*sizeof (T)); -} - -template -bool operator< (const simplevec &v1, const simplevec &v2) -{ - unsigned long minlast = min (v1.size (), v2.size ()); - for (unsigned long i = 0; i < minlast; ++i) { - if (v1[i] < v2[i]) - return true; - if (v2[i] < v1[i]) - return false; - } - return v1.size () < v2.size (); -} - -#endif -