// $Header: /usr/u/moudgill/project/Socket/RCS/select.H,v 1.5 1992/09/29 15:01:07 moudgill Exp moudgill $
// 19th December, 1991. Mayan Moudgill.
// $Id: select.H,v 1.5 1992/09/29 15:01:07 moudgill Exp moudgill $
#ifndef mSELECT_H
#define mSELECT_H

#include <sys/types.h>
#include <sys/time.h>
#ifndef __linux__
#include <osfcn.h>
#include <libc.h>
#endif
#include <stdlib.h>
#include <iostream.h>

class selset {
   friend class         seliter;
   friend ostream&      operator<<(ostream&, selset&);
   friend int           selwait(selset&, selset&, selset&);
   friend int           selpoll(selset&, selset&, selset&);
   friend int           seltime(double, selset&, selset&, selset&);
protected:
   enum {
      totalsize         = FD_SETSIZE,
      wordsize          = NFDBITS,
      numberwords       = howmany(FD_SETSIZE, NFDBITS),
      msbmask           = ~(1 << (NFDBITS - 1)),
   };
   int             size;
   int                  max;
   fd_set               set;

   void                 setsize();
   void                 setmax(int);
public:
                        selset();
        		selset(selset *);
   selset&              operator += (int);
   selset&              operator -= (int);
   int                  operator [] (int);
};

class seliter {
private:
   fd_mask             val;
   int                 ix;
   int                 num;
   selset              sel;
public:
   int                 operator () (selset&);
   int                 operator  ! ();
   int                 operator ++ ();
};

inline selset&          selset::operator += (int bit)
{
   if( !FD_ISSET(bit, &set) ) {
      FD_SET(bit, &set);
      size++;
      if( bit > max) {
         max = bit;
      }
   }
   return *this;
}

inline selset&          selset::operator -= (int bit)
{
   if( bit >=0 && bit <= max && FD_ISSET(bit, &set) ) {
      FD_CLR(bit, &set);
      size--;
      if( bit == max) {
         if( size == 0 ) {
            max = -1;
         }
         else {
            setmax(max);
         }
      }
   }
   return *this;
}

inline int              selset::operator [] (int bit)
{
unsigned long res;
   if( bit < 0 || bit > max) {
      res = 0;
   }
   else {
      res = FD_ISSET(bit, &set);
   }
   return res;
}

inline int              seliter::operator !()
{
   return num <= sel.max;
}
#endif
