envelope.h

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C头文件 代码 · 共 451 行 · 第 1/2 页

H
451
字号
inline CoolEnvelope operator op (const CoolLetter& arg1, const CoolEnvelope& arg2){\
  CoolLetter temp(arg1);                        /*Deep copy of arg1*/         \
  temp op_equal *((CoolLetter*) &arg2);         /*Mutate with op arg2*/       \
  CoolEnvelope& result = *((CoolEnvelope*) &temp);/*Same physical object*/    \
  return result;                                /*Copy envelope only*/        \
}                                                                             \
                                                                              \
inline CoolEnvelope& operator op (CoolEnvelope& arg1, const CoolLetter& arg2) {\
  CoolLetter& temp = *((CoolLetter*) &arg1);    /*Reuse arg1*/                \
  temp op_equal arg2;                           /*Mutate in place*/           \
  return arg1;                                  /*Envelope not copied*/       \
}                                                                             \
                                                                              \
inline CoolEnvelope& operator op (CoolEnvelope& arg1, const CoolEnvelope& arg2) {\
  CoolLetter& temp = *((CoolLetter*) &arg1);    /*Reuse arg1*/                \
  temp op_equal *((CoolLetter*) &arg2);         /*Mutate in place*/           \
  return arg1;                                  /*Envelope not copied*/       \
}                                                                             

  // Arithmetic operators:
#ifdef ENVELOPE_PLUS                            // iff operator+= can be in place
  IMPLEMENT_ENVELOPE_OPERATOR(+,+=)
#endif

#ifdef ENVELOPE_MINUS                           // iff operator-= can be in place
  IMPLEMENT_ENVELOPE_OPERATOR(-,-=)
#endif
#ifdef ENVELOPE_STAR                            // iff operator*= can be in place
  IMPLEMENT_ENVELOPE_OPERATOR(*,*=)
#endif
#ifdef ENVELOPE_SLASH                           // iff operator/= can be in place
  IMPLEMENT_ENVELOPE_OPERATOR(/,/=)
#endif
#ifdef ENVELOPE_PERCENT                         // iff operator%= can be in place
  IMPLEMENT_ENVELOPE_OPERATOR(%,%=)
#endif

  // Logical operators:
#ifdef ENVELOPE_VERTICAL                        // iff operator|= can be in place
  IMPLEMENT_ENVELOPE_OPERATOR(|,|=)
#endif
#ifdef ENVELOPE_AMPERSAND                       // iff operator&= can be in place
  IMPLEMENT_ENVELOPE_OPERATOR(&,&=)
#endif
#ifdef ENVELOPE_CARET                           // iff operator^= can be in place
  IMPLEMENT_ENVELOPE_OPERATOR(^,^=)
#endif

  // Shift operators:
#ifdef ENVELOPE_DOUBLE_LEFT_BRACKET             // iff operator<<= can be in place
  IMPLEMENT_ENVELOPE_OPERATOR(<<,<<=)
#endif
#ifdef ENVELOPE_DOUBLE_RIGHT_BRACKET            // iff operator>>= can be in place
  IMPLEMENT_ENVELOPE_OPERATOR(>>,>>=)
#endif

#undef IMPLEMENT_ENVELOPE_OPERATOR              // Delete macro definition

#else    // new way: CoolEnvelope as class template

#ifndef CoolEnvelope_H
#define CoolEnvelope_H

template<class CoolLetter>
class CoolEnvelope : public CoolLetter {        // Inherit all from class CoolLetter
friend class CoolLetter;                        

public:                                         
  /*inline##*/ CoolEnvelope();                  // Empty Constructor
  /*inline##*/ CoolEnvelope(CoolEnvelope<CoolLetter>&);         // Copy constructor
  /*inline##*/ ~CoolEnvelope();                 // Destructor

  friend ostream& operator<< (ostream&, const CoolEnvelope&); 
  friend ostream& operator<< (ostream&, const CoolEnvelope*);

  // should be defined as member function of Letter class
  // friend CoolLetter& operator= (CoolLetter&, CoolEnvelope&);

  static inline void shallow_swap (CoolEnvelope*, CoolEnvelope*);
protected:
};

// Envelope() -- Empty constructor creates an envelope wrapping an empty letter
// Input:     none
// Ouput:     envelope reference

template<class CoolLetter>
inline CoolEnvelope<CoolLetter>::CoolEnvelope() 
: CoolLetter()                                  // create empty letter inside
{}                                              // nothing for envelope


// Envelope() -- Copy constructor, swapping the contents of letter over.
// Input:     envelope wraping a non null letter
// Ouput:     envelope with contents of letter being swapped over.

template<class CoolLetter>
inline CoolEnvelope<CoolLetter>::CoolEnvelope(CoolEnvelope<CoolLetter>& env) {
  this->shallow_swap (this, &env);              // swap contents over
}

// ~Envelope() -- Destructor, destroy letter too if non null.
// Input:     none
// Output:    none

template<class CoolLetter>
inline CoolEnvelope<CoolLetter>::~CoolEnvelope() {}             // delete letter by inherit.


// operator=  -- Assignment from a envelope back to real letter.
//               Should be defined in CoolLetter class, not here.
// Input:     envelope reference
// Output:    letter reference with contents in envelope being swapped over
// 
// inline CoolLetter& operator= (CoolLetter& let, CoolEnvelope& env) {
//   shallow_swap ((CoolEnvelope*) &let, &env);  // same physical layout
//   return let;
// }            

// shallow_swap() -- Swap contents by doing shallow copy of bytes.
// Input:    pointer to two envelopes
// Output:   none, contents of envelopes are swapped.

template<class CoolLetter>
inline void CoolEnvelope<CoolLetter>::shallow_swap (CoolEnvelope<CoolLetter>* env1, CoolEnvelope<CoolLetter>* env2) {
  int n = sizeof(CoolEnvelope<CoolLetter>);                     // n = sizeof(CoolLetter)
  char* temp = new char[n];                     // temporary space for swap
  char* env1_contents = (char*) env1;           // copy n bytes starting from ptr
  char* env2_contents = (char*) env2;   
  memcpy(temp, env1_contents, n);               // shallow swap the contents of
  memcpy(env1_contents, env2_contents, n);      // env1 and env2
  memcpy(env2_contents, temp, n);
  delete [] temp;                               // free temp space for swap
}

// operator<<  -- Overload output operator to print envelope
// Input:    os, envelope reference
// Output:   os

template<class CoolLetter>
inline ostream& operator<< (ostream& os, const CoolEnvelope<CoolLetter>& env) {
  return os << *((CoolLetter*) &env);
}

// operator<<  -- Overload output operator to print envelope
// Input:    os, envelope pointer
// Output:   os

template<class CoolLetter>
inline ostream& operator<< (ostream& os, const CoolEnvelope<CoolLetter>* env) {
  return os << *((CoolLetter*) env);
}

// operator op -- Use operator op_equal, and return an envelope by value
//                so that deep copy of the object is avoided.
//                For generality, operations are assumed non symmetric.
// Input:    type reference, envelope reference, all 4 permutations.
// Output:   envelope returned by value


#define PASTE_(x,y) x##y
#define PASTE(x,y) PASTE_(x,y)
#define CoolEnvOp(name) PASTE(PASTE(CoolEnvelope,_),name)
//## Should make 'name' a member func of CoolEnvelope instead, but
// BC++ template bug expands out all member funcs even if never used

// Define for each operator OP that can be done in place:
//inline CoolEnvelope<CoolLetter> operator OP (const CoolLetter&arg1, const CoolLetter&arg2)
//   { return CoolEnvOp(NAME)(arg1, arg2); }

#define DEFINE_ENVELOPE_OPERATOR(name,op,op_equal)                            \
template<class CoolLetter> \
inline CoolEnvelope<CoolLetter> CoolEnvOp(name) (const CoolLetter& arg1, const CoolLetter& arg2) {\
  CoolLetter temp(arg1);                        /*Deep copy of arg1*/         \
  temp op_equal arg2;                           /*Mutate with op arg2*/       \
  CoolEnvelope<CoolLetter>& result = *((CoolEnvelope<CoolLetter>*) &temp);/*Same physical object*/    \
  return result;                                /*Copy envelope only*/        \
}                                                                             \
                                                                              \
template<class CoolLetter> \
inline CoolEnvelope<CoolLetter>& operator op (const CoolLetter& arg1, const CoolEnvelope<CoolLetter>& arg2) {\
  CoolLetter temp(arg1);                        /*Deep copy of arg1*/         \
  temp op_equal *((CoolLetter*) &arg2);         /*Mutate with op arg2*/       \
  CoolEnvelope<CoolLetter>& result = *((CoolEnvelope<CoolLetter>*) &temp);/*Same physical object*/    \
  return result;                                /*Copy envelope only*/        \
}                                                                             \
                                                                              \
template<class CoolLetter> \
inline CoolEnvelope<CoolLetter>& operator op (CoolEnvelope<CoolLetter>& arg1, const CoolLetter& arg2) {\
  CoolLetter& temp = *((CoolLetter*) &arg1);    /*Reuse arg1*/                \
  temp op_equal arg2;                           /*Mutate in place*/           \
  return arg1;                                  /*Envelope not copied*/       \
}                                                                             \
                                                                              \
template<class CoolLetter> \
inline CoolEnvelope<CoolLetter>& operator op (CoolEnvelope<CoolLetter>& arg1, const CoolEnvelope<CoolLetter>& arg2) {\
  CoolLetter& temp = *((CoolLetter*) &arg1);    /*Reuse arg1*/                \
  temp op_equal *((CoolLetter*) &arg2);         /*Mutate in place*/           \
  return arg1;                                  /*Envelope not copied*/       \
} \

  // Arithmetic operators:
DEFINE_ENVELOPE_OPERATOR(add,+,+=)
DEFINE_ENVELOPE_OPERATOR(minus,-,-=)
DEFINE_ENVELOPE_OPERATOR(star,*,*=)
DEFINE_ENVELOPE_OPERATOR(slash,/,/=)
DEFINE_ENVELOPE_OPERATOR(percent,%,%=)

  // Logical operators:
DEFINE_ENVELOPE_OPERATOR(vertical,|,|=)
DEFINE_ENVELOPE_OPERATOR(ampersand,&,&=)
DEFINE_ENVELOPE_OPERATOR(caret,^,^=)

  // Shift operators:
DEFINE_ENVELOPE_OPERATOR(double_left_bracket,<<,<<=)
DEFINE_ENVELOPE_OPERATOR(double_right_bracket,>>,>>=)

#undef DEFINE_ENVELOPE_OPERATOR         // Delete macro definition


#endif // CoolEnvelope_H

#endif // #ifdef CoolLetter

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?