FieldSelection.h 4.55 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#ifndef COOLKERNEL_FIELDSELECTION_H
#define COOLKERNEL_FIELDSELECTION_H 1

// First of all, set/unset CORAL290, COOL300, COOL400 and COOL_HAS_CPP11 macros
#include "CoolKernel/VersionInfo.h"

// Include files
#ifdef COOL400CPP11ENUM
#include <ostream>
#endif
#include "CoolKernel/FieldSpecification.h"
#include "CoolKernel/IRecordSelection.h"
#include "CoolKernel/Record.h"

namespace cool
{

  //--------------------------------------------------------------------------

  /** @class FieldSelection FieldSelection.h
   *
   *  Simple selection on a data field.
   *
   *  @author Andrea Valassi and Martin Wache
   *  @date   2008-07-28
   *///

  class FieldSelection : virtual public IRecordSelection
  {

  public:

    /// Binary relation operator (comparison to a reference value).
#ifndef COOL400CPP11ENUM
    enum Relation { EQ, NE, GT, GE, LT, LE };
#else
    enum class Relation { EQ, NE, GT, GE, LT, LE };

    // Overloaded operator<< for cool::FieldSelection::Relation
    inline friend std::ostream&
    operator<<( std::ostream& s, const cool::FieldSelection::Relation& rel )
    {
      return s << (int)rel;
    }
#endif

    /// Unary nullness operator (comparison to NULL).
#ifndef COOL400CPP11ENUM
    enum Nullness { IS_NULL, IS_NOT_NULL };
#else
    enum class Nullness { IS_NULL, IS_NOT_NULL };

    // Overloaded operator<< for cool::FieldSelection::Nullness
    inline friend std::ostream&
    operator<<( std::ostream& s, const cool::FieldSelection::Nullness& nul )
    {
      return s << (int)nul;
    }
#endif

    /// Describe a binary relation operator.
    static const std::string describe( Relation relation );

    /// Describe a unary nullness operator.
    static const std::string describe( Nullness nullness );

  public:

    /// Destructor.
    virtual ~FieldSelection();

    /// Constructor for comparison to non-NULL reference values.
    template<typename T>
    FieldSelection( const std::string& name,
                    const StorageType::TypeId typeId,
                    Relation relation,
                    const T& refValue );

    /// Constructor for comparison to NULL.
    FieldSelection( const std::string& name,
                    const StorageType::TypeId typeId,
                    Nullness nullness );

    /// Can the selection be applied to a record with the given specification?
    bool canSelect( const IRecordSpecification& spec ) const;

    /// Apply the selection to the given record.
    bool select( const IRecord& record ) const;

    /// Clone the record selection (and any objects referenced therein).
    IRecordSelection* clone() const;

    /// Nullness operator for this selection.
    /// Returns IS_NOT_NULL for comparisons to non-NULL reference values.
    Nullness nullness() const;

    /// Relation operator for this selection.
    /// Returns EQ or NE for comparisons to NULL reference values.
    Relation relation() const;

    /// Reference value for this selection.
    /// Returns a NULL field for comparisons to NULL reference values.
    const IField& referenceValue() const;

  private:

    /// Standard constuctor is private
    FieldSelection();

    /// Copy constructor - reimplemented for the clone() method
    FieldSelection( const FieldSelection& rhs );

    /// Assignment operator is private
    FieldSelection& operator=( const FieldSelection& rhs );

    /// Initialize - extra checks for constructor of comparison to non-NULL.
    void initialize();

  private:

    /// The reference value (as a Record with one and only one field).
    /// The specification of the field is the one this selection can select.
    /// For comparisons to NULL, this field is set to NULL.
    Record m_refValue;

    /// The relation to the ref value (eg. 'GT': is this field > ref value?).
    /// For comparisons to NULL, this is set to 'EQ' or 'NE'.
    Relation m_relation;

  };

  //---------------------------------------------------------------------------

  template<typename T>
  inline FieldSelection::FieldSelection( const std::string& name,
                                         const StorageType::TypeId typeId,
                                         Relation relation,
                                         const T& refValue )
    : m_refValue( FieldSpecification( name, typeId ) )
    , m_relation( relation )
  {
    // Set the reference value and ensure that T and typeId are compatible
    m_refValue[0].setValue( refValue );
    // Extra cross-checks for constructor of comparison to non-NULL
    initialize();
  }

  //---------------------------------------------------------------------------

}
#endif // COOLKERNEL_FIELDSELECTION_H