Commit 3502a7fc authored by Allison Vacanti's avatar Allison Vacanti Committed by Kitware Robot

Merge topic 'new_delete_to_vector_1'

cdf698dd Replace many scoped new[]/delete[] variables with std::vector.
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Acked-by: Ben Boeckel's avatarBen Boeckel <ben.boeckel@kitware.com>
Merge-request: !6249
parents b3cb2825 cdf698dd
Pipeline #153407 running with stage
......@@ -19,10 +19,10 @@
#include "vtkObjectFactory.h"
#include "vtkStdString.h"
#include <sstream>
#include <algorithm>
#include <cmath>
#include <sstream>
#include <vector>
vtkStandardNewMacro(vtkAxisExtended);
......@@ -274,7 +274,7 @@ double vtkAxisExtended::Legibility(
double lmin, double lmax, double lstep, double scaling, vtkVector<int, 3>& parameters)
{
int numTicks = static_cast<int>((lmax - lmin) / lstep);
double* tickPositions = new double[numTicks];
std::vector<double> tickPositions(numTicks);
int fontSizes[8] = { 8, 9, 10, 12, 14, 18, 20, 24 };
for (int i = 0; i < numTicks; ++i)
{
......@@ -393,7 +393,6 @@ double vtkAxisExtended::Legibility(
parameters[0] = bestFormat;
parameters[1] = bestFontSize;
parameters[2] = bestOrientation;
delete[] tickPositions;
return bestLegScore;
}
......
......@@ -28,6 +28,7 @@
// STD includes
#include <algorithm>
#include <cassert>
#include <vector>
//-----------------------------------------------------------------------------
vtkStandardNewMacro(vtkCompositeTransferFunctionItem);
......@@ -122,8 +123,9 @@ void vtkCompositeTransferFunctionItem::ComputeTexture()
const bool logY = this->GetYAxis()->GetLogScaleActive();
const int dimension = this->GetTextureWidth();
double* values = new double[dimension];
this->OpacityFunction->GetTable(dataBounds[0], dataBounds[1], dimension, values, 1, logX ? 1 : 0);
std::vector<double> values(dimension);
this->OpacityFunction->GetTable(
dataBounds[0], dataBounds[1], dimension, values.data(), 1, logX ? 1 : 0);
unsigned char* ptr = reinterpret_cast<unsigned char*>(this->Texture->GetScalarPointer(0, 0, 0));
// TBD: maybe the shape should be defined somewhere else...
......@@ -160,5 +162,4 @@ void vtkCompositeTransferFunctionItem::ComputeTexture()
ptr += 4;
}
}
delete[] values;
}
......@@ -25,6 +25,7 @@
#include "vtkPoints2D.h"
#include <cassert>
#include <vector>
//-----------------------------------------------------------------------------
vtkStandardNewMacro(vtkPiecewiseFunctionItem);
......@@ -110,12 +111,12 @@ void vtkPiecewiseFunctionItem::ComputeTexture()
}
const int dimension = this->GetTextureWidth();
double* values = new double[dimension];
std::vector<double> values(dimension);
// should depends on the true size on screen
this->Texture->SetExtent(0, dimension - 1, 0, 0, 0, 0);
this->Texture->AllocateScalars(VTK_UNSIGNED_CHAR, 4);
this->PiecewiseFunction->GetTable(bounds[0], bounds[1], dimension, values);
this->PiecewiseFunction->GetTable(bounds[0], bounds[1], dimension, values.data());
unsigned char* ptr = reinterpret_cast<unsigned char*>(this->Texture->GetScalarPointer(0, 0, 0));
if (this->MaskAboveCurve || this->PolyLinePen->GetLineType() != vtkPen::NO_PEN)
{
......@@ -141,5 +142,4 @@ void vtkPiecewiseFunctionItem::ComputeTexture()
ptr += 4;
}
}
delete[] values;
}
......@@ -118,7 +118,7 @@ bool vtkPlotParallelCoordinates::Paint(vtkContext2D* painter)
size_t cols = this->Storage->size();
size_t rows = this->Storage->at(0).size();
vtkVector2f* line = new vtkVector2f[cols];
std::vector<vtkVector2f> line(cols);
// Update the axis positions
vtkChartParallelCoordinates* parent = vtkChartParallelCoordinates::SafeDownCast(this->Parent);
......@@ -186,8 +186,6 @@ bool vtkPlotParallelCoordinates::Paint(vtkContext2D* painter)
}
}
delete[] line;
return true;
}
......
......@@ -16,7 +16,9 @@
#include "vtkObjectFactory.h"
#include "vtkPiecewiseFunction.h"
#include <cassert>
#include <vector>
vtkStandardNewMacro(vtkCardinalSpline);
......@@ -81,9 +83,9 @@ double vtkCardinalSpline::Evaluate(double t)
void vtkCardinalSpline::Compute()
{
double *ts, *xs;
double* work;
std::vector<double> work;
std::vector<double> dependent;
double* coefficients;
double* dependent;
int size;
int i;
......@@ -111,14 +113,14 @@ void vtkCardinalSpline::Compute()
}
// allocate memory for work arrays
work = new double[size];
work.resize(size);
// allocate memory for coefficients
delete[] this->Coefficients;
this->Coefficients = new double[4 * size];
// allocate memory for dependent variables
dependent = new double[size];
dependent.resize(size);
// get start of coefficients for this dependent variable
coefficients = this->Coefficients;
......@@ -127,10 +129,10 @@ void vtkCardinalSpline::Compute()
xs = this->PiecewiseFunction->GetDataPointer() + 1;
for (int j = 0; j < size; j++)
{
*(dependent + j) = *(xs + 2 * j);
dependent[j] = xs[2 * j];
}
this->Fit1D(size, this->Intervals, dependent, work, (double(*)[4])coefficients,
this->Fit1D(size, this->Intervals, dependent.data(), work.data(), (double(*)[4])coefficients,
this->LeftConstraint, this->LeftValue, this->RightConstraint, this->RightValue);
}
......@@ -153,14 +155,14 @@ void vtkCardinalSpline::Compute()
}
// allocate memory for work arrays
work = new double[size];
work.resize(size);
// allocate memory for coefficients
delete[] this->Coefficients;
this->Coefficients = new double[4 * size];
// allocate memory for dependent variables
dependent = new double[size];
dependent.resize(size);
// get start of coefficients for this dependent variable
coefficients = this->Coefficients;
......@@ -169,17 +171,14 @@ void vtkCardinalSpline::Compute()
xs = this->PiecewiseFunction->GetDataPointer() + 1;
for (int j = 0; j < size - 1; j++)
{
*(dependent + j) = *(xs + 2 * j);
dependent[j] = xs[2 * j];
}
dependent[size - 1] = *xs;
dependent[size - 1] = xs[0];
this->FitClosed1D(size, this->Intervals, dependent, work, (double(*)[4])coefficients);
this->FitClosed1D(
size, this->Intervals, dependent.data(), work.data(), (double(*)[4])coefficients);
}
// free the work array and dependent variable storage
delete[] work;
delete[] dependent;
// update compute time
this->ComputeTime = this->GetMTime();
}
......
......@@ -17,6 +17,8 @@
#include "vtkObjectFactory.h"
#include "vtkPiecewiseFunction.h"
#include <vector>
vtkStandardNewMacro(vtkKochanekSpline);
//----------------------------------------------------------------------------
......@@ -89,7 +91,7 @@ void vtkKochanekSpline::Compute()
{
double *ts, *xs;
double* coefficients;
double* dependent;
std::vector<double> dependent;
int size;
int i;
......@@ -118,7 +120,7 @@ void vtkKochanekSpline::Compute()
this->Coefficients = new double[4 * size];
// allocate memory for dependent variables
dependent = new double[size];
dependent.resize(size);
// get start of coefficients for this dependent variable
coefficients = this->Coefficients;
......@@ -127,7 +129,7 @@ void vtkKochanekSpline::Compute()
xs = this->PiecewiseFunction->GetDataPointer() + 1;
for (int j = 0; j < size; j++)
{
*(dependent + j) = *(xs + 2 * j);
dependent[j] = xs[2 * j];
}
}
else // spline is closed, create extra "fictitious" point
......@@ -155,7 +157,7 @@ void vtkKochanekSpline::Compute()
this->Coefficients = new double[4 * size];
// allocate memory for dependent variables
dependent = new double[size];
dependent.resize(size);
// get start of coefficients for this dependent variable
coefficients = this->Coefficients;
......@@ -164,18 +166,15 @@ void vtkKochanekSpline::Compute()
xs = this->PiecewiseFunction->GetDataPointer() + 1;
for (int j = 0; j < size - 1; j++)
{
*(dependent + j) = *(xs + 2 * j);
dependent[j] = xs[2 * j];
}
dependent[size - 1] = *xs;
dependent[size - 1] = xs[0];
}
this->Fit1D(size, this->Intervals, dependent, this->DefaultTension, this->DefaultBias,
this->Fit1D(size, this->Intervals, dependent.data(), this->DefaultTension, this->DefaultBias,
this->DefaultContinuity, (double(*)[4])coefficients, this->LeftConstraint, this->LeftValue,
this->RightConstraint, this->RightValue);
// free the dependent variable storage
delete[] dependent;
// update compute time
this->ComputeTime = this->GetMTime();
}
......
......@@ -56,19 +56,21 @@
#include "vtkQuadraticLinearWedge.h"
#include "vtkTriQuadraticHexahedron.h"
#include <vector>
template <class TCell>
int TestOneInterpolationFunction(double eps = VTK_EPSILON)
{
TCell* cell = TCell::New();
int numPts = cell->GetNumberOfPoints();
double* sf = new double[numPts];
std::vector<double> sf(numPts);
double* coords = cell->GetParametricCoords();
int r = 0;
for (int i = 0; i < numPts; ++i)
{
double* point = coords + 3 * i;
double sum = 0.;
cell->InterpolateFunctions(point, sf); // virtual function
cell->InterpolateFunctions(point, sf.data()); // virtual function
for (int j = 0; j < numPts; j++)
{
sum += sf[j];
......@@ -98,7 +100,7 @@ int TestOneInterpolationFunction(double eps = VTK_EPSILON)
// Let's test unity condition on the center point:
double center[3];
cell->GetParametricCenter(center);
cell->InterpolateFunctions(center, sf); // virtual function
cell->InterpolateFunctions(center, sf.data()); // virtual function
double sum = 0.;
for (int j = 0; j < numPts; j++)
{
......@@ -110,7 +112,6 @@ int TestOneInterpolationFunction(double eps = VTK_EPSILON)
}
cell->Delete();
delete[] sf;
return r;
}
......
......@@ -51,8 +51,8 @@
#endif
#include <cassert>
#include <cmath>
#include <vector>
namespace
{
......@@ -76,14 +76,14 @@ vtkSmartPointer<vtkLagrangeTetra> CreateTetra(int nPoints)
int TestInterpolationFunction(vtkSmartPointer<vtkLagrangeTetra> cell, double eps = VTK_EPSILON)
{
int numPts = cell->GetNumberOfPoints();
double* sf = new double[numPts];
std::vector<double> sf(numPts);
double* coords = cell->GetParametricCoords();
int r = 0;
for (int i = 0; i < numPts; ++i)
{
double* point = coords + 3 * i;
double sum = 0.;
cell->InterpolateFunctions(point, sf); // virtual function
cell->InterpolateFunctions(point, sf.data()); // virtual function
for (int j = 0; j < numPts; j++)
{
sum += sf[j];
......@@ -114,7 +114,7 @@ int TestInterpolationFunction(vtkSmartPointer<vtkLagrangeTetra> cell, double eps
// Let's test unity condition on the center point:
double center[3];
cell->GetParametricCenter(center);
cell->InterpolateFunctions(center, sf); // virtual function
cell->InterpolateFunctions(center, sf.data()); // virtual function
double sum = 0.;
for (int j = 0; j < numPts; j++)
{
......@@ -126,7 +126,6 @@ int TestInterpolationFunction(vtkSmartPointer<vtkLagrangeTetra> cell, double eps
++r;
}
delete[] sf;
return r;
}
......@@ -134,8 +133,8 @@ void InterpolateDerivsNumeric(vtkSmartPointer<vtkLagrangeTetra> cell, double pco
double* derivs, double eps = VTK_EPSILON)
{
vtkIdType nPoints = cell->GetPoints()->GetNumberOfPoints();
double* valp = new double[nPoints];
double* valm = new double[nPoints];
std::vector<double> valm(nPoints);
std::vector<double> valp(nPoints);
double pcoordsp[3], pcoordsm[3];
......@@ -144,10 +143,10 @@ void InterpolateDerivsNumeric(vtkSmartPointer<vtkLagrangeTetra> cell, double pco
pcoordsp[i] = pcoordsm[i] = pcoords[i];
}
pcoordsp[0] += eps;
cell->InterpolateFunctions(pcoordsp, valp);
cell->InterpolateFunctions(pcoordsp, valp.data());
pcoordsm[0] -= eps;
cell->InterpolateFunctions(pcoordsm, valm);
cell->InterpolateFunctions(pcoordsm, valm.data());
for (vtkIdType idx = 0; idx < nPoints; idx++)
{
......@@ -159,10 +158,10 @@ void InterpolateDerivsNumeric(vtkSmartPointer<vtkLagrangeTetra> cell, double pco
pcoordsp[i] = pcoordsm[i] = pcoords[i];
}
pcoordsp[1] += eps;
cell->InterpolateFunctions(pcoordsp, valp);
cell->InterpolateFunctions(pcoordsp, valp.data());
pcoordsm[1] -= eps;
cell->InterpolateFunctions(pcoordsm, valm);
cell->InterpolateFunctions(pcoordsm, valm.data());
for (vtkIdType idx = 0; idx < nPoints; idx++)
{
......@@ -176,35 +175,32 @@ void InterpolateDerivsNumeric(vtkSmartPointer<vtkLagrangeTetra> cell, double pco
pcoordsp[i] = pcoordsm[i] = pcoords[i];
}
pcoordsp[2] += eps;
cell->InterpolateFunctions(pcoordsp, valp);
cell->InterpolateFunctions(pcoordsp, valp.data());
pcoordsm[2] -= eps;
cell->InterpolateFunctions(pcoordsm, valm);
cell->InterpolateFunctions(pcoordsm, valm.data());
for (vtkIdType idx = 0; idx < nPoints; idx++)
{
derivs[2 * nPoints + idx] = (valp[idx] - valm[idx]) / (2. * eps);
}
}
delete[] valp;
delete[] valm;
}
int TestInterpolationDerivs(vtkSmartPointer<vtkLagrangeTetra> cell, double eps = VTK_EPSILON)
{
int numPts = cell->GetNumberOfPoints();
int dim = cell->GetCellDimension();
double* derivs = new double[dim * numPts];
double* derivs_n = new double[dim * numPts];
std::vector<double> derivs(dim * numPts);
std::vector<double> derivs_n(dim * numPts);
double* coords = cell->GetParametricCoords();
int r = 0;
for (int i = 0; i < numPts; ++i)
{
double* point = coords + 3 * i;
double sum = 0.;
cell->InterpolateDerivs(point, derivs);
InterpolateDerivsNumeric(cell, point, derivs_n, 1.e-10);
cell->InterpolateDerivs(point, derivs.data());
InterpolateDerivsNumeric(cell, point, derivs_n.data(), 1.e-10);
for (int j = 0; j < dim * numPts; j++)
{
sum += derivs[j];
......@@ -226,7 +222,7 @@ int TestInterpolationDerivs(vtkSmartPointer<vtkLagrangeTetra> cell, double eps =
// Let's test zero condition on the center point:
double center[3];
cell->GetParametricCenter(center);
cell->InterpolateDerivs(center, derivs);
cell->InterpolateDerivs(center, derivs.data());
double sum = 0.;
for (int j = 0; j < dim * numPts; j++)
{
......@@ -238,8 +234,6 @@ int TestInterpolationDerivs(vtkSmartPointer<vtkLagrangeTetra> cell, double eps =
++r;
}
delete[] derivs;
delete[] derivs_n;
return r;
}
......
......@@ -20,6 +20,8 @@
#include "vtkObjectFactory.h"
#include "vtkPolyData.h"
#include <vector>
vtkStandardNewMacro(vtkCellLinks);
//----------------------------------------------------------------------------
......@@ -131,11 +133,9 @@ void vtkCellLinks::BuildLinks(vtkDataSet* data)
vtkIdType numCells = data->GetNumberOfCells();
int j;
vtkIdType cellId;
vtkIdType* linkLoc;
// fill out lists with number of references to cells
linkLoc = new vtkIdType[numPts];
memset(linkLoc, 0, numPts * sizeof(vtkIdType));
std::vector<vtkIdType> linkLoc(numPts, 0);
// Use fast path if polydata
if (data->GetDataObjectType() == VTK_POLY_DATA)
......@@ -200,8 +200,6 @@ void vtkCellLinks::BuildLinks(vtkDataSet* data)
}
cell->Delete();
} // end else
delete[] linkLoc;
}
//----------------------------------------------------------------------------
......
......@@ -17,24 +17,25 @@
#include "vtkDataArray.h"
#include "vtkObjectFactory.h"
#include <vector>
vtkStandardNewMacro(vtkPointData);
void vtkPointData::NullPoint(vtkIdType ptId)
{
vtkFieldData::Iterator it(this);
vtkDataArray* da;
std::vector<float> tuple(32, 0.f);
for (da = it.Begin(); !it.End(); da = it.Next())
{
if (da)
{
int length = da->GetNumberOfComponents();
float* tuple = new float[length];
for (int j = 0; j < length; j++)
const size_t numComps = static_cast<size_t>(da->GetNumberOfComponents());
if (numComps > tuple.size())
{
tuple[j] = 0;
tuple.resize(numComps, 0.f);
}
da->InsertTuple(ptId, tuple);
delete[] tuple;
da->InsertTuple(ptId, tuple.data());
}
}
}
......
......@@ -30,6 +30,8 @@
#include "vtkSmartPointer.h"
#include "vtkTriangle.h"
#include <vector>
vtkStandardNewMacro(vtkPolygon);
//----------------------------------------------------------------------------
......@@ -465,8 +467,8 @@ void vtkPolygon::InterpolateFunctionsUsingMVC(const double x[3], double* weights
}
// create local array for storing point-to-vertex vectors and distances
double* dist = new double[numPts];
double* uVec = new double[3 * numPts];
std::vector<double> dist(numPts);
std::vector<double> uVec(3 * numPts);
static const double eps = 0.00000001;
for (int i = 0; i < numPts; i++)
{
......@@ -479,14 +481,12 @@ void vtkPolygon::InterpolateFunctionsUsingMVC(const double x[3], double* weights
uVec[3 * i + 2] = pt[2] - x[2];
// distance
dist[i] = vtkMath::Norm(uVec + 3 * i);
dist[i] = vtkMath::Norm(uVec.data() + 3 * i);
// handle special case when the point is really close to a vertex
if (dist[i] < eps)
{
weights[i] = 1.0;
delete[] dist;
delete[] uVec;
return;
}
......@@ -500,7 +500,7 @@ void vtkPolygon::InterpolateFunctionsUsingMVC(const double x[3], double* weights
// To do consider the simplification of
// tan(alpha/2) = (1-cos(alpha))/sin(alpha)
// = (d0*d1 - cross(u0, u1))/(2*dot(u0,u1))
double* tanHalfTheta = new double[numPts];
std::vector<double> tanHalfTheta(numPts);
for (int i = 0; i < numPts; i++)
{
int i1 = i + 1;
......@@ -509,8 +509,8 @@ void vtkPolygon::InterpolateFunctionsUsingMVC(const double x[3], double* weights
i1 = 0;
}
double* u0 = uVec + 3 * i;
double* u1 = uVec + 3 * i1;
double* u0 = uVec.data() + 3 * i;
double* u1 = uVec.data() + 3 * i1;
double l = sqrt(vtkMath::Distance2BetweenPoints(u0, u1));
double theta = 2.0 * asin(l / 2.0);
......@@ -520,9 +520,6 @@ void vtkPolygon::InterpolateFunctionsUsingMVC(const double x[3], double* weights
{
weights[i] = dist[i1] / (dist[i] + dist[i1]);
weights[i1] = 1 - weights[i];
delete[] dist;
delete[] uVec;
delete[] tanHalfTheta;
return;
}
......@@ -541,11 +538,6 @@ void vtkPolygon::InterpolateFunctionsUsingMVC(const double x[3], double* weights
weights[i] = (tanHalfTheta[i] + tanHalfTheta[i1]) / dist[i];
}
// clear memory
delete[] dist;
delete[] uVec;
delete[] tanHalfTheta;
// normalize weight
double sum = 0.0;
for (int i = 0; i < numPts; i++)
......@@ -1042,13 +1034,15 @@ int vtkPolygon::BoundedTriangulate(vtkIdList* outTris, double tolerance)
// For most polygons, there should be fewer than VTK_CELL_SIZE points. In
// the event that we have a huge polygon, dynamically allocate an
// appropriately sized array.
std::vector<double> area_dynamic;
if (numPts - 2 <= VTK_CELL_SIZE)
{
area = &area_static[0];
}
else
{
area = new double[numPts - 2];
area_dynamic.resize(numPts - 2);
area = area_dynamic.data();
}
for (i = 0; i < numPts; i++)
......@@ -1090,12 +1084,6 @@ int vtkPolygon::BoundedTriangulate(vtkIdList* outTris, double tolerance)
outTris->DeepCopy(this->Tris);
// If we dynamically allocated our area array, delete it here.
if (numPts - 2 > VTK_CELL_SIZE)
{
delete[] area;
}
return success;
}
......@@ -1506,13 +1494,13 @@ int vtkPolygon::UnbiasedEarCutTriangulation(int seed)
int vtkPolygon::CellBoundary(int vtkNotUsed(subId), const double pcoords[3], vtkIdList* pts)
{
int i, numPts = this->PointIds->GetNumberOfIds();
double x[3], *weights;
double x[3];
int closestPoint = 0, previousPoint, nextPoint;
double largestWeight = 0.0;
double p0[3], p10[3], l10, p20[3], l20, n[3];
pts->Reset();
weights = new double[numPts];
std::vector<double> weights(numPts);
// determine global coordinates given parametric coordinates
this->ParameterizePolygon(p0, p10, l10, p20, l20, n);
......@@ -1523,7 +1511,7 @@ int vtkPolygon::CellBoundary(int vtkNotUsed(subId), const double pcoords[3], vtk
// find edge with largest and next largest weight values. This will be
// the closest edge.
this->InterpolateFunctions(x, weights);
this->InterpolateFunctions(x, weights.data());
for (i = 0; i < numPts; i++)
{
if (weights[i] > largestWeight)
......@@ -1554,7 +1542,6 @@ int vtkPolygon::CellBoundary(int vtkNotUsed(subId), const double pcoords[3], vtk
{
pts->InsertId(1, this->PointIds->GetId(nextPoint));
}
delete[] weights;
// determine whether point is inside of polygon
if (pcoords[0] >= 0.0 && pcoords[0] <= 1.0 && pcoords[1] >= 0.0 && pcoords[1] <= 1.0 &&
......@@ -1654,7 +1641,6 @@ int vtkPolygon::IntersectWithLine(const double p1[3], const double p2[3], double
double closestPoint[3];
double dist2;
int npts = this->GetNumberOfPoints();
double* weights;
subId = 0;
pcoords[0] = pcoords[1] = pcoords[2] = 0.0;
......@@ -1673,16 +1659,14 @@ int vtkPolygon::IntersectWithLine(const double p1[3], const double p2[3], double
// Evaluate position
//
weights = new double[npts];
if (this->EvaluatePosition(x, closestPoint, subId, pcoords, dist2, weights) >= 0)
std::vector<double> weights(npts);
if (this->EvaluatePosition(x, closestPoint, subId, pcoords, dist2, weights.data()) >= 0)
{
if (dist2 <= tol2)
{
delete[] weights;
return 1;
}
}
delete[] weights;
return 0;
}
......@@ -1768,8 +1752,8 @@ void vtkPolygon::Derivatives(
}
int numVerts = this->PointIds->GetNumberOfIds();
double* weights = new double[numVerts];
double* sample = new double[dim * 3];
std::vector<double> weights(numVerts);
std::vector<double> sample(dim * 3);
// compute positions of three sample points
for (i = 0; i < 3; i++)
......@@ -1782,7 +1766,7 @@ void vtkPolygon::Derivatives(
// for each sample point, sample data values
for (idx = 0, k = 0; k < 3; k++) // loop over three sample points
{
this->InterpolateFunctions(x[k], weights);
this->InterpolateFunctions(x[k], weights.data());
for (j = 0; j < dim; j++, idx++) // over number of derivates requested
{
sample[idx] = 0.0;
......@@ -1814,9 +1798,6 @@ void vtkPolygon::Derivatives(
derivs[3 * j + 1]