21#include "MantidQtWidgets/Common/QtPropertyBrowser/DoubleDialogEditor.h"
22#include "MantidQtWidgets/Common/QtPropertyBrowser/FilenameDialogEditor.h"
23#include "MantidQtWidgets/Common/QtPropertyBrowser/FormulaDialogEditor.h"
24#include "MantidQtWidgets/Common/QtPropertyBrowser/WorkspaceEditorFactory.h"
28#include "MantidQtWidgets/Common/QtPropertyBrowser/CompositeEditorFactory.h"
29#include "MantidQtWidgets/Common/QtPropertyBrowser/DoubleEditorFactory.h"
30#include "MantidQtWidgets/Common/QtPropertyBrowser/qteditorfactory.h"
31#include "MantidQtWidgets/Common/QtPropertyBrowser/qtpropertymanager.h"
32#include "MantidQtWidgets/Common/QtPropertyBrowser/qttreepropertybrowser.h"
34#include <QApplication>
39#include <QInputDialog>
45#include <QSignalMapper>
50#include <boost/lexical_cast.hpp>
57const char *globalOptionName =
"Global";
59const std::regex PREFIX_REGEX(
"(^[f][0-9](.*))");
60inline bool variableIsPrefixed(std::string
const &
name) {
return std::regex_match(
name, PREFIX_REGEX); }
62std::string insertPrefix(std::string
const ¶m) {
63 auto const parameterName = QString::fromStdString(param);
64 return parameterName.left(parameterName.indexOf(
".") + 1).toStdString() +
"f0." +
65 parameterName.right(parameterName.size() - parameterName.indexOf(
".") - 1).toStdString();
68std::string addPrefix(std::string
const ¶m) {
return "f0." + param; }
70std::string removeEmbeddedPrefix(std::string
const ¶m) {
71 if (variableIsPrefixed(param)) {
72 const auto paramSplit = QString::fromStdString(param).split(
".");
73 return paramSplit[0].toStdString() +
"." + paramSplit[paramSplit.size() - 1].toStdString();
79std::string removePrefix(std::string
const ¶m) {
80 if (variableIsPrefixed(param)) {
81 const auto paramSplit = QString::fromStdString(param).split(
".");
82 return paramSplit[paramSplit.size() - 1].toStdString();
88bool containsOneOf(std::string
const &str, std::string
const &delimiters) {
89 return !str.empty() && str.find_first_of(delimiters) != std::string::npos;
94const std::vector<std::string> REQUIRESRECONSTRUCTIONATTRIBUTES = {
"n",
"Formula",
"Workspace"};
107 :
IFunctionView(parent), m_multiDataset(multi), m_multiDomainFunctionPrefix(),
108 m_allowedCategories(
std::move(categories)), m_selectFunctionDialog(nullptr)
115 QVBoxLayout *layout =
new QVBoxLayout(
this);
116 layout->setContentsMargins(0, 0, 0, 0);
145 options << globalOptionName;
147 m_browser =
new QtTreePropertyBrowser(
this, options);
168 QtSpinBoxFactory *spinBoxFactory =
new QtSpinBoxFactory(
this);
169 DoubleEditorFactory *dblEditorFactory =
new DoubleEditorFactory(
this);
170 ParameterEditorFactory *paramEditorFactory =
new ParameterEditorFactory(
this);
172 QtAbstractEditorFactory<ParameterPropertyManager> *parameterEditorFactory(
nullptr);
175 auto compositeFactory =
new CompositeEditorFactory<ParameterPropertyManager>(
this,
m_doubleEditorFactory);
176 compositeFactory->setSecondaryFactory(globalOptionName, paramEditorFactory);
177 parameterEditorFactory = compositeFactory;
182 parameterEditorFactory = paramEditorFactory;
185 QtLineEditFactory *lineEditFactory =
new QtLineEditFactory(
this);
186 QtCheckBoxFactory *checkBoxFactory =
new QtCheckBoxFactory(
this);
188 FormulaDialogEditorFactory *formulaDialogEditFactory =
new FormulaDialogEditorFactory(
this);
189 WorkspaceEditorFactory *workspaceEditorFactory =
new WorkspaceEditorFactory(
this);
206 m_browser->setContextMenuPolicy(Qt::CustomContextMenu);
207 connect(
m_browser, SIGNAL(customContextMenuRequested(
const QPoint &)),
this, SLOT(
popupMenu(
const QPoint &)));
208 connect(
m_browser, SIGNAL(optionChanged(QtProperty *,
const QString &,
bool)),
this,
228 m_browser->setFocusPolicy(Qt::StrongFocus);
307 ap.
prop = subproperty;
308 if (parent ==
nullptr) {
311 parent->addSubProperty(subproperty);
312 auto items =
m_browser->items(subproperty);
313 if (items.isEmpty()) {
314 throw std::runtime_error(
"Unexpected error in FunctionTreeView [1]");
334 auto children = prop->subProperties();
335 foreach (QtProperty *child, children) {
345 for (
auto it =
m_ties.begin(); it !=
m_ties.end(); ++it) {
346 if (it.value().tieProp == prop) {
355 auto &cp = it.value();
356 if (cp.lower == prop) {
363 }
else if (cp.upper == prop) {
376 ap.
parent->removeSubProperty(prop);
391 if (parent &&
dynamic_cast<QtAbstractPropertyManager *
>(
m_functionManager) != parent->propertyManager()) {
392 throw std::runtime_error(
"Unexpected error in FunctionTreeView [2]");
394 QtProperty *prop =
m_functionManager->addProperty(QString::fromStdString(funName));
406 std::string
const ¶mDesc,
double paramValue) {
408 if (!parent ||
dynamic_cast<QtAbstractPropertyManager *
>(
m_functionManager) != parent->propertyManager()) {
409 throw std::runtime_error(
"Unexpected error in FunctionTreeView [3]");
411 QtProperty *prop =
m_parameterManager->addProperty(QString::fromStdString(parameterName));
419 prop->setOption(globalOptionName,
false);
430 auto children = prop->subProperties();
431 foreach (QtProperty *child, children) {
455 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(parentFun);
457 throw std::logic_error(
"FunctionTreeView: CompositeFunction is expected for addFunction");
460 cf->addFunction(fun);
461 }
catch (
const std::exception &e) {
462 QMessageBox::warning(
this,
"Mantid - Warning", QString(
"Cannot Add function:\n\n%1").arg(e.what()));
483 throw std::runtime_error(
"Unexpected error in FunctionTreeView [4]");
490 QtProperty *prop =
nullptr;
491 if (
m_attName.indexOf(
"FileName") != -1) {
496 }
else if (
m_attName.indexOf(
"Formula") != -1) {
501 }
else if (
m_attName.indexOf(
"Workspace") != -1) {
526 prop->setEnabled(i < std::numeric_limits<int>::max());
551 QString parName =
"value[%1]";
552 for (
size_t i = 0; i < v.size(); ++i) {
559 sizeProp->setEnabled(
false);
581 void apply(std::string &str)
const override {
582 QString attName =
m_prop->propertyName();
583 if (attName ==
"FileName") {
585 }
else if (attName ==
"Formula") {
587 }
else if (attName ==
"Workspace") {
600 void apply(std::vector<double> &v)
const override {
603 throw std::runtime_error(
"FunctionTreeView: empty vector attribute group.");
604 int n = members.size() - 1;
610 for (
int i = 0; i <
n; ++i) {
629 return att.
apply(cap);
644 const std::size_t &parentIndex) {
649 auto attributeNames = fun->getAttributeNames();
650 for (
const auto &att : attributeNames) {
651 if (!variableIsPrefixed(att)) {
656 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(fun);
659 for (
size_t i = 0; i < cf->nFunctions(); ++i) {
664 for (
size_t i = 0; i < fun->nParams(); ++i) {
665 auto name = fun->parameterName(i);
666 auto desc = fun->parameterDescription(i);
667 double value = fun->getParameter(i);
670 if (!fun->isActive(i))
675 if (
const auto constraint = fun->getConstraint(i)) {
694 const std::string ¶meterName,
const std::size_t ¶meterIndex,
696 if (
const auto tie = function->getTie(parameterIndex)) {
699 auto tieAdded =
false;
704 addTieProperty(property, QString::number(function->getParameter(parameterIndex)).toStdString());
719 for (
auto i = 0u; i < composite->nParams(); ++i) {
721 if (fullName == composite->parameterName(i)) {
722 if (
const auto tie = composite->getTie(i)) {
723 const auto tieStr = QString::fromStdString(tie->asString());
724 addTieProperty(property, tieStr.mid(tieStr.indexOf(
'=') + 1).toStdString());
744 const std::size_t &parentIndex) {
748 auto const fullName =
getFullParameterName(parameterName, parentComposite ?
static_cast<int>(parentIndex) : -1);
751 [&fullName](
const auto &globalTie) { return fullName == globalTie.m_parameter; });
764 indexProperty->setEnabled(
false);
788 QString
index =
"fff";
790 ip->setEnabled(
false);
803 if (prop ==
nullptr) {
809 auto children = prop->subProperties();
811 foreach (QtProperty *child, children) {
826 if (props.isEmpty()) {
833 QtProperty *prop = props[0];
842 return prop &&
dynamic_cast<QtAbstractPropertyManager *
>(
m_functionManager) == prop->propertyManager();
851 dynamic_cast<QtAbstractPropertyManager *
>(
m_formulaManager) == prop->propertyManager() ||
852 dynamic_cast<QtAbstractPropertyManager *
>(
m_filenameManager) == prop->propertyManager() ||
853 dynamic_cast<QtAbstractPropertyManager *
>(
m_workspaceManager) == prop->propertyManager());
869 return prop &&
dynamic_cast<QtAbstractPropertyManager *
>(
m_attributeIntManager) == prop->propertyManager();
877 return prop &&
dynamic_cast<QtAbstractPropertyManager *
>(
m_attributeBoolManager) == prop->propertyManager();
902 return prop &&
dynamic_cast<QtAbstractPropertyManager *
>(
m_parameterManager) == prop->propertyManager();
915 return prop &&
dynamic_cast<QtAbstractPropertyManager *
>(
m_indexManager) == prop->propertyManager();
926 auto props = prop->subProperties();
929 const auto it = std::find_if(props.cbegin(), props.cend(), [&](
const auto &prop) { return isIndex(prop); });
930 if (it != props.cend()) {
946 return getIndex(prop) + prop->propertyName().toStdString();
949 return getIndex(prop) + parent->propertyName().toStdString();
958 return getIndex(prop) + prop->propertyName().toStdString();
960 throw std::logic_error(
"QtProperty " + prop->propertyName().toStdString() +
" is not an attribute property.");
971 const auto it = std::find_if(keys.cbegin(), keys.cend(), [&](
const auto &property) {
972 return isFunction(property) && getIndex(property) == index;
974 if (it != keys.cend())
988 throw std::runtime_error(
"FunctionTreeView: null property pointer");
1009 m_ties.insert(funProp, atie);
1019 if (!
isNumber(tie) && !containsOneOf(tie,
"="))
1035 if (compositeIndex != -1)
1037 fullParameterName += parameter;
1038 return fullParameterName;
1048 const auto children = prop->subProperties();
1049 return std::any_of(children.cbegin(), children.cend(),
1050 [](
const auto child) { return child->propertyName() ==
"Tie"; });
1058 return prop &&
dynamic_cast<QtAbstractPropertyManager *
>(
m_tieManager) == prop->propertyManager();
1068 if (prop->propertyName() ==
"Tie") {
1071 const auto children = prop->subProperties();
1073 std::find_if(children.cbegin(), children.cend(), [](
const auto child) { return child->propertyName() ==
"Tie"; });
1074 if (it != children.cend()) {
1086 std::string
const &constraint) {
1090 if (parts.first.empty())
1092 auto lowerBound = parts.second.first;
1093 auto upperBound = parts.second.second;
1101 if (!lowerBound.empty()) {
1104 ac.
lower = apLower.prop;
1108 if (!upperBound.empty()) {
1111 ac.
upper = apUpper.prop;
1126 return prop &&
dynamic_cast<QtAbstractPropertyManager *
>(
m_constraintManager) == prop->propertyManager();
1142 const auto props = prop->subProperties();
1143 return std::any_of(props.cbegin(), props.cend(), [&](
const auto &p) {
1144 return dynamic_cast<QtAbstractPropertyManager *>(m_constraintManager) == p->propertyManager() &&
1145 p->propertyName() ==
"LowerBound";
1156 const auto props = prop->subProperties();
1157 return std::any_of(props.cbegin(), props.cend(), [&](
const auto &p) {
1158 return dynamic_cast<QtAbstractPropertyManager *>(m_constraintManager) == p->propertyManager() &&
1159 p->propertyName() ==
"UpperBound";
1165 const double &upperBound)
const {
1167 std::string constraint;
1169 constraint += QString::number(lowerBound).toStdString() +
"<";
1171 constraint += parameterName;
1173 constraint +=
"<" + QString::number(upperBound).toStdString();
1184 QMenu context(
this);
1186 if (!QApplication::clipboard()->text().isEmpty()) {
1189 if (!
m_browser->properties().isEmpty()) {
1192 context.exec(QCursor::pos());
1195 QtProperty *prop = item->property();
1197 QMenu context(
this);
1199 Mantid::API::FunctionFactory::Instance().createFunction(prop->propertyName().toStdString());
1200 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(fun);
1205 if (!QApplication::clipboard()->text().isEmpty()) {
1208 if (!
m_browser->properties().isEmpty()) {
1212 context.exec(QCursor::pos());
1214 QMenu context(
this);
1223 if (!hasLower && !hasUpper) {
1224 QMenu *constraintMenu =
new QMenu(
"Constraints",
this);
1228 context.addMenu(constraintMenu);
1232 context.exec(QCursor::pos());
1234 QMenu context(
this);
1236 context.exec(QCursor::pos());
1246 QtProperty *prop =
nullptr;
1248 prop = item->property();
1256 if (!
top.isEmpty()) {
1274 if (result != QDialog::Accepted) {
1279 if (newFunction.isEmpty())
1283 auto f = Mantid::API::FunctionFactory::Instance().createFunction(newFunction.toStdString());
1291 Mantid::API::FunctionFactory::Instance().createFunction(prop->propertyName().toStdString());
1292 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(fun);
1302 std::transform(globalParameters.begin(), globalParameters.end(), globalParameters.begin(),
1304 cf->addFunction(f0);
1325 std::string attName = prop->propertyName().toStdString();
1331 }
catch (std::exception &expt) {
1332 QMessageBox::critical(
this,
"Mantid - Error",
1333 "Cannot set attribute " + QString::fromStdString(attName) +
" of function " +
1334 prop->propertyName() +
":\n\n" + QString::fromStdString(expt.what()));
1344 if (prop ==
nullptr) {
1346 if (props.isEmpty())
1354 auto fun = Mantid::API::FunctionFactory::Instance().createFunction(prop->propertyName().toStdString());
1355 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(fun);
1357 auto children = prop->subProperties();
1358 foreach (QtProperty *child, children) {
1371 auto children = prop->subProperties();
1372 foreach (QtProperty *child, children) {
1375 }
else if (!attributesOnly &&
isParameter(child)) {
1376 fun->setParameter(child->propertyName().toStdString(),
getParameter(child));
1388 auto from =
m_ties.lowerBound(prop);
1389 auto to =
m_ties.upperBound(prop);
1392 for (
auto it = from; it != to; ++it) {
1393 auto const tie = (it->paramName +
"=" +
m_tieManager->value(it.value().tieProp).toStdString());
1397 failedTies << it.value().tieProp;
1398 g_log.
warning() <<
"Invalid tie has been removed: " << tie << std::endl;
1402 foreach (QtProperty *p, failedTies) {
1411 for (
auto it = from; it != to; ++it) {
1413 const auto &localParam = it.value();
1417 fun->addConstraints(constraint);
1446 auto children = prop->subProperties();
1447 const auto it = std::find_if(children.cbegin(), children.cend(), [&](
auto &child) {
1448 return isParameter(child) && child->propertyName().toStdString() == name;
1450 if (it != children.cend()) {
1481 QString
value = QString::fromStdString(valueAsStdStr);
1485 auto attName = prop->propertyName();
1486 if (attName ==
"FileName") {
1488 }
else if (attName ==
"Formula") {
1490 }
else if (attName ==
"Workspace") {
1544 throw std::runtime_error(
"Unknown function attribute " + attrName);
1552 const auto children = prop->subProperties();
1553 const auto it = std::find_if(children.cbegin(), children.cend(), [&](
const auto &child) {
1554 return isParameter(child) && child->propertyName().toStdString() == name;
1556 if (it != children.cend()) {
1560 std::string message =
"Unknown function parameter " + parameterName +
1561 "\n\n This may happen if there is a CompositeFunction "
1562 "containing only one function.";
1563 throw std::runtime_error(message);
1568 const QtProperty *prop;
1570 if (!variableIsPrefixed(attributeName)) {
1577 const auto children = prop->subProperties();
1578 const auto it = std::find_if(children.cbegin(), children.cend(), [&](
const auto &child) {
1579 return isAttribute(child) && child->propertyName().toStdString() == name;
1581 if (it != children.cend()) {
1584 std::string message =
"Unknown function attribute " + attributeName;
1585 throw std::runtime_error(message);
1592 std::find_if(
m_ties.cbegin(),
m_ties.cend(), [&prop](
const auto &tie) { return tie.tieProp == prop; });
1593 if (itProp !=
m_ties.cend())
1594 return (*itProp).paramProp;
1597 return (constraint.lower == prop || constraint.upper == prop);
1600 return (*itConstr).paramProp;
1601 throw std::logic_error(
"QtProperty " + prop->propertyName().toStdString() +
1602 " is not a child of a property for any function parameter.");
1612 QtProperty *prop = item->property();
1615 auto const functionString =
getFunction(prop)->asString();
1616 auto const functionIndex =
getIndex(prop);
1626 if (!props.isEmpty()) {
1631 auto topProp = props[0];
1632 auto cf = std::dynamic_pointer_cast<Mantid::API::CompositeFunction>(
getFunction(topProp));
1638 if (cf->nFunctions() == 1 && cf->name() ==
"CompositeFunction") {
1641 auto func =
getFunction(props[0]->subProperties()[1]);
1642 std::transform(globalParameters.begin(), globalParameters.end(), globalParameters.begin(),
1664 QtProperty *prop = item->property();
1667 auto tie = QString::number(
getParameter(prop)).toStdString();
1674 const auto children = prop->subProperties();
1675 const auto it = std::find_if(children.cbegin(), children.cend(),
1676 [](
const auto &child) { return child->propertyName() ==
"Tie"; });
1677 if (it != children.cend()) {
1690 QtProperty *prop = item->property();
1707 QtProperty *prop = item->property();
1712 auto tie = QInputDialog::getText(
this,
"Add a tie",
"Tie:", QLineEdit::Normal,
"", &ok).toStdString();
1713 if (ok && !tie.empty()) {
1718 QMessageBox::critical(
this,
"Mantid - Error",
"Syntax errors found in tie: " + QString::fromStdString(tie));
1719 }
catch (std::exception &e) {
1720 QMessageBox::critical(
this,
"Mantid - Error", QString::fromLatin1(
"Errors found in tie: ") + e.what());
1729 auto funStr = QApplication::clipboard()->text().toStdString();
1733 auto fun = Mantid::API::FunctionFactory::Instance().createInitialized(funStr);
1740 QMessageBox::warning(
this,
"Mantid - Warning",
1741 "Text in the clipboard isn't a function definition"
1742 " or contains errors.");
1758 QtProperty *prop = item->property();
1761 std::string functionIndex,
name;
1776 QtProperty *prop = item->property();
1780 std::string functionIndex,
name;
1782 auto const constraint =
1783 QString::number(val * 0.9).toStdString() +
"<" +
name +
"<" + QString::number(val * 1.1).toStdString();
1795 QtProperty *prop = item->property();
1799 std::string functionIndex,
name;
1801 auto const constraint =
1802 QString::number(val * 0.5).toStdString() +
"<" +
name +
"<" + QString::number(val * 1.5).toStdString();
1808 auto props = prop->subProperties();
1809 foreach (QtProperty *p, props) {
1823 QtProperty *prop = item->property();
1837 QtProperty *prop = item->property();
1844 std::string functionIndex, constraint;
1846 if (!constraint.empty()) {
1857 QtProperty *prop = item->property();
1873 for (
auto const *p : prop->subProperties()) {
1874 if (p->propertyName() ==
"LowerBound")
1876 if (p->propertyName() ==
"UpperBound")
1880 std::string functionIndex,
name;
1884 return std::make_pair(
"",
"");
1898 if (std::find(REQUIRESRECONSTRUCTIONATTRIBUTES.begin(), REQUIRESRECONSTRUCTIONATTRIBUTES.end(),
1899 removePrefix(attributeName)) != REQUIRESRECONSTRUCTIONATTRIBUTES.end()) {
1917 }
catch (std::exception &expt) {
1918 QMessageBox::critical(
this,
"Mantid - Error", QString::fromStdString(expt.what()));
1928 throw std::logic_error(
"FunctionTreeView: inconsistency in vector "
1929 "properties.\nAttribute property not found.");
1932 throw std::logic_error(
"FunctionTreeView: inconsistency in vector "
1933 "properties.\nFunction property not found.");
1936 throw std::logic_error(
"FunctionTreeView: inconsistency in vector "
1937 "properties.\nFunction undefined.");
1938 auto attName = vectorProp->propertyName().toStdString();
1939 auto attribute = fun->getAttribute(attName).asVector();
1943 if (attribute.size() !=
static_cast<size_t>(newSize)) {
1947 attribute.resize(newSize);
1949 fun->setAttributeValue(attName, attribute);
1963 throw std::runtime_error(
"FunctionTreeView: inconsistency in vector properties.");
1969 if (tieProp && !tieProp->isEnabled()) {
1971 QString newTie = QString(
"%1=%2").arg(prop->propertyName()).arg(
m_parameterManager->value(prop));
1972 if (!newTie.isEmpty()) {
1984 for (
const auto &atie :
m_ties) {
1985 if (atie.tieProp == prop) {
1994 const bool isLower = constr.lower == prop;
1995 const bool isUpper = constr.upper == prop;
1996 if (isLower || isUpper) {
1998 std::string functionIndex, constraint;
2000 if (!constraint.empty()) {
2069 std::optional<std::string> newIndex;
2071 if (
auto item =
m_browser->currentItem()) {
2072 auto prop = item->property();
2087 m_tieManager->setValue(tieProp, QString::fromStdString(tie));
2091 }
else if (tieProp) {
2105 std::vector<std::string> globals;
2107 if (prop.prop->checkOption(globalOptionName)) {
2109 globals.emplace_back(
name);
2117 auto prop = ap.prop;
2118 if (!prop->hasOption(globalOptionName))
2122 auto const isGlobal = std::any_of(globals.cbegin(), globals.cend(), [&](std::string
const &global) {
2123 return m_multiDomainFunctionPrefix + global == parameterName;
2125 prop->setOption(globalOptionName, isGlobal);
2137 return item->treeWidget()->visualItemRect(item);
2144 }
catch (std::exception &) {
2153 }
catch (std::exception &) {
2161 return item->treeWidget()->itemWidget(item, 1);
2162 }
catch (std::exception &) {
double value
The value of the point.
std::map< DeltaEMode::Type, std::string > index
#define UNUSED_ARG(x)
Function arguments are sometimes unused in certain implmentations but are required for documentation ...
double lower
lower and upper bounds on the multiplier, if known
This class is responsible for creating the correct dialog for an algorithm.
void showFitFunctionHelp(const QString &name=QString())
A composite function is a function containing other functions.
Specialised exception for parsing errors.
Attribute is a non-fitting parameter.
T apply(AttributeVisitor< T > &v)
Apply an attribute visitor.
Const version of AttributeVisitor.
This is an interface to a fitting function - a semi-abstarct class.
virtual Attribute getAttribute(const std::string &name) const
Return a value of attribute attName.
virtual void setAttribute(const std::string &name, const Attribute &)
Set a value to attribute attName.
The Logger class is in charge of the publishing messages from the framework through various channels.
void warning(const std::string &msg)
Logs at warning level.
Kernel::Logger g_log("ExperimentInfo")
static logger object
std::shared_ptr< IFunction > IFunction_sptr
shared pointer to the function base class
std::shared_ptr< CompositeFunction > CompositeFunction_sptr
shared pointer to the composite function base class
constexpr double EMPTY_DBL() noexcept
Returns what we consider an "empty" double within a property.
std::string to_string(const wide_integer< Bits, Signed > &n)