/*-------------------------------------------------------------------------------------*/
/*  NOMAD - Nonsmooth Optimization by Mesh Adaptive Direct search - version 3.0.0      */
/*                                                                                     */
/*  Copyright (C) 2001-2008  Mark Abramson        - the Boeing Company, Seattle        */
/*                           Charles Audet        - Ecole Polytechnique, Montreal      */
/*                           Gilles Couture       - Ecole Polytechnique, Montreal      */
/*                           John Dennis          - Rice University, Houston           */
/*                           Sebastien Le Digabel - Ecole Polytechnique, Montreal      */
/*                                                                                     */
/*  funded in part by AFOSR and Exxon Mobil                                            */
/*                                                                                     */
/*  Author: Sebastien Le Digabel                                                       */
/*                                                                                     */
/*  Contact information:                                                               */
/*    Ecole Polytechnique de Montreal - GERAD                                          */
/*    C.P. 6079, Succ. Centre-ville, Montreal (Quebec) H3C 3A7 Canada                  */
/*    e-mail: Sebastien.Le.Digabel@gerad.ca                                            */
/*    phone : 1-514-340-6053 #6673                                                     */
/*    fax   : 1-514-340-5665                                                           */
/*                                                                                     */
/*  This program is free software: you can redistribute it and/or modify it under the  */
/*  terms of the GNU General Public License as published by the Free Software          */
/*  Foundation, either version 3 of the License, or (at your option) any later         */
/*  version.                                                                           */
/*                                                                                     */
/*  This program 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 General Public License for more details.          */
/*                                                                                     */
/*  You should have received a copy of the GNU General Public License along with this  */
/*  program. If not, see <http://www.gnu.org/licenses/>.                               */
/*                                                                                     */
/*  You can find information on the NOMAD software at www.gerad.ca/nomad               */
/*-------------------------------------------------------------------------------------*/
#ifndef __SET_ELEMENT__
#define __SET_ELEMENT__

#include "defines.hpp"

// forward declaration of NOMAD::Double:
namespace NOMAD {
class Double;
}

template <class T>
class Set_Element {

private:

#ifdef DEBUG
  static int _cardinality;       // number of Set_Element's in memory.
  static int _max_cardinality;   // max number of Set_Element's in memory.
#endif

  const T  * _el;                // the element

  // affectation operator:
  Set_Element & operator = ( const Set_Element & );

public:
  
  // constructor:
  explicit Set_Element ( const T * el ) : _el(el) {
#ifdef DEBUG
    ++Set_Element::_cardinality;
    if ( Set_Element::_cardinality > Set_Element::_max_cardinality )
      ++Set_Element::_max_cardinality;
#endif
  }
  
  // copy constructor:
  explicit Set_Element ( const Set_Element & sp ): _el(sp._el) {
#ifdef DEBUG
    ++Set_Element::_cardinality;
    if ( Set_Element::_cardinality > Set_Element::_max_cardinality )
      ++Set_Element::_max_cardinality;
#endif
  }

  // destructor:
  virtual ~Set_Element ( void ) {
#ifdef DEBUG
    --Set_Element::_cardinality;
#endif
  }

  // specific Priority_Eval_Point elements of comparison
  // (only Priority_Eval_Point::get_priority_criteria()  does something):
  virtual void get_priority_criteria ( NOMAD::Double & c1 ,
 				       NOMAD::Double & c2 ,
 				       NOMAD::Double & c3 ,
 				       NOMAD::Double & c4   ) const {}

  // comparison operator:
  virtual bool operator < ( const Set_Element & se ) const = 0;

  // access to the element:
  const T * get_element ( void         ) const { return _el; }

  // set an element:
  void      set_element ( const T * el )       { _el = el;   }

#ifdef DEBUG
  static int get_cardinality     ( void ) { return Set_Element::_cardinality;     }
  static int get_max_cardinality ( void ) { return Set_Element::_max_cardinality; }
#endif

};

#ifdef DEBUG
template<class T> int Set_Element<T>::_cardinality     = 0;
template<class T> int Set_Element<T>::_max_cardinality = 0;
#endif

#endif
