11#include "MantidGeometry/DllConfig.h"
14#include <boost/spirit/include/qi.hpp>
39 throw std::runtime_error(
"Less than three rows were processed by MatrixVectorPairBuilder.");
42 std::vector<T> typedMatrixElements;
44 typedMatrixElements.emplace_back(boost::rational_cast<T>((rb).
x()));
45 typedMatrixElements.emplace_back(boost::rational_cast<T>((rb).
y()));
46 typedMatrixElements.emplace_back(boost::rational_cast<T>((rb).
z()));
56 int numerator = boost::fusion::at_c<0>(rationalNumberComponents);
57 boost::optional<int> denominator = boost::fusion::at_c<1>(rationalNumberComponents);
59 if (denominator.is_initialized()) {
60 if (denominator.get() == 0) {
61 throw std::runtime_error(
"Zero denominator is not allowed in MatrixVectorPair-strings.");
98 throw std::runtime_error(
"MatrixVectorPair can not have more than 3 rows.");
151using boost::spirit::qi::grammar;
152using boost::spirit::qi::rule;
176 using boost::spirit::unused_type;
178 namespace qi = boost::spirit::qi;
189 auto positiveSignAction = [&builder](unused_type, unused_type, unused_type) { builder.
setCurrentSignPositive(); };
191 auto negativeSignAction = [&builder](unused_type, unused_type, unused_type) { builder.
setCurrentSignNegative(); };
193 auto currentFactorAction = [&builder](
const ParsedRationalNumber &rationalNumberComponents, unused_type,
196 auto currentDirectionAction = [&builder](
const std::string &s, unused_type, unused_type) {
200 auto addCurrentStateToResultAction = [&builder](unused_type, unused_type, unused_type) {
204 auto advanceRowAction = [&builder](unused_type, unused_type, unused_type) { builder.
advanceRow(); };
207 m_sign = lit(
'+')[positiveSignAction] | lit(
'-')[negativeSignAction];
210 m_rational = (int_ >> -(
'/' >> int_))[currentFactorAction];
213 m_direction = (qi::string(
"x") | qi::string(
"y") | qi::string(
"z"))[currentDirectionAction];
240 namespace qi = boost::spirit::qi;
242 auto strIterator = matrixVectorString.cbegin();
243 auto strEnd = matrixVectorString.cend();
249 qi::phrase_parse(strIterator, strEnd, parser, qi::space);
251 if (std::distance(strIterator, strEnd) > 0) {
252 throw std::runtime_error(
"Additional characters at end of string: '" + std::string(strIterator, strEnd) +
"'.");
254 }
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.