void read_xml_internal(std::basic_istream<typename Ptree::key_type::value_type> &stream,
                           Ptree &pt,
                           int flags,
                           const std::string &filename)
    {
        typedef typename Ptree::key_type::value_type Ch;

        // Create and load document from stream
        stream.unsetf(std::ios::skipws);

        if (!stream.good())
            throw xml_parser_error("read error", filename, 0);

        std::vector<Ch> buf;
        std::copy(std::istream_iterator<Ch>(stream), std::istream_iterator<Ch>(), std::back_inserter(buf));
        buf.push_back(0); // zero-terminate  

        unsigned int pugi_flags = pugi::parse_w3c;
        if ( flags & no_comments )
            pugi_flags = pugi_flags & ~pugi::parse_comments;

        pugi::xml_parser parser(&buf[0], pugi_flags);
        pugi::xml_node doc = parser.document();

        // Create ptree from nodes
        Ptree local;
        for ( pugi::xml_node child = doc.first_child(); child; child = child.next_sibling())
            read_xml_node( child, local, flags );

        // Swap local and result ptrees
        pt.swap(local);
    }
示例#2
0
    void load(std::basic_istream<char> &stream, xml_node &node)
    {
        stream.unsetf(std::ios::skipws);
        std::vector<char> v(std::istreambuf_iterator<char>(stream.rdbuf()),
                            std::istreambuf_iterator<char>());
        if (!stream.good())
        {
            throw config_error("Could not load map file", 0, filename_);
        }
        v.push_back(0); // zero-terminate
        try
        {
            // Parse using appropriate flags
            const int f_tws = rapidxml::parse_normalize_whitespace
                              | rapidxml::parse_trim_whitespace;
            rapidxml::xml_document<> doc;
            doc.parse<f_tws>(&v.front());

            for (rapidxml::xml_node<char> *child = doc.first_node();
                    child; child = child->next_sibling())
            {
                populate_tree(child, node);
            }
        }
        catch (rapidxml::parse_error &e)
        {
            long line = static_cast<long>(
                            std::count(&v.front(), e.where<char>(), '\n') + 1);
            throw config_error(e.what(), line, filename_);
        }
    }
示例#3
0
文件: io.hpp 项目: osyo-manga/Sprout
	inline std::basic_istream<Elem, Traits>&
	operator>>(std::basic_istream<Elem, Traits>& lhs, sprout::optional<T>& rhs) {
		if (lhs.good()) {
			int d = lhs.get();
			if (d == ' ') {
				T x;
				lhs >> x;
				rhs = x;
			} else {
std::basic_istream< CharT, TraitsT >& operator>> (std::basic_istream< CharT, TraitsT >& strm, point& p)
{
    if (strm.good())
    {
        CharT left_brace = static_cast< CharT >(0), comma = static_cast< CharT >(0), right_brace = static_cast< CharT >(0);
        strm.setf(std::ios_base::skipws);
        strm >> left_brace >> p.m_x >> comma >> p.m_y >> right_brace;
        if (left_brace != '(' || comma != ',' || right_brace != ')')
            strm.setstate(std::ios_base::failbit);
    }
    void read_xml_internal(std::basic_istream<
                               typename Ptree::key_type::value_type> &stream,
                           Ptree &pt,
                           int flags,
                           const std::string &filename)
    {
        typedef typename Ptree::key_type::value_type Ch;
        using namespace detail::pdalboostrapidxml;

        // Load data into vector
        stream.unsetf(std::ios::skipws);
        std::vector<Ch> v(std::istreambuf_iterator<Ch>(stream.rdbuf()),
                          std::istreambuf_iterator<Ch>());
        if (!stream.good())
            BOOST_PROPERTY_TREE_THROW(
                xml_parser_error("read error", filename, 0));
        v.push_back(0); // zero-terminate

        try {
            // Parse using appropriate flags
            const int f_tws = parse_normalize_whitespace
                            | parse_trim_whitespace;
            const int f_c = parse_comment_nodes;
            // Some compilers don't like the bitwise or in the template arg.
            const int f_tws_c = parse_normalize_whitespace
                              | parse_trim_whitespace
                              | parse_comment_nodes;
            xml_document<Ch> doc;
            if (flags & no_comments) {
                if (flags & trim_whitespace)
                    doc.BOOST_NESTED_TEMPLATE parse<f_tws>(&v.front());
                else
                    doc.BOOST_NESTED_TEMPLATE parse<0>(&v.front());
            } else {
                if (flags & trim_whitespace)
                    doc.BOOST_NESTED_TEMPLATE parse<f_tws_c>(&v.front());
                else
                    doc.BOOST_NESTED_TEMPLATE parse<f_c>(&v.front());
            }

            // Create ptree from nodes
            Ptree local;
            for (xml_node<Ch> *child = doc.first_node();
                 child; child = child->next_sibling())
                read_xml_node(child, local, flags);

            // Swap local and result ptrees
            pt.swap(local);
        } catch (parse_error &e) {
            long line = static_cast<long>(
                std::count(&v.front(), e.where<Ch>(), Ch('\n')) + 1);
            BOOST_PROPERTY_TREE_THROW(
                xml_parser_error(e.what(), filename, line));  
        }
    }
示例#6
0
文件: io.hpp 项目: himura/p-stade
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, iter_range<Iterator, Injector> const& rng)
{
    if (!is.good())
        return is;

    io_detail::eat_mn_char(is, io_detail::mn_open);
    io_detail::in(is, boost::begin(rng), boost::end(rng));
    io_detail::eat_mn_char(is, io_detail::mn_close);

    return is;
}
示例#7
0
inline
std::basic_istream<CharType, CharTrait>&
operator>>(std::basic_istream<CharType, CharTrait>& in, optional<T>& v)
{
  if (in.good())
  {
    int d = in.get();
    if (d == ' ')
    {
      T x;
      in >> x;
      v = x;
    }
void CDataSerializer::Read(std::basic_istream<char>& sStream, CData* pData)
{
	if (!sStream.good())
		return;

	if (!pData)
		return;

	char szLine[1024];
	string sLine;

	CData* pCurrentData = pData;
	CData* pLastData = NULL;

	while (sStream.getline(szLine, 1024))
	{
		sLine = string(szLine);

		size_t iComment = sLine.find("//");
		if (iComment != string::npos)
			sLine = sLine.substr(0, iComment);

		sLine = trim(sLine);

		if (sLine.length() == 0)
			continue;

		if (sLine[0] == '{')
		{
			pCurrentData = pLastData;
			continue;
		}

		if (sLine[0] == '}')
		{
			pCurrentData = pCurrentData->GetParent();
			continue;
		}

		vector<string> asTokens;
		explode(sLine, asTokens, ":");

		if (asTokens.size() == 1)
			pLastData = pCurrentData->AddChild(trim(sLine));
		else if (asTokens.size() >= 2)
			pLastData = pCurrentData->AddChild(trim(asTokens[0]), trim(sLine.substr(sLine.find(':')+1)));
	}
}
示例#9
0
		inline SPROUT_NON_CONSTEXPR std::basic_istream<Elem, Traits>&
		operator>>(std::basic_istream<Elem, Traits>& lhs, sprout::math::quaternion<T>& rhs) {
			std::ctype<Elem> const& ct = std::use_facet<std::ctype<Elem> >(lhs.getloc());
			T a = T();
			T b = T();
			T c = T();
			T d = T();
			sprout::complex<T> u = sprout::complex<T>();
			sprout::complex<T> v = sprout::complex<T>();
			Elem ch = Elem();
			char cc;
			lhs >> ch;
			if (!lhs.good()) {
				goto finish;
			}
			cc = ct.narrow(ch, char());
			if (cc == '(') {
				lhs >> ch;
				if (!lhs.good()) {
					goto finish;
				}
				cc = ct.narrow(ch, char());
				if (cc == '(') {
					lhs.putback(ch);
					lhs >> u;
					a = u.real();
					b = u.imag();
					if (!lhs.good()) {
						goto finish;
					}
					lhs >> ch;
					if (!lhs.good()) {
						goto finish;
					}
					cc = ct.narrow(ch, char());
					if (cc == ')') {
						rhs = sprout::math::quaternion<T>(a, b);
					} else if (cc == ',') {
						lhs >> v;
						c = v.real();
						d = v.imag();
						if (!lhs.good()) {
							goto finish;
						}
						lhs >> ch;
						if (!lhs.good()) {
							goto finish;
						}
						cc = ct.narrow(ch, char());
						if (cc == ')') {
							rhs = sprout::math::quaternion<T>(a, b, c, d);
						} else {
							lhs.setstate(std::ios_base::failbit);
						}
					} else {
示例#10
0
inline
std::basic_istream<CharType, CharTrait>&
operator>>(std::basic_istream<CharType, CharTrait>& in, optional<T>& v)
{
  if (in.good())
  {
    int d = in.get();
    if (d == ' ')
    {
      T x;
      in >> x;
#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
      v = boost::move(x);
#else
      v = x;
#endif
    }
示例#11
0
std::basic_istream<CharT,Traits>&
operator>>(std::basic_istream<CharT,Traits>& in, pcg128_t& value)
{
    typename std::basic_istream<CharT,Traits>::sentry s(in);

    if (!s)
         return in;

    constexpr auto BASE = pcg128_t(10ULL);
    pcg128_t current(0ULL);
    bool did_nothing = true;
    bool overflow = false;
    for(;;) {
        CharT wide_ch = in.get();
        if (!in.good())
            break;
        auto ch = in.narrow(wide_ch, '\0');
        if (ch < '0' || ch > '9') {
            in.unget();
            break;
        }
        did_nothing = false;
        pcg128_t digit(uint32_t(ch - '0'));
        pcg128_t timesbase = current*BASE;
        overflow = overflow || timesbase < current;
        current = timesbase + digit;
        overflow = overflow || current < digit;
    }

    if (did_nothing || overflow) {
        in.setstate(std::ios::failbit);
        if (overflow)
            current = ~pcg128_t(0ULL);
    }

    value = current;

    return in;
}
示例#12
0
文件: square.hpp 项目: blooto/blooto
 std::basic_istream<CharT, CharTraits> &
 operator>>(std::basic_istream<CharT, CharTraits> &in, Square &sq)
 {
     if (!in.good())
         return in;
     CharT file_ch;
     if (!in.get(file_ch))
         return in;
     if (file_ch < CharT{'a'} || file_ch > CharT{'h'}) {
         in.setstate(std::basic_istream<CharT, CharTraits>::failbit);
         return in;
     }
     CharT rank_ch;
     if (!in.get(rank_ch))
         return in;
     if (rank_ch < CharT{'1'} || rank_ch > CharT{'8'}) {
         in.setstate(std::basic_istream<CharT, CharTraits>::failbit);
         return in;
     }
     sq = Square((std::uint8_t((rank_ch - CharT{'1'}) & 7) << 3) |
                 (std::uint8_t((file_ch - CharT{'a'}) & 7)));
     return in;
 }
std::basic_istream<CharT, Traits>&
operator>>(std::basic_istream<CharT, Traits>& is, duration<Rep, Period>& d)
{
  //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
    typedef duration_punct<CharT> Facet;
    std::locale loc = is.getloc();
    //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
    if (!std::has_facet<Facet>(loc)) {
      //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
        is.imbue(std::locale(loc, new Facet));
    }
    //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
    loc = is.getloc();
    const Facet& f = std::use_facet<Facet>(loc);
    typedef typename chrono_detail::duration_io_intermediate<Rep>::type intermediate_type;
    intermediate_type r;
    std::ios_base::iostate err = std::ios_base::goodbit;
    // read value into r
    //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
    is >> r;
    //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
    if (is.good())
    {
      //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
        // now determine unit
        typedef std::istreambuf_iterator<CharT, Traits> in_iterator;
        in_iterator i(is);
        in_iterator e;
        //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
        if (i != e && *i == ' ')  // mandatory ' ' after value
        {
          //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
            ++i;
            if (i != e)
            {
              //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
                // unit is num / den (yet to be determined)
                unsigned long long num = 0;
                unsigned long long den = 0;
                if (*i == '[')
                {
                  //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
                    // parse [N/D]s or [N/D]seconds format
                    ++i;
                    CharT x;
                    is >> num >> x >> den;
                    if (!is.good() || (x != '/'))
                    {
                      //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
                        is.setstate(is.failbit);
                        return is;
                    }
                    i = in_iterator(is);
                    if (*i != ']')
                    {
                      //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
                        is.setstate(is.failbit);
                        return is;
                    }
                    ++i;
                    const std::basic_string<CharT> units[] =
                    {
                        f.template singular<ratio<1> >(),
                        f.template plural<ratio<1> >(),
                        f.template short_name<ratio<1> >()
                    };
                    //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
                    const std::basic_string<CharT>* k = chrono_detail::scan_keyword(i, e,
                                  units, units + sizeof(units)/sizeof(units[0]),
                                  //~ std::use_facet<std::ctype<CharT> >(loc),
                                  err);
                    //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
                    is.setstate(err);
                    switch ((k - units) / 3)
                    {
                    case 0:
                      //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
                        break;
                    default:
                        is.setstate(err);
                        //std::cerr << __FILE__ << "[" << __LINE__ << "]"<< std::endl;
                        return is;
                    }
                }
                else
                {
    //! The constructor reads parameters from the stream
    explicit settings(std::basic_istream< char_type >& strm)
    {
        typedef typename string_type::iterator str_iterator;
        std::locale loc = strm.getloc();
        typename sections_t::iterator current_section = m_Sections.end();
        string_type line;
        for (unsigned int line_counter = 1; strm.good(); ++line_counter)
        {
            line.clear();
            std::getline(strm, line);
            boost::algorithm::trim(line, loc);

            // Skipping empty lines and comments
            // NOTE: The comments are only allowed to be the whole line.
            //       Comments beginning in the middle of the line are not supported.
            if (!line.empty() && line[0] != constants::char_comment)
            {
                // Check if the line is a section starter
                if (line[0] == constants::char_section_bracket_left)
                {
                    str_iterator it = std::find(line.begin() + 1, line.end(), constants::char_section_bracket_right);
                    string_type section_name(line.begin() + 1, it);
                    boost::algorithm::trim(section_name, loc);
                    if (it != line.end() && !section_name.empty())
                    {
                        // Creating a new section
                        current_section = m_Sections.insert(std::make_pair(section_name, params_t())).first;
                    }
                    else
                    {
                        // The section starter is broken
                        std::ostringstream descr;
                        descr << "At line " << line_counter << ". The section header is invalid.";
                        boost::log::aux::throw_exception(std::runtime_error(descr.str()));
                    }
                }
                else
                {
                    // Check that we've already started a section
                    if (current_section != m_Sections.end())
                    {
                        // Find the '=' between the parameter name and value
                        str_iterator it = std::find(line.begin(), line.end(), constants::char_equal);
                        string_type param_name(line.begin(), it);
                        boost::algorithm::trim_right(param_name, loc);
                        if (it != line.end() && !param_name.empty())
                        {
                            // Put the parameter value into the map
                            string_type param_value(++it, line.end());
                            boost::algorithm::trim_left(param_value, loc);
                            if (param_value.size() >= 2
                                && param_value[0] == constants::char_quote && *param_value.rbegin() == constants::char_quote)
                            {
                                param_value = param_value.substr(1, param_value.size() - 2);
                            }

                            current_section->second[param_name] = param_value;
                        }
                        else
                        {
                            // The parameter name is not valid
                            std::ostringstream descr;
                            descr << "At line " << line_counter << ". Parameter description is not valid.";
                            boost::log::aux::throw_exception(std::runtime_error(descr.str()));
                        }
                    }
                    else
                    {
                        // The parameter encountered before any section starter
                        std::ostringstream descr;
                        descr << "At line " << line_counter << ". Parameters are only allowed in sections.";
                        boost::log::aux::throw_exception(std::runtime_error(descr.str()));
                    }
                }
            }
        }
    }
void use_byte_order_mark (
	std::basic_istream <codepoint, char_traits <codepoint> > & stream)
{
	std::fpos<utf_mbstate> original_position = stream.tellg ();
	if (!stream.good())
	{
		imbue_default (stream);
		return;
	}
	try
	{
		stream.imbue (std::locale (stream.getloc(), new trivial_codecvt));

		/*
		We now start looking for a byte order mark.
		The following must be recognised:
		00 00 FE FF:	UTF-32BE
		FF FE 00 00:	UTF-32LE
		FE FF:			UTF-16BE
		FF FE:			UTF-16LE
		EF BB BF:		UTF-8
		*/

		codepoint byte = stream.rdbuf()->sbumpc();

		switch (byte)
		{
		case 0x00:
			if (stream.rdbuf()->sbumpc() == 0x00 &&
				stream.rdbuf()->sbumpc() == 0xfe &&
				stream.rdbuf()->sbumpc() == 0xff)
			{
				imbue_and_eat_bom (stream, original_position,
					new utf32be_codecvt);
				return;
			}
			break;
			
		case 0xef:
			if (stream.rdbuf()->sbumpc() == 0xbb &&
				stream.rdbuf()->sbumpc() == 0xbf)
			{
				imbue_and_eat_bom (stream, original_position,
					new utf8_codecvt);
				return;
			}
			break;

		case 0xfe:
			if (stream.rdbuf()->sbumpc() == 0xff)
			{
				imbue_and_eat_bom (stream, original_position,
					new utf16be_codecvt);
				return;
			}
			break;

		case 0xff:
			if (stream.rdbuf()->sbumpc() == 0xfe)
			{
				// This is either UTF-16LE or UTF-32LE.
				if (stream.rdbuf()->sbumpc() == 0x00 &&
					stream.rdbuf()->sbumpc() == 0x00)
				{
					imbue_and_eat_bom (stream, original_position,
						new utf32le_codecvt);
				} else
				{
					imbue_and_eat_bom (stream, original_position,
						new utf16le_codecvt);
				}
				return;
			}
			break;
		}
	}
	// If anything has gone wrong, just return to the original position and
	// state and imbue the default codecvt.
	catch (std::ios_base::failure &)
	{}
	stream.seekg (original_position);
	stream.clear();
	imbue_default (stream);
}
示例#16
0
    void read_ini(std::basic_istream<
                    typename Ptree::key_type::value_type> &stream,
                  Ptree &pt)
    {
        typedef typename Ptree::key_type::value_type Ch;
        typedef std::basic_string<Ch> Str;
        const Ch semicolon = stream.widen(';');
        const Ch hash = stream.widen('#');
        const Ch lbracket = stream.widen('[');
        const Ch rbracket = stream.widen(']');

        Ptree local;
        unsigned long line_no = 0;
        Ptree *section = 0;
        Str line;

        // For all lines
        while (stream.good())
        {

            // Get line from stream
            ++line_no;
            std::getline(stream, line);
            if (!stream.good() && !stream.eof())
                BOOST_PROPERTY_TREE_THROW(ini_parser_error(
                    "read error", "", line_no));

            // If line is non-empty
            line = property_tree::detail::trim(line, stream.getloc());
            if (!line.empty())
            {
                // Comment, section or key?
                if (line[0] == semicolon || line[0] == hash)
                {
                    // Ignore comments
                }
                else if (line[0] == lbracket)
                {
                    // If the previous section was empty, drop it again.
                    if (section && section->empty())
                        local.pop_back();
                    typename Str::size_type end = line.find(rbracket);
                    if (end == Str::npos)
                        BOOST_PROPERTY_TREE_THROW(ini_parser_error(
                            "unmatched '['", "", line_no));
                    Str key = property_tree::detail::trim(
                        line.substr(1, end - 1), stream.getloc());
                    if (local.find(key) != local.not_found())
                        BOOST_PROPERTY_TREE_THROW(ini_parser_error(
                            "duplicate section name", "", line_no));
                    section = &local.push_back(
                        std::make_pair(key, Ptree()))->second;
                }
                else
                {
                    Ptree &container = section ? *section : local;
                    typename Str::size_type eqpos = line.find(Ch('='));
                    if (eqpos == Str::npos)
                        BOOST_PROPERTY_TREE_THROW(ini_parser_error(
                            "'=' character not found in line", "", line_no));
                    if (eqpos == 0)
                        BOOST_PROPERTY_TREE_THROW(ini_parser_error(
                            "key expected", "", line_no));
                    Str key = property_tree::detail::trim(
                        line.substr(0, eqpos), stream.getloc());
                    Str data = property_tree::detail::trim(
                        line.substr(eqpos + 1, Str::npos), stream.getloc());
                    if (container.find(key) != container.not_found())
                        BOOST_PROPERTY_TREE_THROW(ini_parser_error(
                            "duplicate key name", "", line_no));
                    container.push_back(std::make_pair(key, Ptree(data)));
                }
            }
        }
        // If the last section was empty, drop it again.
        if (section && section->empty())
            local.pop_back();

        // Swap local ptree with result ptree
        pt.swap(local);

    }
    void operator()(::std::basic_istream<CharT,CharTraitsT>& is)
    {
        enum parser_states
        {
            skip_state,
            out_analysis_state,
            results_state,
            end_state
        };


        parser_states state(skip_state);
        bool ok(true);
        ::std::size_t num_solver_info(0);
        while (is.good() && state != end_state)
        {
            ::std::string line;
            ::std::getline(is, line);

            ::std::size_t pos(0);

            ::std::cerr << "Read-AMPL>> " << line << " (old state: " << state << ")" <<::std::endl;//XXX
            switch (state)
            {
            case skip_state:
                if (line.find("-- [RESULT] --") != ::std::string::npos)
                {
                    state = out_analysis_state;
                }
                break;
            case out_analysis_state:
                if ((pos = line.find("solve_exitcode=")) != ::std::string::npos)
                {
                    parse_str(line.substr(pos+15), solver_exit_code_);
                    ::std::cerr << "Read-AMPL>> SOLVE EXITCODE: " << solver_exit_code_ << ::std::endl;//XXX

                    if (solver_exit_code_ != 0)
                    {
                        // Problem in calling the solver
                        state = end_state;
                        ok = false;
                    }
                }
                else if ((pos = line.find("solve_result=")) != ::std::string::npos)
                {
                    ::std::string res;
                    parse_str(line.substr(pos+13), res);

                    solver_result_ = solver_result_from_string(res);
                    ::std::cerr << "Read-AMPL>> SOLVE RESULT: " << solver_result_ << ::std::endl;//XXX
                }
                else if ((pos = line.find("solve_result_num=")) != ::std::string::npos)
                {
                    parse_str(line.substr(pos+17), solver_result_code_);
                    ::std::cerr << "Read-AMPL>> SOLVE RESULT NUM: " << solver_result_code_ << ::std::endl;//XXX
                }

                if (ok)
                {

                    if (num_solver_info < 2)
                    {
                        state = out_analysis_state;
                        ++num_solver_info;
                    }
                    else if ((solver_result_ == solved_result && solver_result_code_ >= 0 && solver_result_code_ < 100)
                             ||
                             (solver_result_ == unknown_result && solver_result_code_ == -1))
                    {
                        // Either a solution has been found or the problem has not been solved anymore.
                        // The latter case may happen when initial value gives the best value found by the solver
                        state = results_state;
                    }
                    else
                    {
                        state = end_state;
                        ok = false;
                    }
                }
                break;
            case results_state:
                if (line.find("cost=") != ::std::string::npos)
                {
                    parse_str(line.substr(pos+5), cost_);
                    ::std::cerr << "Read-AMPL>> COST: " << cost_ << ::std::endl;//XXX
                }
                else if (line.find("x=") != ::std::string::npos)
                {
                    parse_str(line.substr(pos+2), x_);
                    ::std::cerr << "Read-AMPL>> X: " << x_ << ::std::endl;//XXX
                }
                else if (line.find("y=") != ::std::string::npos)
                {
                    parse_str(line.substr(pos+2), y_);
                    ::std::cerr << "Read-AMPL>> Y: " << y_ << ::std::endl;//XXX
                }
                else if (line.find("s=") != ::std::string::npos)
                {
                    parse_str(line.substr(pos+2), s_);
                    ::std::cerr << "Read-AMPL>> S: " << s_ << ::std::endl;//XXX
                }
                else if (line.find("-- [/RESULT] --") != ::std::string::npos)
                {
                    state = end_state;
                }
                break;
            case end_state:
                break;
            }
            ::std::cerr << "Read-AMPL>> " << line << " (new state: " << state << ")" <<::std::endl;//XXX
        }
    }
		void operator()(::std::basic_istream<CharT,CharTraitsT>& is)
	{
		enum parser_states
		{
			skip_state,
			out_analysis_state,
			results_state,
			end_state
		};


		parser_states state(skip_state);
		bool ok(true);
		::std::size_t num_solver_info(0);
		while (is.good() && state != end_state)
		{
			::std::string line;
			::std::getline(is, line);

			::std::size_t pos(0);
			bool skip(false);

//::std::cerr << "Read-GAMS>> " << line << " (old state: " << state << ")" <<::std::endl;//XXX
			switch (state)
			{
				case skip_state:
					if (line.find("-- [RESULT] --") != ::std::string::npos)
					{
						state = out_analysis_state;
					}
					break;
				case out_analysis_state:
					if ((pos = line.find("solver_status=")) != ::std::string::npos)
					{
						int status;
						parse_str(line.substr(pos+14), status);
						solver_result_ = static_cast<solver_results>(status);
//::std::cerr << "Read-GAMS>> SOLVER STATUS: " << solver_result_ << ::std::endl;//XXX

						if (solver_result_ != normal_completion_solver_result)
						{
							// Problem in calling the solver
							state = end_state;
							ok = false;
						}
					}
					else if ((pos = line.find("model_status=")) != ::std::string::npos)
					{
						int status;
						parse_str(line.substr(pos+13), status);
						model_result_ = static_cast<model_results>(status);
//::std::cerr << "Read-GAMS>> MODEL STATUS: " << model_result_ << ::std::endl;//XXX
					}
					else
					{
						skip = true;
					}

					if (ok && !skip)
					{
						if (num_solver_info < 1)
						{
							state = out_analysis_state;
							++num_solver_info;
						}
						else if (solver_result_ == normal_completion_solver_result
								 &&
								 (model_result_ == optimal_model_result
								  || model_result_ == locally_optimal_model_result
								  || model_result_ == integer_solution_model_result
								  || model_result_ == solved_unique_model_result
								  || model_result_ == solved_model_result
								  || model_result_ == solved_singular_model_result))
						{
							state = results_state;
						}
						else
						{
							state = end_state;
							ok = false;
						}
					}
					break;
				case results_state:
					if (line.find("cost=") != ::std::string::npos)
					{
						parse_str(line.substr(pos+5), cost_);
//::std::cerr << "Read-GAMS>> COST: " << cost_ << ::std::endl;//XXX
					}
					else if (line.find("x=") != ::std::string::npos)
					{
						parse_str(line.substr(pos+2), x_);
//::std::cerr << "Read-GAMS>> X: " << x_ << ::std::endl;//XXX
					}
					else if (line.find("y=") != ::std::string::npos)
					{
						parse_str(line.substr(pos+2), y_);
//::std::cerr << "Read-GAMS>> Y: " << y_ << ::std::endl;//XXX
					}
					else if (line.find("s=") != ::std::string::npos)
					{
						parse_str(line.substr(pos+2), s_);
//::std::cerr << "Read-GAMS>> S: " << s_ << ::std::endl;//XXX
					}
					else if (line.find("-- [/RESULT] --") != ::std::string::npos)
					{
						state = end_state;
					}
					break;
				case end_state:
					break;
			}
//::std::cerr << "Read-GAMS>> " << line << " (new state: " << state << ")" <<::std::endl;//XXX
		}

//		if (ok && (model_result_ != optimal_model_result || model_result_ != locally_optimal_model_result))
//		{
//			// Do not trust the cost value returned by GAMS
//			cost_ = ...
//		}
	}