pelib  2.0.0
include/pelib/AmplInputScalar.hpp
Go to the documentation of this file.
00001 /*
00002  Copyright 2015 Nicolas Melot
00003 
00004  This file is part of Pelib.
00005 
00006  Pelib is free software: you can redistribute it and/or modify
00007  it under the terms of the GNU General Public License as published by
00008  the Free Software Foundation, either version 3 of the License, or
00009  (at your option) any later version.
00010 
00011  Pelib is distributed in the hope that it will be useful,
00012  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014  GNU General Public License for more details.
00015 
00016  You should have received a copy of the GNU General Public License
00017  along with Pelib. If not, see <http://www.gnu.org/licenses/>.
00018 */
00019 
00020 
00021 #include <pelib/AmplInputData.hpp>
00022 #include <pelib/DataParser.hpp>
00023 #include <pelib/Scalar.hpp>
00024 #include <pelib/CastException.hpp>
00025 #include <pelib/ParseException.hpp>
00026 #include <pelib/NoDecimalFloatException.hpp>
00027 #ifndef PELIB_AMPLINPUTSCALAR
00028 #define PELIB_AMPLINPUTSCALAR
00029 
00030 #define debug(var) std::cout << "[" << __FILE__ << ":" << __FUNCTION__ << ":" << __LINE__ << "] " << #var << " = \"" << (var) << "\"" << std::endl;
00031 
00032 namespace pelib
00033 {
00035         template <class Value>
00036         class
00037         AmplInputScalar: public AmplInputData
00038         {
00039                 public:
00043                         AmplInputScalar(bool strict = true)
00044                         {
00045                                 this->strict = strict;
00046                         }
00047                         
00049                         virtual
00050                         AmplInputScalar*
00051                         clone() const
00052                         {
00053                                 return new AmplInputScalar();
00054                         }
00055                         
00057                         virtual
00058                         AlgebraData*
00059                         parse(std::istream &in)
00060                         {
00061                                 std::string str((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
00062                                 boost::cmatch match;
00063                                 // TODO: Investigate why regex doesn't return correct string when called in AlgebraDataParser
00064                                 if(!boost::regex_match(str.c_str(), match, boost::regex(getDetailedPattern())))
00065                                 {
00066                                         throw ParseException(std::string("String \"").append(str).append("\" doesn't match regex \"").append(getDetailedPattern()).append("\". "));
00067                                 }
00068                                 /*
00069                                 try
00070                                 {
00071                                         match = AlgebraDataParser::match(getDetailedPattern(), str);
00072         } catch(NoDecimalFloatException &e)
00073                                 {
00074                                         std::ostringstream ss;
00075                                         ss << e.getValue();
00076                                         throw ParseException(std::string("Asked a decimal conversion, but \"").append(ss.str()).append("\" is integer."));
00077                                 }
00078                                 */
00079 
00080                                 std::string match1 = match[1];
00081                                 std::string match2 = match[2];
00082                                 Value val = AlgebraDataParser::convert<Value>(match2, strict);
00083                                 Scalar<Value> *scalar = new Scalar<Value>(match1, val);
00084                                 return scalar;
00085                         }
00086 
00091                         virtual
00092                         void
00093                         dump(std::ostream &stream, const AlgebraData *data) const
00094                         {
00095                                 const Scalar<Value> *scalar = dynamic_cast<const Scalar<Value>* >(data);
00096                                 if(scalar == NULL) throw CastException("parameter \"data\" was not of type \"Scalar<Value>\".");
00097 
00098                                 Value val = scalar->getValue();
00099                                 if(scalar->getPrecision() == AlgebraData::higher)
00100                                 {
00101                                         val = AlgebraData::fixPrecision(val, stream.precision());
00102                                 }
00103 
00104                                 stream << "param " << scalar->getName() << " := " << val << ";" << std::endl;
00105                         }
00106 
00108                         virtual
00109                         std::string
00110                         getDetailedPattern()
00111                         {
00112                                 return "param\\s+([^\\s\\n]*)\\s*:=\\s*([^\\s]+)\\s*";
00113                         }
00114 
00116                         virtual
00117                         std::string
00118                         getGlobalPattern()
00119                         {
00120                                 return "param\\s+[^\\s\\n]*\\s*:=.+";
00121                         }
00122         
00123                 protected:
00125                         bool strict;
00126                 private:                
00127         };
00128 }
00129 
00130 #undef debug
00131 #endif