Commit ace06802 authored by Christophe Gonzales's avatar Christophe Gonzales

adding testunits for continuous variables + improving exception in ContinuousVariable's operator[]

parent b15240f4
......@@ -88,14 +88,17 @@ namespace gum {
/// @{
/// copy operator
ContinuousVariable<GUM_SCALAR>& operator= (const ContinuousVariable<GUM_SCALAR>& from );
ContinuousVariable<GUM_SCALAR>&
operator= (const ContinuousVariable<GUM_SCALAR>& from );
/// generalized copy operator
template <typename TX_VAL>
ContinuousVariable<GUM_SCALAR>& operator= (const ContinuousVariable<TX_VAL>& from );
ContinuousVariable<GUM_SCALAR>&
operator= (const ContinuousVariable<TX_VAL>& from );
/// move operator
ContinuousVariable<GUM_SCALAR>& operator= (ContinuousVariable<GUM_SCALAR>&& from );
ContinuousVariable<GUM_SCALAR>&
operator= (ContinuousVariable<GUM_SCALAR>&& from );
/// returns the T_VAL corresponding to a string
/** @throw OutOfBounds is raised if the value does not belong to the
......@@ -161,6 +164,9 @@ namespace gum {
// the upper bound.
GUM_SCALAR __upper_bound;
template <typename TX_VAL>
friend class ContinuousVariable;
};
......@@ -168,6 +174,15 @@ namespace gum {
template <typename T_VAL>
std::ostream& operator<<(std::ostream&, const ContinuousVariable<T_VAL>& );
// specialized operator[] for real numbers
template <>
float ContinuousVariable<float>::operator[] ( const std::string& str ) const;
template <>
double ContinuousVariable<double>::operator[] ( const std::string& str ) const;
} /* namespace gum */
// always include the template implementation
......
......@@ -35,13 +35,23 @@ namespace gum {
INLINE float
ContinuousVariable<float>::operator[] ( const std::string& str ) const {
float value;
std::size_t pos;
try {
value = std::stof ( str );
value = std::stof ( str, &pos );
}
catch ( ... ) {
GUM_ERROR ( TypeError, "cannot convert the string into a float" );
catch ( std::invalid_argument& ) {
GUM_ERROR ( TypeError, "the value is not a number" );
}
catch ( std::out_of_range& ) {
GUM_ERROR ( OutOfBounds, "the value is too huge" );
}
// check whether there remains non-space unprocessed characters
for ( auto iter = str.begin() + pos, end = str.end (); iter != end; ++iter ) {
if ( ! std::isspace(static_cast<unsigned char>( *iter ) ) )
GUM_ERROR ( TypeError, "the value is not a number" );
}
if ( belongs ( value ) )
return value;
else
......@@ -52,16 +62,26 @@ namespace gum {
/// returns the GUM_SCALAR corresponding to a string, specialized for doubles
template <>
ALWAYS_INLINE double
INLINE double
ContinuousVariable<double>::operator[] ( const std::string& str ) const {
double value;
std::size_t pos;
try {
value = std::stod ( str );
value = std::stod ( str, &pos );
}
catch ( ... ) {
GUM_ERROR ( TypeError, "cannot convert the string into a float" );
catch ( std::invalid_argument& ) {
GUM_ERROR ( TypeError, "the value is not a number" );
}
catch ( std::out_of_range& ) {
GUM_ERROR ( OutOfBounds, "the value is too huge" );
}
// check whether there remains non-space unprocessed characters
for ( auto iter = str.begin() + pos, end = str.end (); iter != end; ++iter ) {
if ( ! std::isspace(static_cast<unsigned char>( *iter ) ) )
GUM_ERROR ( TypeError, "the value is not a number" );
}
if ( belongs ( value ) )
return value;
else
......
......@@ -24,6 +24,8 @@
* @author Christophe GONZALES and Pierre-Henri WUILLEMIN
*/
#include <utility>
#include <cerrno>
#include <cstdlib>
#include <agrum/agrum.h>
#include <agrum/variables/continuousVariable.h>
......@@ -37,9 +39,9 @@ namespace gum {
template <typename GUM_SCALAR>
INLINE
ContinuousVariable<GUM_SCALAR>::ContinuousVariable ( const std::string& aName,
const std::string& aDesc,
GUM_SCALAR lower_bound,
GUM_SCALAR upper_bound )
const std::string& aDesc,
GUM_SCALAR lower_bound,
GUM_SCALAR upper_bound )
: Variable(aName, aDesc)
, __lower_bound ( lower_bound )
, __upper_bound ( upper_bound ) {
......@@ -93,7 +95,8 @@ namespace gum {
/// Copy Factory.
template <typename GUM_SCALAR>
INLINE ContinuousVariable<GUM_SCALAR>* ContinuousVariable<GUM_SCALAR>::clone() const {
INLINE ContinuousVariable<GUM_SCALAR>*
ContinuousVariable<GUM_SCALAR>::clone() const {
return new ContinuousVariable<GUM_SCALAR> ( *this );
}
......@@ -101,7 +104,8 @@ namespace gum {
/// copy operator
template <typename GUM_SCALAR>
INLINE ContinuousVariable<GUM_SCALAR>&
ContinuousVariable<GUM_SCALAR>::operator= (const ContinuousVariable<GUM_SCALAR>& from ) {
ContinuousVariable<GUM_SCALAR>::operator= (
const ContinuousVariable<GUM_SCALAR>& from ) {
Variable::operator= ( from );
__lower_bound = from.__lower_bound;
__upper_bound = from.__upper_bound;
......@@ -113,7 +117,8 @@ namespace gum {
template <typename GUM_SCALAR>
template <typename TX_VAL>
INLINE ContinuousVariable<GUM_SCALAR>&
ContinuousVariable<GUM_SCALAR>::operator= (const ContinuousVariable<TX_VAL>& from ) {
ContinuousVariable<GUM_SCALAR>::operator= (
const ContinuousVariable<TX_VAL>& from ) {
Variable::operator= ( from );
__lower_bound = from.__lower_bound;
__upper_bound = from.__upper_bound;
......@@ -124,7 +129,8 @@ namespace gum {
/// move operator
template <typename GUM_SCALAR>
INLINE ContinuousVariable<GUM_SCALAR>&
ContinuousVariable<GUM_SCALAR>::operator= (ContinuousVariable<GUM_SCALAR>&& from ) {
ContinuousVariable<GUM_SCALAR>::operator= (
ContinuousVariable<GUM_SCALAR>&& from ) {
Variable::operator= ( std::move ( from ) );
__lower_bound = from.__lower_bound;
__upper_bound = from.__upper_bound;
......
/***************************************************************************
* Copyright (C) 2017 by Pierre-Henri WUILLEMIN and Christophe GONZALES *
* {prenom.nom}_at_lip6.fr *
* *
* 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 2 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, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <iostream>
#include <sstream>
#include <string>
#include <regex>
#include <cxxtest/AgrumTestSuite.h>
#include <cxxtest/testsuite_utils.h>
#include <agrum/variables/continuousVariable.h>
namespace gum_tests {
class ContinuousVariableTestSuite : public CxxTest::TestSuite {
public:
void test_constructors () {
gum::ContinuousVariable<> var1("x1", "" );
TS_ASSERT ( var1.upperBound () ==
std::numeric_limits<float>::infinity () );
TS_ASSERT ( var1.lowerBound () ==
-std::numeric_limits<float>::infinity () );
gum::ContinuousVariable<> var2("x2", "", -10, 10 );
TS_ASSERT ( var2.lowerBound () == -10.0f );
TS_ASSERT ( var2.upperBound () == 10.0f );
gum::ContinuousVariable<> var3( var2 );
TS_ASSERT ( var3.lowerBound () == -10.0f );
TS_ASSERT ( var3.upperBound () == 10.0f );
gum::ContinuousVariable<double> var4( var3 );
TS_ASSERT ( var4.lowerBound () == -10.0 );
TS_ASSERT ( var4.upperBound () == 10.0 );
gum::ContinuousVariable<double> var5( std::move ( var4 ) );
TS_ASSERT ( var4.lowerBound () == -10.0 );
TS_ASSERT ( var4.upperBound () == 10.0 );
gum::ContinuousVariable<double>* var6 = var5.clone ();
TS_ASSERT ( var6->lowerBound () == -10.0 );
TS_ASSERT ( var6->upperBound () == 10.0 );
delete var6;
var3 = var1;
TS_ASSERT ( var3.upperBound () ==
std::numeric_limits<float>::infinity () );
TS_ASSERT ( var3.lowerBound () ==
-std::numeric_limits<float>::infinity () );
var3 = var5;
TS_ASSERT ( var3.lowerBound () == -10.0f );
TS_ASSERT ( var3.upperBound () == 10.0f );
var4.setUpperBound ( 5 );
var4.setLowerBound ( 0 );
TS_ASSERT ( var4.lowerBound () == 0.0 );
TS_ASSERT ( var4.upperBound () == 5.0 );
var4 = std::move ( var5 );
TS_ASSERT ( var4.lowerBound () == -10.0 );
TS_ASSERT ( var4.upperBound () == 10.0 );
}
void test_methods () {
gum::ContinuousVariable<> var1("x1", "" );
TS_ASSERT ( var1.upperBound () ==
std::numeric_limits<float>::infinity () );
TS_ASSERT ( var1.lowerBound () ==
-std::numeric_limits<float>::infinity () );
gum::ContinuousVariable<> var2("x2", "xxx", -10, 10 );
TS_ASSERT ( var2.lowerBound () == -10.0f );
TS_ASSERT ( var2.upperBound () == 10.0f );
TS_ASSERT ( var1["44"] == 44.0f );
TS_ASSERT ( var2["4"] == 4.0f );
TS_ASSERT_THROWS(var2["44"], gum::OutOfBounds );
TS_ASSERT_THROWS(var2["4xx"], gum::TypeError );
TS_ASSERT ( var2[" \t\t4\t "] == 4.0f );
TS_ASSERT_THROWS(var2.setLowerBound ( 44.0f ), gum::OutOfBounds );
var2.setLowerBound ( 4 );
TS_ASSERT ( var2.lowerBound () == 4.0f );
TS_ASSERT ( var2.upperBound () == 10.0f );
TS_ASSERT_THROWS(var2.setUpperBound ( 2.0f ), gum::OutOfBounds );
var2.setUpperBound ( 8.5f );
TS_ASSERT ( var2.lowerBound () == 4.0f );
TS_ASSERT ( var2.upperBound () == 8.5f );
TS_ASSERT ( var2.varType () == gum::VarType::Continuous );
TS_ASSERT ( std::stof ( var2.label ( 4.5 ) ) == 4.5f );
TS_ASSERT_THROWS(var2.label ( 10.0f ), gum::OutOfBounds );
TS_ASSERT ( var2.belongs ( 5.6 ) );
TS_ASSERT ( ! var2.belongs ( 15.6 ) );
auto domain = var2.domain ();
std::string regexp = "\\[([0-9.\\-]+);([0-9.\\-]+)\\]";
std::regex reg ( regexp );
std::smatch match;
TS_ASSERT ( std::regex_match ( domain, match, reg ) );
TS_ASSERT ( std::stof ( match[1] ) == 4.0f );
TS_ASSERT ( std::stof ( match[2] ) == 8.5f );
TS_ASSERT ( var2.toString () == ( "x2" + domain ) );
TS_ASSERT ( var2.toStringWithDescription() == var2.description () + domain );
}
};
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment