11#include "MantidGeometry/DllConfig.h"
14#include <boost/spirit/include/qi.hpp>
40 throw std::runtime_error(
"Less than three rows were processed by MatrixVectorPairBuilder.");
43 std::vector<T> typedMatrixElements;
45 typedMatrixElements.emplace_back(boost::rational_cast<T>((rb).
x()));
46 typedMatrixElements.emplace_back(boost::rational_cast<T>((rb).
y()));
47 typedMatrixElements.emplace_back(boost::rational_cast<T>((rb).
z()));
57 int numerator = boost::fusion::at_c<0>(rationalNumberComponents);
58 boost::optional<int> denominator = boost::fusion::at_c<1>(rationalNumberComponents);
60 if (denominator.is_initialized()) {
61 if (denominator.get() == 0) {
62 throw std::runtime_error(
"Zero denominator is not allowed in MatrixVectorPair-strings.");
99 throw std::runtime_error(
"MatrixVectorPair can not have more than 3 rows.");
152using boost::spirit::qi::grammar;
153using boost::spirit::qi::rule;
177 using boost::spirit::unused_type;
179 namespace qi = boost::spirit::qi;
190 auto positiveSignAction = [&builder](unused_type, unused_type, unused_type) { builder.
setCurrentSignPositive(); };
192 auto negativeSignAction = [&builder](unused_type, unused_type, unused_type) { builder.
setCurrentSignNegative(); };
194 auto currentFactorAction = [&builder](
const ParsedRationalNumber &rationalNumberComponents, unused_type,
197 auto currentDirectionAction = [&builder](
const std::string &s, unused_type, unused_type) {
201 auto addCurrentStateToResultAction = [&builder](unused_type, unused_type, unused_type) {
205 auto advanceRowAction = [&builder](unused_type, unused_type, unused_type) { builder.
advanceRow(); };
208 m_sign = lit(
'+')[positiveSignAction] | lit(
'-')[negativeSignAction];
211 m_rational = (int_ >> -(
'/' >> int_))[currentFactorAction];
214 m_direction = (qi::string(
"x") | qi::string(
"y") | qi::string(
"z"))[currentDirectionAction];
241 namespace qi = boost::spirit::qi;
243 auto strIterator = matrixVectorString.cbegin();
244 auto strEnd = matrixVectorString.cend();
250 qi::phrase_parse(strIterator, strEnd, parser, qi::space);
252 if (std::distance(strIterator, strEnd) > 0) {
253 throw std::runtime_error(
"Additional characters at end of string: '" + std::string(strIterator, strEnd) +
"'.");
255 }
catch (std::runtime_error &builderError) {
std::vector< V3R > m_matrixRows
void setCurrentDirection(const std::string &vector)
Set the direction vector to one of the stored values that correspond to x, y or z.
MatrixVectorPairBuilder()
MatrixVectorPair< T, V3R > getMatrixVectorPair() const
Construct and return the actual matrix/vector pair, the rational matrix components are castd to T.
RationalNumber m_currentFactor
void setCurrentSignNegative()
Make the current sign negative.
void reset()
Completely reset the builder, including stored preliminary results.
void advanceRow()
Advance to the next row of the matrix/vector pair.
void resetState()
Reset the current state, i.e. the state representing the current row.
std::map< std::string, V3R > m_directions
void addCurrentStateToResult()
Adds currently stored state to the parse result.
void setCurrentSignPositive()
Make the current sign positive.
void setCurrentFactor(const ParsedRationalNumber &rationalNumberComponents)
Set the current factor, which is a rational number.
void resetAccumulatedResults()
Reset all accumulated results.
rule< Iterator, boost::spirit::qi::space_type > m_component
rule< Iterator, boost::spirit::qi::space_type > m_rational
MatrixVectorPairParser(MatrixVectorPairBuilder &builder)
rule< Iterator, boost::spirit::qi::space_type > m_sign
rule< Iterator, boost::spirit::qi::space_type > m_direction
rule< Iterator, boost::spirit::qi::space_type > m_parser
rule< Iterator, boost::spirit::qi::space_type > m_componentSeries
Records the filename, the description of failure and the line on which it happened.
boost::rational< int > RationalNumber
V3R :
boost::fusion::vector< int, boost::optional< int > > ParsedRationalNumber
MatrixVectorPair< T, V3R > parseMatrixVectorPair(const std::string &matrixVectorString)
Tries to parse the given string.
Helper class which provides the Collimation Length for SANS instruments.