repo: rxvt-unicode-sixel action: commit revision: path_from: revision_from: aef8b292f4f8535be5a7c3ae6a1acbe5047f1bbd: path_to: revision_to:
commit aef8b292f4f8535be5a7c3ae6a1acbe5047f1bbd Author: Marc LehmannDate: Thu Sep 2 07:44:40 2004 +0000 *** empty log message *** diff --git a/src/iom.C b/src/iom.C
--- 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
--- 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
--- 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
--- 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
--- 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 18806f6e0810ba9439aaf2b41b6989461bc04c0d..0000000000000000000000000000000000000000 --- 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 -
-----END OF PAGE-----