|
Packit |
a4aae4 |
// -*- mode: c++; c-basic-offset:4 -*-
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// This file is part of libdap, A C++ implementation of the OPeNDAP Data
|
|
Packit |
a4aae4 |
// Access Protocol.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Copyright (c) 2002,2003 OPeNDAP, Inc.
|
|
Packit |
a4aae4 |
// Author: James Gallagher <jgallagher@opendap.org>
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// This library is free software; you can redistribute it and/or
|
|
Packit |
a4aae4 |
// modify it under the terms of the GNU Lesser General Public
|
|
Packit |
a4aae4 |
// License as published by the Free Software Foundation; either
|
|
Packit |
a4aae4 |
// version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// This library is distributed in the hope that it will be useful,
|
|
Packit |
a4aae4 |
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
a4aae4 |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
a4aae4 |
// Lesser General Public License for more details.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// You should have received a copy of the GNU Lesser General Public
|
|
Packit |
a4aae4 |
// License along with this library; if not, write to the Free Software
|
|
Packit |
a4aae4 |
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// (c) COPYRIGHT URI/MIT 1999
|
|
Packit |
a4aae4 |
// Please read the full copyright statement in the file COPYRIGHT_URI.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// Authors:
|
|
Packit |
a4aae4 |
// jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
// Templates for relational operations.
|
|
Packit |
a4aae4 |
//
|
|
Packit |
a4aae4 |
// jhrg 3/24/99
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#ifndef _operators_h
|
|
Packit |
a4aae4 |
#define _operators_h
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#include "GNURegex.h" // GNU Regex class used for string =~ op.
|
|
Packit |
a4aae4 |
#include "ce_expr.tab.hh"
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
namespace libdap {
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Compare two numerical types, both of which are either signed or unsigned.
|
|
Packit |
a4aae4 |
This class is one implementation of the comparison policy used by
|
|
Packit |
a4aae4 |
rops.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@see rops
|
|
Packit |
a4aae4 |
@see USCmp
|
|
Packit |
a4aae4 |
@see SUCmp */
|
|
Packit |
a4aae4 |
template<class T1, class T2>
|
|
Packit |
a4aae4 |
bool Cmp(int op, T1 v1, T2 v2)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
DBGN(cerr << __PRETTY_FUNCTION__ << v1 << " " << op << " " << v2 << endl);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
switch (op) {
|
|
Packit |
a4aae4 |
case SCAN_EQUAL:
|
|
Packit |
a4aae4 |
return v1 == v2;
|
|
Packit |
a4aae4 |
case SCAN_NOT_EQUAL:
|
|
Packit |
a4aae4 |
return v1 != v2;
|
|
Packit |
a4aae4 |
case SCAN_GREATER:
|
|
Packit |
a4aae4 |
return v1 > v2;
|
|
Packit |
a4aae4 |
case SCAN_GREATER_EQL:
|
|
Packit |
a4aae4 |
return v1 >= v2;
|
|
Packit |
a4aae4 |
case SCAN_LESS:
|
|
Packit |
a4aae4 |
return v1 < v2;
|
|
Packit |
a4aae4 |
case SCAN_LESS_EQL:
|
|
Packit |
a4aae4 |
return v1 <= v2;
|
|
Packit |
a4aae4 |
case SCAN_REGEXP:
|
|
Packit |
a4aae4 |
throw Error(malformed_expr, "Regular expressions are supported for strings only.");
|
|
Packit |
a4aae4 |
default:
|
|
Packit |
a4aae4 |
throw Error(malformed_expr, "Unrecognized operator.");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
template<class T>
|
|
Packit |
a4aae4 |
static inline unsigned long long dap_floor_zero(T i)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
return (unsigned long long) ((i < 0) ? 0 : i);
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Compare two numerical types, the first one unsigned and the second
|
|
Packit |
a4aae4 |
signed. If the signed argument is negative, zero is used in the
|
|
Packit |
a4aae4 |
comparison. This class is one implementation of the comparison policy
|
|
Packit |
a4aae4 |
used by rops.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@see rops
|
|
Packit |
a4aae4 |
@see SUCmp
|
|
Packit |
a4aae4 |
@see Cmp */
|
|
Packit |
a4aae4 |
template<class UT1, class T2>
|
|
Packit |
a4aae4 |
bool USCmp(int op, UT1 v1, T2 v2)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
DBGN(cerr << __PRETTY_FUNCTION__ << v1 << " " << op << " " << v2 << endl);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
switch (op) {
|
|
Packit |
a4aae4 |
case SCAN_EQUAL:
|
|
Packit |
a4aae4 |
return v1 == dap_floor_zero<T2>(v2);
|
|
Packit |
a4aae4 |
case SCAN_NOT_EQUAL:
|
|
Packit |
a4aae4 |
return v1 != dap_floor_zero<T2>(v2);
|
|
Packit |
a4aae4 |
case SCAN_GREATER:
|
|
Packit |
a4aae4 |
return v1 > dap_floor_zero<T2>(v2);
|
|
Packit |
a4aae4 |
case SCAN_GREATER_EQL:
|
|
Packit |
a4aae4 |
return v1 >= dap_floor_zero<T2>(v2);
|
|
Packit |
a4aae4 |
case SCAN_LESS:
|
|
Packit |
a4aae4 |
return v1 < dap_floor_zero<T2>(v2);
|
|
Packit |
a4aae4 |
case SCAN_LESS_EQL:
|
|
Packit |
a4aae4 |
return v1 <= dap_floor_zero<T2>(v2);
|
|
Packit |
a4aae4 |
case SCAN_REGEXP:
|
|
Packit |
a4aae4 |
throw Error(malformed_expr, "Regular expressions are supported for strings only.");
|
|
Packit |
a4aae4 |
default:
|
|
Packit |
a4aae4 |
throw Error(malformed_expr, "Unrecognized operator.");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Compare two numerical types, the first one signed and the second
|
|
Packit |
a4aae4 |
unsigned. If the signed argument is negative, zero is used in the
|
|
Packit |
a4aae4 |
comparison. This class is one implementation of the comparison policy
|
|
Packit |
a4aae4 |
used by rops. This class is here to make writing the Byte::ops, ...
|
|
Packit |
a4aae4 |
member functions simpler. It is not necessary since the functions could
|
|
Packit |
a4aae4 |
twidle the order of arguments to rops and use <tt>USCmp</tt>. Having
|
|
Packit |
a4aae4 |
this class make Byte:ops, ... simpler to read and write.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@see Byte::ops
|
|
Packit |
a4aae4 |
@see USCmp
|
|
Packit |
a4aae4 |
@see Cmp
|
|
Packit |
a4aae4 |
@see ops */
|
|
Packit |
a4aae4 |
template<class T1, class UT2>
|
|
Packit |
a4aae4 |
bool SUCmp(int op, T1 v1, UT2 v2)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
DBGN(cerr << __PRETTY_FUNCTION__ << v1 << " " << op << " " << v2 << endl);
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
switch (op) {
|
|
Packit |
a4aae4 |
case SCAN_EQUAL:
|
|
Packit |
a4aae4 |
return dap_floor_zero<T1>(v1) == v2;
|
|
Packit |
a4aae4 |
case SCAN_NOT_EQUAL:
|
|
Packit |
a4aae4 |
return dap_floor_zero<T1>(v1) != v2;
|
|
Packit |
a4aae4 |
case SCAN_GREATER:
|
|
Packit |
a4aae4 |
return dap_floor_zero<T1>(v1) > v2;
|
|
Packit |
a4aae4 |
case SCAN_GREATER_EQL:
|
|
Packit |
a4aae4 |
return dap_floor_zero<T1>(v1) >= v2;
|
|
Packit |
a4aae4 |
case SCAN_LESS:
|
|
Packit |
a4aae4 |
return dap_floor_zero<T1>(v1) < v2;
|
|
Packit |
a4aae4 |
case SCAN_LESS_EQL:
|
|
Packit |
a4aae4 |
return dap_floor_zero<T1>(v1) <= v2;
|
|
Packit |
a4aae4 |
case SCAN_REGEXP:
|
|
Packit |
a4aae4 |
throw Error(malformed_expr, "Regular expressions are supported for strings only.");
|
|
Packit |
a4aae4 |
default:
|
|
Packit |
a4aae4 |
throw Error(malformed_expr, "Unrecognized operator.");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
/** Compare two string types.
|
|
Packit |
a4aae4 |
This class is one implementation of the comparison policy used by
|
|
Packit |
a4aae4 |
rops.
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
@see rops */
|
|
Packit |
a4aae4 |
template<class T1, class T2>
|
|
Packit |
a4aae4 |
bool StrCmp(int op, T1 v1, T2 v2)
|
|
Packit |
a4aae4 |
{
|
|
Packit |
a4aae4 |
switch (op) {
|
|
Packit |
a4aae4 |
case SCAN_EQUAL:
|
|
Packit |
a4aae4 |
return v1 == v2;
|
|
Packit |
a4aae4 |
case SCAN_NOT_EQUAL:
|
|
Packit |
a4aae4 |
return v1 != v2;
|
|
Packit |
a4aae4 |
case SCAN_GREATER:
|
|
Packit |
a4aae4 |
return v1 > v2;
|
|
Packit |
a4aae4 |
case SCAN_GREATER_EQL:
|
|
Packit |
a4aae4 |
return v1 >= v2;
|
|
Packit |
a4aae4 |
case SCAN_LESS:
|
|
Packit |
a4aae4 |
return v1 < v2;
|
|
Packit |
a4aae4 |
case SCAN_LESS_EQL:
|
|
Packit |
a4aae4 |
return v1 <= v2;
|
|
Packit |
a4aae4 |
case SCAN_REGEXP: {
|
|
Packit |
a4aae4 |
Regex r(v2.c_str());
|
|
Packit |
a4aae4 |
return r.match(v1.c_str(), v1.length()) > 0;
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
default:
|
|
Packit |
a4aae4 |
throw Error(malformed_expr, "Unrecognized operator.");
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
}
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
} // namespace libdap
|
|
Packit |
a4aae4 |
|
|
Packit |
a4aae4 |
#endif // _operators_h
|