<commit_before>/**
  Copyright(c) 2015 - 2017 Denis Blank <denis.blank at outlook dot com>

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files(the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions :

  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.
**/

#include <exception>
#include <functional>
#include <string>
#include <system_error>

struct continuable_base {
  template <typename T> continuable_base& then(T&&) { return *this; }

  template <typename T> continuable_base& dropped(T&&) { return *this; }

  template <typename T> continuable_base& thrown(T&&) { return *this; }

  template <typename T> continuable_base& failed(T&&) { return *this; }
};

template <typename... T> struct promise {
  void set_value(T...) noexcept {}

  void operator()(T...) && noexcept {}

  void set_exception(std::exception_ptr exception) noexcept {
    // ...
    (void)exception;
  }

  void set_error(std::error_code error) noexcept {
    // ...
    (void)error;
  }

  void cancel() noexcept {}

  bool is_canceled() const noexcept { return false; }
};

template <typename... T> struct promise {
  void set_value(T...) noexcept {}

  void operator()(T...) && noexcept {}

  void set_exception(std::exception_ptr exception) noexcept {
    // ...
    (void)exception;
  }

  void set_error(std::error_code error) noexcept {
    // ...
    (void)error;
  }
};

template <typename... Result> struct accumulator {
  auto accumulate() {
    return [] {};
  }
};

template <typename Accumulator, typename... Initial>
auto make_accumulator(Accumulator&& /*ac*/, Initial&&... /*initial*/) {
  return std::make_tuple(continuable_base{}, accumulator<int>{});
}

continuable_base http_request(std::string) { return {}; }

int main(int, char**) {
  auto accumulator = make_accumulator(std::plus<int>{}, 0);

  http_request("github.com")
      .then([](std::string response) {
        // ...
        (void)response;
      })
      .then(std::get<1>(accumulator).accumulate())
      .thrown([](std::exception_ptr exception) {
        // ...
        (void)exception;
      })
      .failed([](std::error_code code) {
        // ...
        (void)code;
      });

  return 0;
}
<commit_msg>Cleanup<commit_after>/**
  Copyright(c) 2015 - 2017 Denis Blank <denis.blank at outlook dot com>

  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files(the "Software"), to deal
  in the Software without restriction, including without limitation the rights
  to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
  copies of the Software, and to permit persons to whom the Software is
  furnished to do so, subject to the following conditions :

  The above copyright notice and this permission notice shall be included in
  all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  SOFTWARE.
**/

#include <exception>
#include <functional>
#include <string>
#include <system_error>

struct continuable_base {
  template <typename T> continuable_base& then(T&&) { return *this; }

  template <typename T> continuable_base& dropped(T&&) { return *this; }

  template <typename T> continuable_base& thrown(T&&) { return *this; }

  template <typename T> continuable_base& failed(T&&) { return *this; }
};

template <typename... T> struct promise {
  void set_value(T...) noexcept {}

  void operator()(T...) && noexcept {}

  void set_exception(std::exception_ptr exception) noexcept {
    // ...
    (void)exception;
  }

  void set_error(std::error_code error) noexcept {
    // ...
    (void)error;
  }

  void cancel() noexcept {}

  bool is_canceled() const noexcept { return false; }
};

template <typename... Result> struct accumulator {
  auto accumulate() {
    return [] {};
  }
};

template <typename Accumulator, typename... Initial>
auto make_accumulator(Accumulator&& /*ac*/, Initial&&... /*initial*/) {
  return std::make_tuple(continuable_base{}, accumulator<int>{});
}

continuable_base http_request(std::string) { return {}; }

int main(int, char**) {
  auto accumulator = make_accumulator(std::plus<int>{}, 0);

  http_request("github.com")
      .then([](std::string response) {
        // ...
        (void)response;
      })
      .then(std::get<1>(accumulator).accumulate())
      .thrown([](std::exception_ptr exception) {
        // ...
        (void)exception;
      })
      .failed([](std::error_code code) {
        // ...
        (void)code;
      });

  return 0;
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkDistanceRepresentation2D.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkDistanceRepresentation2D.h"
#include "vtkPointHandleRepresentation2D.h"
#include "vtkAxisActor2D.h"
#include "vtkPolyDataMapper2D.h"
#include "vtkLineSource.h"
#include "vtkProperty2D.h"
#include "vtkCoordinate.h"
#include "vtkRenderer.h"
#include "vtkObjectFactory.h"
#include "vtkBox.h"
#include "vtkInteractorObserver.h"
#include "vtkMath.h"
#include "vtkTextProperty.h"
#include "vtkWindow.h"

vtkCxxRevisionMacro(vtkDistanceRepresentation2D, "1.7");
vtkStandardNewMacro(vtkDistanceRepresentation2D);

//----------------------------------------------------------------------
vtkDistanceRepresentation2D::vtkDistanceRepresentation2D()
{
  // By default, use one of these handles
  this->HandleRepresentation  = vtkPointHandleRepresentation2D::New();

  this->AxisProperty = vtkProperty2D::New();
  this->AxisProperty->SetColor(0,1,0);

  this->AxisActor = vtkAxisActor2D::New();
  this->AxisActor->GetPoint1Coordinate()->SetCoordinateSystemToWorld();
  this->AxisActor->GetPoint2Coordinate()->SetCoordinateSystemToWorld();
  this->AxisActor->SetNumberOfLabels(5);
  this->AxisActor->LabelVisibilityOff();
  this->AxisActor->AdjustLabelsOff();
  this->AxisActor->SetProperty(this->AxisProperty);
  this->AxisActor->SetTitle("Distance");
  this->AxisActor->GetTitleTextProperty()->SetBold(1);
  this->AxisActor->GetTitleTextProperty()->SetItalic(1);
  this->AxisActor->GetTitleTextProperty()->SetShadow(1);
  this->AxisActor->GetTitleTextProperty()->SetFontFamilyToArial();

  this->Distance = 0.0;
}

//----------------------------------------------------------------------
vtkDistanceRepresentation2D::~vtkDistanceRepresentation2D()
{
  this->AxisProperty->Delete();
  this->AxisActor->Delete();
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::GetPoint1WorldPosition(double pos[3])
{
  this->Point1Representation->GetWorldPosition(pos);
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::GetPoint2WorldPosition(double pos[3])
{
  this->Point2Representation->GetWorldPosition(pos);
}

//----------------------------------------------------------------------
double* vtkDistanceRepresentation2D::GetPoint1WorldPosition()
{
  return this->Point1Representation->GetWorldPosition();
}

//----------------------------------------------------------------------
double* vtkDistanceRepresentation2D::GetPoint2WorldPosition()
{
  return this->Point2Representation->GetWorldPosition();
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::SetPoint1DisplayPosition(double x[3])
{
  this->Point1Representation->SetDisplayPosition(x);
  double p[3];
  this->Point1Representation->GetWorldPosition(p);
  this->Point1Representation->SetWorldPosition(p);
  this->AxisActor->GetPoint1Coordinate()->SetValue(p);
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::SetPoint2DisplayPosition(double x[3])
{
  this->Point2Representation->SetDisplayPosition(x);
  double p[3];
  this->Point2Representation->GetWorldPosition(p);
  this->Point2Representation->SetWorldPosition(p);
  this->AxisActor->GetPoint2Coordinate()->SetValue(p);
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::SetPoint1WorldPosition(double x[3])
{
  this->Point1Representation->SetWorldPosition(x);
  this->AxisActor->GetPoint1Coordinate()->SetValue(x);
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::SetPoint2WorldPosition(double x[3])
{
  this->Point2Representation->SetWorldPosition(x);
  this->AxisActor->GetPoint2Coordinate()->SetValue(x);
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::GetPoint1DisplayPosition(double pos[3])
{
  this->Point1Representation->GetDisplayPosition(pos);
  pos[2] = 0.0;
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::GetPoint2DisplayPosition(double pos[3])
{
  this->Point2Representation->GetDisplayPosition(pos);
  pos[2] = 0.0;
}

//----------------------------------------------------------------------
vtkAxisActor2D *vtkDistanceRepresentation2D::GetAxis()
{
  return this->AxisActor;
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::BuildRepresentation()
{
  if ( this->GetMTime() > this->BuildTime ||
       this->Point1Representation->GetMTime() > this->BuildTime ||
       this->Point2Representation->GetMTime() > this->BuildTime ||
       (this->Renderer && this->Renderer->GetVTKWindow() &&
        this->Renderer->GetVTKWindow()->GetMTime() > this->BuildTime) )
    {
    this->Superclass::BuildRepresentation();

    // Okay, compute the distance and set the label
    double p1[3], p2[3];
    this->Point1Representation->GetWorldPosition(p1);
    this->Point2Representation->GetWorldPosition(p2);
    this->Distance = sqrt(vtkMath::Distance2BetweenPoints(p1,p2));
    char string[512];
    sprintf(string, this->LabelFormat, this->Distance);
    this->AxisActor->SetTitle(string);

    this->BuildTime.Modified();
    }
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::ReleaseGraphicsResources(vtkWindow *w)
{
  this->AxisActor->ReleaseGraphicsResources(w);
}

//----------------------------------------------------------------------
int vtkDistanceRepresentation2D::RenderOverlay(vtkViewport *v)
{
  this->BuildRepresentation();

  if ( this->AxisActor->GetVisibility() )
    {
    return this->AxisActor->RenderOverlay(v);
    }
  else
    {
    return 0;
    }
}

//----------------------------------------------------------------------
int vtkDistanceRepresentation2D::RenderOpaqueGeometry(vtkViewport *v)
{
  this->BuildRepresentation();

  if ( this->AxisActor->GetVisibility() )
    {
    return this->AxisActor->RenderOpaqueGeometry(v);
    }
  else
    {
    return 0;
    }
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::PrintSelf(ostream& os, vtkIndent indent)
{
  //Superclass typedef defined in vtkTypeMacro() found in vtkSetGet.h
  this->Superclass::PrintSelf(os,indent);
}
<commit_msg>BUG: Fixed TestSetGet segfaults.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkDistanceRepresentation2D.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkDistanceRepresentation2D.h"
#include "vtkPointHandleRepresentation2D.h"
#include "vtkAxisActor2D.h"
#include "vtkPolyDataMapper2D.h"
#include "vtkLineSource.h"
#include "vtkProperty2D.h"
#include "vtkCoordinate.h"
#include "vtkRenderer.h"
#include "vtkObjectFactory.h"
#include "vtkBox.h"
#include "vtkInteractorObserver.h"
#include "vtkMath.h"
#include "vtkTextProperty.h"
#include "vtkWindow.h"

vtkCxxRevisionMacro(vtkDistanceRepresentation2D, "1.8");
vtkStandardNewMacro(vtkDistanceRepresentation2D);

//----------------------------------------------------------------------
vtkDistanceRepresentation2D::vtkDistanceRepresentation2D()
{
  // By default, use one of these handles
  this->HandleRepresentation  = vtkPointHandleRepresentation2D::New();

  this->AxisProperty = vtkProperty2D::New();
  this->AxisProperty->SetColor(0,1,0);

  this->AxisActor = vtkAxisActor2D::New();
  this->AxisActor->GetPoint1Coordinate()->SetCoordinateSystemToWorld();
  this->AxisActor->GetPoint2Coordinate()->SetCoordinateSystemToWorld();
  this->AxisActor->SetNumberOfLabels(5);
  this->AxisActor->LabelVisibilityOff();
  this->AxisActor->AdjustLabelsOff();
  this->AxisActor->SetProperty(this->AxisProperty);
  this->AxisActor->SetTitle("Distance");
  this->AxisActor->GetTitleTextProperty()->SetBold(1);
  this->AxisActor->GetTitleTextProperty()->SetItalic(1);
  this->AxisActor->GetTitleTextProperty()->SetShadow(1);
  this->AxisActor->GetTitleTextProperty()->SetFontFamilyToArial();

  this->Distance = 0.0;
}

//----------------------------------------------------------------------
vtkDistanceRepresentation2D::~vtkDistanceRepresentation2D()
{
  this->AxisProperty->Delete();
  this->AxisActor->Delete();
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::GetPoint1WorldPosition(double pos[3])
{
  this->Point1Representation->GetWorldPosition(pos);
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::GetPoint2WorldPosition(double pos[3])
{
  this->Point2Representation->GetWorldPosition(pos);
}

//----------------------------------------------------------------------
double* vtkDistanceRepresentation2D::GetPoint1WorldPosition()
{
  if (!this->Point1Representation)
    {
    static double temp[3]=  {0, 0, 0};
    return temp;
    }
  return this->Point1Representation->GetWorldPosition();
}

//----------------------------------------------------------------------
double* vtkDistanceRepresentation2D::GetPoint2WorldPosition()
{
  if (!this->Point2Representation)
    {
    static double temp[3]=  {0, 0, 0};
    return temp;
    }
  return this->Point2Representation->GetWorldPosition();
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::SetPoint1DisplayPosition(double x[3])
{
  this->Point1Representation->SetDisplayPosition(x);
  double p[3];
  this->Point1Representation->GetWorldPosition(p);
  this->Point1Representation->SetWorldPosition(p);
  this->AxisActor->GetPoint1Coordinate()->SetValue(p);
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::SetPoint2DisplayPosition(double x[3])
{
  this->Point2Representation->SetDisplayPosition(x);
  double p[3];
  this->Point2Representation->GetWorldPosition(p);
  this->Point2Representation->SetWorldPosition(p);
  this->AxisActor->GetPoint2Coordinate()->SetValue(p);
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::SetPoint1WorldPosition(double x[3])
{
  if (this->Point1Representation)
    {
    this->Point1Representation->SetWorldPosition(x);
    this->AxisActor->GetPoint1Coordinate()->SetValue(x);
    }
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::SetPoint2WorldPosition(double x[3])
{
  if (this->Point2Representation)
    {
    this->Point2Representation->SetWorldPosition(x);
    this->AxisActor->GetPoint2Coordinate()->SetValue(x);
    }
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::GetPoint1DisplayPosition(double pos[3])
{
  this->Point1Representation->GetDisplayPosition(pos);
  pos[2] = 0.0;
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::GetPoint2DisplayPosition(double pos[3])
{
  this->Point2Representation->GetDisplayPosition(pos);
  pos[2] = 0.0;
}

//----------------------------------------------------------------------
vtkAxisActor2D *vtkDistanceRepresentation2D::GetAxis()
{
  return this->AxisActor;
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::BuildRepresentation()
{
  if ( this->GetMTime() > this->BuildTime ||
       this->Point1Representation->GetMTime() > this->BuildTime ||
       this->Point2Representation->GetMTime() > this->BuildTime ||
       (this->Renderer && this->Renderer->GetVTKWindow() &&
        this->Renderer->GetVTKWindow()->GetMTime() > this->BuildTime) )
    {
    this->Superclass::BuildRepresentation();

    // Okay, compute the distance and set the label
    double p1[3], p2[3];
    this->Point1Representation->GetWorldPosition(p1);
    this->Point2Representation->GetWorldPosition(p2);
    this->Distance = sqrt(vtkMath::Distance2BetweenPoints(p1,p2));
    char string[512];
    sprintf(string, this->LabelFormat, this->Distance);
    this->AxisActor->SetTitle(string);

    this->BuildTime.Modified();
    }
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::ReleaseGraphicsResources(vtkWindow *w)
{
  this->AxisActor->ReleaseGraphicsResources(w);
}

//----------------------------------------------------------------------
int vtkDistanceRepresentation2D::RenderOverlay(vtkViewport *v)
{
  this->BuildRepresentation();

  if ( this->AxisActor->GetVisibility() )
    {
    return this->AxisActor->RenderOverlay(v);
    }
  else
    {
    return 0;
    }
}

//----------------------------------------------------------------------
int vtkDistanceRepresentation2D::RenderOpaqueGeometry(vtkViewport *v)
{
  this->BuildRepresentation();

  if ( this->AxisActor->GetVisibility() )
    {
    return this->AxisActor->RenderOpaqueGeometry(v);
    }
  else
    {
    return 0;
    }
}

//----------------------------------------------------------------------
void vtkDistanceRepresentation2D::PrintSelf(ostream& os, vtkIndent indent)
{
  //Superclass typedef defined in vtkTypeMacro() found in vtkSetGet.h
  this->Superclass::PrintSelf(os,indent);
}
<|endoftext|>


<commit_before>/* Copyright 2013 - 2015 Yurii Litvinov and CyberTech Labs Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. */

#include <QtCore/qglobal.h>

#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
	#include <QtGui/QApplication>
#else
	#include <QtWidgets/QApplication>
#endif

#include <QtCore/QTimer>
#include <QtCore/QCoreApplication>
#include <QtCore/QEventLoop>
#include <QFileInfo>

#include <trikKernel/configurer.h>
#include <trikKernel/deinitializationHelper.h>
#include <trikKernel/fileUtils.h>
#include <trikKernel/applicationInitHelper.h>
#include <trikKernel/paths.h>
#include <trikControl/brickFactory.h>
#include <trikControl/brickInterface.h>
#include "trikScriptRunner/trikScriptRunner.h"
#include <trikNetwork/mailboxFactory.h>
#include <trikNetwork/mailboxInterface.h>

#include <QsLog.h>

int main(int argc, char *argv[])
{
	QStringList params;
	for (int i = 1; i < argc; ++i) {
		params << QString(argv[i]);
	}

	QScopedPointer<QCoreApplication> app;

	if (params.contains("--no-display") || params.contains("-no-display")) {
		app.reset(new QCoreApplication(argc, argv));
	} else {
		app.reset(new QApplication(argc, argv));
	}

	app->setApplicationName("TrikRun");

	// RAII-style code to ensure that after brick gets destroyed there will be an event loop that cleans it up.
	trikKernel::DeinitializationHelper helper;
	Q_UNUSED(helper);

	trikKernel::ApplicationInitHelper initHelper(*app);

	initHelper.commandLineParser().addPositionalArgument("file", QObject::tr("File with script to execute")
			+ " " + QObject::tr("(optional of -js or -py option is specified)"));

	initHelper.commandLineParser().addOption("js", "js-script"
			, QObject::tr("JavaScript script to be executed directly from command line.") + "\n\t"
							+ QObject::tr("Example:") + " ./trikRun -js \"brick.smile(); script.wait(2000);\"");

	initHelper.commandLineParser().addOption("py", "py-script"
			, QObject::tr("Python script to be executed directly from command line.") + "\n\t"
							+ QObject::tr("Example:") + " ./trikRun -py \""
										  "brick.display().showImage('media/trik_smile_normal.png'); "
										  "script.wait(2000)\"");

	initHelper.commandLineParser().addFlag("no-display", "no-display"
			, QObject::tr("Disable display support. When this flag is active, trikRun can work without QWS or even "
								"physical display"));

	initHelper.commandLineParser().addApplicationDescription(QObject::tr("Runner of JavaScript and Python files."));

	if (!initHelper.parseCommandLine()) {
		return 0;
	}

	initHelper.init();

	QLOG_INFO() << "TrikRun started";

	const auto run = [&](const QString &script, const QString &fileName, trikScriptRunner::ScriptType stype) {
		QScopedPointer<trikControl::BrickInterface> brick(
					trikControl::BrickFactory::create(initHelper.configPath(), trikKernel::Paths::mediaPath())
					);

		trikKernel::Configurer configurer(initHelper.configPath() + "/system-config.xml"
										  , initHelper.configPath() + "/model-config.xml");

		QScopedPointer<trikNetwork::MailboxInterface> mailbox(trikNetwork::MailboxFactory::create(configurer));
		trikScriptRunner::TrikScriptRunner result(*brick, mailbox.data());

		QObject::connect(&result, &trikScriptRunner::TrikScriptRunner::completed, app.data(), [&app](const QString &e){
			if (!e.isEmpty()) {
				QLOG_ERROR() << "Script reported:" << e;
			}
			app->quit();
		});

		QObject::connect(&result, &trikScriptRunner::TrikScriptRunner::sendMessage, app.data(), [&app](const QString &m){
			QTextStream(stdout) << m << "\n";
		});

		if (fileName.isEmpty()) { // from command line
			result.run(script, stype);
		} else { // from file
			result.run(script, fileName);
		}

		return app->exec();
	};

	if (initHelper.commandLineParser().isSet("js")) {
		return run(initHelper.commandLineParser().value("js"), "", trikScriptRunner::ScriptType::JAVASCRIPT);
	} else if (initHelper.commandLineParser().isSet("py")) {
		return run(initHelper.commandLineParser().value("py"), "", trikScriptRunner::ScriptType::PYTHON);
	} else {
		const QStringList positionalArgs = initHelper.commandLineParser().positionalArgs();
		if (positionalArgs.size() == 1) {
			return run(trikKernel::FileUtils::readFromFile(positionalArgs[0]),
					positionalArgs[0], trikScriptRunner::ScriptType::JAVASCRIPT);
		} else {
			initHelper.commandLineParser().showHelp();
			return 1;
		}
	}
}
<commit_msg>Travis 120ch issue<commit_after>/* Copyright 2013 - 2015 Yurii Litvinov and CyberTech Labs Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. */

#include <QtCore/qglobal.h>

#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
	#include <QtGui/QApplication>
#else
	#include <QtWidgets/QApplication>
#endif

#include <QtCore/QTimer>
#include <QtCore/QCoreApplication>
#include <QtCore/QEventLoop>
#include <QFileInfo>

#include <trikKernel/configurer.h>
#include <trikKernel/deinitializationHelper.h>
#include <trikKernel/fileUtils.h>
#include <trikKernel/applicationInitHelper.h>
#include <trikKernel/paths.h>
#include <trikControl/brickFactory.h>
#include <trikControl/brickInterface.h>
#include "trikScriptRunner/trikScriptRunner.h"
#include <trikNetwork/mailboxFactory.h>
#include <trikNetwork/mailboxInterface.h>

#include <QsLog.h>

int main(int argc, char *argv[])
{
	QStringList params;
	for (int i = 1; i < argc; ++i) {
		params << QString(argv[i]);
	}

	QScopedPointer<QCoreApplication> app;

	if (params.contains("--no-display") || params.contains("-no-display")) {
		app.reset(new QCoreApplication(argc, argv));
	} else {
		app.reset(new QApplication(argc, argv));
	}

	app->setApplicationName("TrikRun");

	// RAII-style code to ensure that after brick gets destroyed there will be an event loop that cleans it up.
	trikKernel::DeinitializationHelper helper;
	Q_UNUSED(helper);

	trikKernel::ApplicationInitHelper initHelper(*app);

	initHelper.commandLineParser().addPositionalArgument("file", QObject::tr("File with script to execute")
			+ " " + QObject::tr("(optional of -js or -py option is specified)"));

	initHelper.commandLineParser().addOption("js", "js-script"
			, QObject::tr("JavaScript script to be executed directly from command line.") + "\n\t"
							+ QObject::tr("Example:") + " ./trikRun -js \"brick.smile(); script.wait(2000);\"");

	initHelper.commandLineParser().addOption("py", "py-script"
			, QObject::tr("Python script to be executed directly from command line.") + "\n\t"
							+ QObject::tr("Example:") + " ./trikRun -py \""
										  "brick.display().showImage('media/trik_smile_normal.png'); "
										  "script.wait(2000)\"");

	initHelper.commandLineParser().addFlag("no-display", "no-display"
			, QObject::tr("Disable display support. When this flag is active, trikRun can work without QWS or even "
								"physical display"));

	initHelper.commandLineParser().addApplicationDescription(QObject::tr("Runner of JavaScript and Python files."));

	if (!initHelper.parseCommandLine()) {
		return 0;
	}

	initHelper.init();

	QLOG_INFO() << "TrikRun started";

	const auto run = [&](const QString &script, const QString &fileName, trikScriptRunner::ScriptType stype) {
		QScopedPointer<trikControl::BrickInterface> brick(
					trikControl::BrickFactory::create(initHelper.configPath(), trikKernel::Paths::mediaPath())
					);

		trikKernel::Configurer configurer(initHelper.configPath() + "/system-config.xml"
										  , initHelper.configPath() + "/model-config.xml");

		QScopedPointer<trikNetwork::MailboxInterface> mailbox(trikNetwork::MailboxFactory::create(configurer));
		trikScriptRunner::TrikScriptRunner result(*brick, mailbox.data());

		QObject::connect(&result, &trikScriptRunner::TrikScriptRunner::completed, app.data(), [&app](const QString &e){
			if (!e.isEmpty()) {
				QLOG_ERROR() << "Script reported:" << e;
			}
			app->quit();
		});

		QObject::connect(&result, &trikScriptRunner::TrikScriptRunner::sendMessage, app.data(),
				 [&app](const QString &m){
			QTextStream(stdout) << m << "\n";
		});

		if (fileName.isEmpty()) { // from command line
			result.run(script, stype);
		} else { // from file
			result.run(script, fileName);
		}

		return app->exec();
	};

	if (initHelper.commandLineParser().isSet("js")) {
		return run(initHelper.commandLineParser().value("js"), "", trikScriptRunner::ScriptType::JAVASCRIPT);
	} else if (initHelper.commandLineParser().isSet("py")) {
		return run(initHelper.commandLineParser().value("py"), "", trikScriptRunner::ScriptType::PYTHON);
	} else {
		const QStringList positionalArgs = initHelper.commandLineParser().positionalArgs();
		if (positionalArgs.size() == 1) {
			return run(trikKernel::FileUtils::readFromFile(positionalArgs[0]),
					positionalArgs[0], trikScriptRunner::ScriptType::JAVASCRIPT);
		} else {
			initHelper.commandLineParser().showHelp();
			return 1;
		}
	}
}
<|endoftext|>


<commit_before>#include "kwsysPrivate.h"
#include KWSYS_HEADER(stl/vector)
#include KWSYS_HEADER(ios/sstream)
#include KWSYS_HEADER(ios/iostream)

// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
# include "kwsys_stl_string.hxx.in"
# include "kwsys_stl_vector.h.in"
# include "kwsys_ios_sstream.h.in"
# include "kwsys_ios_iostream.h.in"
#endif

int testIOS(int, char*[])
{
  kwsys_ios::ostringstream ostr;
  ostr << "hello";
  if(ostr.str() != "hello")
    {
    kwsys_ios::cerr << "failed to write hello to ostr" << kwsys_ios::endl;
    return 1;
    }
  kwsys_ios::istringstream istr(" 10 20 str ");
  kwsys_stl::string s;
  int x;
  if(istr >> x)
    {
    if(x != 10)
      {
      kwsys_ios::cerr << "x != 10" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read 10 from istr" << kwsys_ios::endl;
    return 1;
    }
  if(istr >> x)
    {
    if(x != 20)
      {
      kwsys_ios::cerr << "x != 20" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read 20 from istr" << kwsys_ios::endl;
    return 1;
    }
  if(istr >> s)
    {
    if(s != "str")
      {
      kwsys_ios::cerr << "s != \"str\"" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read str from istr" << kwsys_ios::endl;
    return 1;
    }
  if(istr >> s)
    {
    kwsys_ios::cerr << "Able to read past end of stream" << kwsys_ios::endl;
    return 1;
    }
  istr.str("30");
  if(istr >> x)
    {
    if(x != 30)
      {
      kwsys_ios::cerr << "x != 30" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read 30 from istr" << kwsys_ios::endl;
    return 1;
    }

  kwsys_ios::stringstream sstr;
  sstr << "40 str2";
  if(sstr >> x)
    {
    if(x != 40)
      {
      kwsys_ios::cerr << "x != 40" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read 40 from sstr" << kwsys_ios::endl;
    return 1;
    }
  if(sstr >> s)
    {
    if(s != "str2")
      {
      kwsys_ios::cerr << "s != \"str2\"" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read str2 from sstr" << kwsys_ios::endl;
    return 1;
    }

  kwsys_ios::cout << "IOS tests passed" << kwsys_ios::endl;
  return 0;
}
<commit_msg>BUG: Need to clear read failure when string is reset.<commit_after>#include "kwsysPrivate.h"
#include KWSYS_HEADER(stl/vector)
#include KWSYS_HEADER(ios/sstream)
#include KWSYS_HEADER(ios/iostream)

// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
# include "kwsys_stl_string.hxx.in"
# include "kwsys_stl_vector.h.in"
# include "kwsys_ios_sstream.h.in"
# include "kwsys_ios_iostream.h.in"
#endif

int testIOS(int, char*[])
{
  kwsys_ios::ostringstream ostr;
  ostr << "hello";
  if(ostr.str() != "hello")
    {
    kwsys_ios::cerr << "failed to write hello to ostr" << kwsys_ios::endl;
    return 1;
    }
  kwsys_ios::istringstream istr(" 10 20 str ");
  kwsys_stl::string s;
  int x;
  if(istr >> x)
    {
    if(x != 10)
      {
      kwsys_ios::cerr << "x != 10" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read 10 from istr" << kwsys_ios::endl;
    return 1;
    }
  if(istr >> x)
    {
    if(x != 20)
      {
      kwsys_ios::cerr << "x != 20" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read 20 from istr" << kwsys_ios::endl;
    return 1;
    }
  if(istr >> s)
    {
    if(s != "str")
      {
      kwsys_ios::cerr << "s != \"str\"" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read str from istr" << kwsys_ios::endl;
    return 1;
    }
  if(istr >> s)
    {
    kwsys_ios::cerr << "Able to read past end of stream" << kwsys_ios::endl;
    return 1;
    }
  else
    {
    // Clear the failure.
    istr.clear(istr.rdstate() & ~kwsys_ios::ios::eofbit);
    istr.clear(istr.rdstate() & ~kwsys_ios::ios::failbit);
    }
  istr.str("30");
  if(istr >> x)
    {
    if(x != 30)
      {
      kwsys_ios::cerr << "x != 30" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read 30 from istr" << kwsys_ios::endl;
    return 1;
    }

  kwsys_ios::stringstream sstr;
  sstr << "40 str2";
  if(sstr >> x)
    {
    if(x != 40)
      {
      kwsys_ios::cerr << "x != 40" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read 40 from sstr" << kwsys_ios::endl;
    return 1;
    }
  if(sstr >> s)
    {
    if(s != "str2")
      {
      kwsys_ios::cerr << "s != \"str2\"" << kwsys_ios::endl;
      return 1;
      }
    }
  else
    {
    kwsys_ios::cerr << "Failed to read str2 from sstr" << kwsys_ios::endl;
    return 1;
    }

  kwsys_ios::cout << "IOS tests passed" << kwsys_ios::endl;
  return 0;
}
<|endoftext|>


<commit_before>// Macro MUONTracker.C (TO BE COMPILED)
// for testing the C++ reconstruction code
// Output is using aliroot standard output MUON.Tracks.root
// The output is a TClonesArray of AliMUONTracks.
#include <TClonesArray.h>

#include "AliRun.h"
#include "AliMUON.h"
#include "AliMUONData.h"
#include "AliMUONEventReconstructor.h"
#include "AliMUONTrack.h"
#include "AliMUONTrackHit.h"
#include "AliMUONTrackParam.h"

void MUONTracker (Text_t *FileName = "galice.root", Int_t FirstEvent = 0, Int_t LastEvent = 9999)
{
  //
  cout << "MUONTracker" << endl;
  cout << "FirstEvent " << FirstEvent << endl;
  cout << "LastEvent " << LastEvent << endl;
  cout << "FileName ``" << FileName << "''" << endl;

  // Creating Run Loader and openning file containing Hits, Digits and RecPoints
  AliRunLoader * RunLoader = AliRunLoader::Open(FileName,"Event","UPDATE");
  if (RunLoader ==0x0) {
    printf(">>> Error : Error Opening %s file \n",FileName);
    return;
  }
  // Loading AliRun master
  RunLoader->LoadgAlice();
  gAlice = RunLoader->GetAliRun();
  RunLoader->LoadKinematics("READ");

  // Loading MUON subsystem
  AliMUON * MUON = (AliMUON *) gAlice->GetDetector("MUON");
  AliLoader * MUONLoader = RunLoader->GetLoader("MUONLoader");
  MUONLoader->LoadHits("READ");
  MUONLoader->LoadRecPoints("READ");
  AliMUONData * muondata = MUON->GetMUONData();
  muondata->SetLoader(MUONLoader);

  Int_t ievent, nevents;
  nevents = RunLoader->GetNumberOfEvents();

  AliMUONEventReconstructor *Reco = new AliMUONEventReconstructor();

  // The right place for changing AliMUONEventReconstructor parameters
  // with respect to the default ones
  //   Reco->SetMaxSigma2Distance(100.0);
  //   Reco->SetPrintLevel(20);
  Reco->SetPrintLevel(1);
  //   Reco->SetBendingResolution(0.0);
  //   Reco->SetNonBendingResolution(0.0);
  cout << "AliMUONEventReconstructor: actual parameters" << endl;
  Reco->Dump();
  //   gObjectTable->Print();

  if  (LastEvent>nevents) LastEvent=nevents;
  // Loop over events
  for (Int_t event = FirstEvent; event < LastEvent; event++) {
    cout << "Event: " << event << endl;
    RunLoader->GetEvent(event);
    muondata->SetTreeAddress("RC");
    if (MUONLoader->TreeT() == 0x0) MUONLoader->MakeTree("T");
    muondata->MakeBranch("RT");
    muondata->SetTreeAddress("RT");
    Reco->EventReconstruct();
    // Dump current event
    Reco->EventDump();

    // Duplicating rectrack data in muondata for output
    for(Int_t i=0; i<Reco->GetNRecTracks(); i++) {
      AliMUONTrack * track = (AliMUONTrack*) Reco->GetRecTracksPtr()->At(i);
      muondata->AddRecTrack(*track);
    }

    muondata->Fill("RT");
    MUONLoader->WriteTracks("OVERWRITE");
    muondata->ResetRecTracks();
  } // Event loop
  MUONLoader->UnloadRecPoints();
}
<commit_msg>Tracker for newIO. TClonesArray of AliMUONTrack in TreeT in MUON.Tracks.root<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

// Macro MUONTracker.C (TO BE COMPILED)
// for testing the C++ reconstruction code
// Output is using aliroot standard output MUON.Tracks.root
// The output is a TClonesArray of AliMUONTracks.
// Gines MARTINEZ, Subatech, sep 2003

#include <TClonesArray.h>

#include "AliRun.h"
#include "AliMUON.h"
#include "AliMUONData.h"
#include "AliMUONEventReconstructor.h"
#include "AliMUONTrack.h"
#include "AliMUONTrackHit.h"
#include "AliMUONTrackParam.h"

void MUONTracker (Text_t *FileName = "galice.root", Int_t FirstEvent = 0, Int_t LastEvent = 9999)
{
  //
  cout << "MUONTracker" << endl;
  cout << "FirstEvent " << FirstEvent << endl;
  cout << "LastEvent " << LastEvent << endl;
  cout << "FileName ``" << FileName << "''" << endl;

  // Creating Run Loader and openning file containing Hits, Digits and RecPoints
  AliRunLoader * RunLoader = AliRunLoader::Open(FileName,"Event","UPDATE");
  if (RunLoader ==0x0) {
    printf(">>> Error : Error Opening %s file \n",FileName);
    return;
  }
  // Loading AliRun master
  RunLoader->LoadgAlice();
  gAlice = RunLoader->GetAliRun();
  RunLoader->LoadKinematics("READ");

  // Loading MUON subsystem
  AliMUON * MUON = (AliMUON *) gAlice->GetDetector("MUON");
  AliLoader * MUONLoader = RunLoader->GetLoader("MUONLoader");
  MUONLoader->LoadHits("READ");
  MUONLoader->LoadRecPoints("READ");
  AliMUONData * muondata = MUON->GetMUONData();
  muondata->SetLoader(MUONLoader);

  Int_t ievent, nevents;
  nevents = RunLoader->GetNumberOfEvents();

  AliMUONEventReconstructor *Reco = new AliMUONEventReconstructor();

  // The right place for changing AliMUONEventReconstructor parameters
  // with respect to the default ones
  //   Reco->SetMaxSigma2Distance(100.0);
  //   Reco->SetPrintLevel(20);
  Reco->SetPrintLevel(1);
  //   Reco->SetBendingResolution(0.0);
  //   Reco->SetNonBendingResolution(0.0);
  cout << "AliMUONEventReconstructor: actual parameters" << endl;
  Reco->Dump();
  //   gObjectTable->Print();

  if  (LastEvent>nevents) LastEvent=nevents;
  // Loop over events
  for (Int_t event = FirstEvent; event < LastEvent; event++) {
    cout << "Event: " << event << endl;
    RunLoader->GetEvent(event);
    muondata->SetTreeAddress("RC");
    if (MUONLoader->TreeT() == 0x0) MUONLoader->MakeTree("T");
    muondata->MakeBranch("RT");
    muondata->SetTreeAddress("RT");
    Reco->EventReconstruct();
    // Dump current event
    Reco->EventDump();

    // Duplicating rectrack data in muondata for output
    for(Int_t i=0; i<Reco->GetNRecTracks(); i++) {
      AliMUONTrack * track = (AliMUONTrack*) Reco->GetRecTracksPtr()->At(i);
      muondata->AddRecTrack(*track);
    }

    muondata->Fill("RT");
    MUONLoader->WriteTracks("OVERWRITE");
    muondata->ResetRecTracks();
  } // Event loop
  MUONLoader->UnloadHits();
  MUONLoader->UnloadRecPoints();
}
<|endoftext|>


<commit_before>#include "restclient-cpp/restclient.h"
#include "restclient-cpp/connection.h"
#include <gtest/gtest.h>
#include <json/json.h>
#include <string>

class ConnectionTest : public ::testing::Test
{
 protected:

    RestClient::Connection* conn;

    ConnectionTest()
    {
      conn = NULL;
    }

    virtual ~ConnectionTest()
    {
    }

    virtual void SetUp()
    {
      conn = new RestClient::Connection("https://httpbin.org");
      conn->SetTimeout(10);
    }

    virtual void TearDown()
    {
      delete conn;
    }

};

TEST_F(ConnectionTest, TestTimeout)
{
  std::string uri = "/delay/5";
  conn->SetTimeout(2);
  RestClient::Response res = conn->get(uri);
  EXPECT_EQ(28, res.code);
}

TEST_F(ConnectionTest, TestFailForInvalidCA)
{
  // set a non-existing file for the CA file and it should fail to verify the peer
  conn->SetCAInfoFilePath("non-existent file");
  RestClient::Response res = conn->get("/get");

  EXPECT_EQ("Failed to query.", res.body);
  EXPECT_EQ(-1, res.code);
}

TEST_F(ConnectionTest, TestDefaultUserAgent)
{
  RestClient::Response res = conn->get("/get");
  Json::Value root;
  std::istringstream str(res.body);
  str >> root;

  EXPECT_EQ("https://httpbin.org/get", root.get("url", "no url set").asString());
  EXPECT_EQ("restclient-cpp/" RESTCLIENT_VERSION,
      root["headers"].get("User-Agent", "nope/nope").asString());
}

TEST_F(ConnectionTest, TestCustomUserAgent)
{
  conn->SetUserAgent("foobar/1.2.3");
  RestClient::Response res = conn->get("/get");
  Json::Value root;
  std::istringstream str(res.body);
  str >> root;

  EXPECT_EQ("https://httpbin.org/get", root.get("url", "no url set").asString());
  EXPECT_EQ("foobar/1.2.3 restclient-cpp/" RESTCLIENT_VERSION,
      root["headers"].get("User-Agent", "nope/nope").asString());
}

TEST_F(ConnectionTest, TestBasicAuth)
{
  RestClient::Response res = conn->get("/basic-auth/foo/bar");
  EXPECT_EQ(401, res.code);

  conn->SetBasicAuth("foo", "bar");
  res = conn->get("/basic-auth/foo/bar");
  EXPECT_EQ(200, res.code);

  Json::Value root;
  std::istringstream str(res.body);
  str >> root;

  EXPECT_EQ("foo", root.get("user", "no user").asString());
  EXPECT_EQ(true, root.get("authenticated", false).asBool());

}

TEST_F(ConnectionTest, TestSSLCert)
{
  conn->SetCertPath("non-existent file");
  conn->SetKeyPath("non-existent key path");
  conn->SetKeyPassword("imaginary_password");
  conn->SetCertType("invalid cert type");
  RestClient::Response res = conn->get("/get");

  EXPECT_EQ(58, res.code);
}

TEST_F(ConnectionTest, TestSetHeaders)
{
  RestClient::HeaderFields headers;
  headers["Foo"] = "bar";
  headers["Bla"] = "lol";
  conn->SetHeaders(headers);
  RestClient::Response res = conn->get("/headers");
  EXPECT_EQ(200, res.code);

  Json::Value root;
  std::istringstream str(res.body);
  str >> root;
  EXPECT_EQ("bar", root["headers"].get("Foo", "").asString());
  EXPECT_EQ("lol", root["headers"].get("Bla", "").asString());

  // let's replace the headers now
  RestClient::HeaderFields headers_again;
  headers_again["foo"] = "bob";
  conn->SetHeaders(headers_again);
  res = conn->get("/headers");
  EXPECT_EQ(200, res.code);

  std::istringstream str2(res.body);
  str2 >> root;
  EXPECT_EQ("bob", root["headers"].get("Foo", "").asString());
  // this shouldn't be set anymore
  EXPECT_EQ("", root["headers"].get("Bla", "").asString());
}

TEST_F(ConnectionTest, TestGetHeaders)
{
  RestClient::HeaderFields headers;
  headers["Foo"] = "bar";
  headers["Bla"] = "lol";
  conn->SetHeaders(headers);
  RestClient::Response res = conn->get("/headers");
  EXPECT_EQ(200, res.code);

  RestClient::HeaderFields headers_returned = conn->GetHeaders();
  EXPECT_EQ("bar", headers_returned["Foo"]);
  EXPECT_EQ("lol", headers_returned["Bla"]);

}

TEST_F(ConnectionTest, TestGetInfo)
{
  RestClient::HeaderFields headers;
  headers["Foo"] = "bar";
  headers["Bla"] = "lol";
  conn->SetHeaders(headers);
  conn->SetBasicAuth("foo", "bar");
  conn->SetTimeout(2);
  conn->SetUserAgent("foobar/1.2.3");
  conn->get("/get");
  RestClient::Connection::Info info = conn->GetInfo();
  EXPECT_EQ("bar", info.headers["Foo"]);
  EXPECT_EQ("lol", info.headers["Bla"]);
  EXPECT_EQ("foo", info.basicAuth.username);
  EXPECT_EQ("bar", info.basicAuth.password);
  EXPECT_EQ("foobar/1.2.3", info.customUserAgent);
  EXPECT_EQ(2, info.timeout);
  EXPECT_EQ("https://httpbin.org", info.baseUrl);
  EXPECT_NE(0, info.lastRequest.totalTime);
  EXPECT_NE(0, info.lastRequest.connectTime);
  EXPECT_NE(0, info.lastRequest.nameLookupTime);
  EXPECT_NE(0, info.lastRequest.appConnectTime);
  EXPECT_NE(0, info.lastRequest.preTransferTime);
  EXPECT_NE(0, info.lastRequest.startTransferTime);
  EXPECT_EQ(0, info.lastRequest.redirectTime);
  EXPECT_EQ(0, info.lastRequest.redirectCount);
}

TEST_F(ConnectionTest, TestFollowRedirect)
{
  RestClient::Response res = conn->get("/redirect/2");
  EXPECT_EQ(302, res.code);
  conn->FollowRedirects(true);
  res = conn->get("/redirect/2");
  EXPECT_EQ(200, res.code);
}

TEST_F(ConnectionTest, TestGetInfoFromRedirect)
{
  conn->FollowRedirects(true);
  RestClient::Response res = conn->get("/redirect/2");
  EXPECT_EQ(200, res.code);
  RestClient::Connection::Info info = conn->GetInfo();
  EXPECT_NE(0, info.lastRequest.redirectTime);
  EXPECT_NE(0, info.lastRequest.redirectCount);
}

TEST_F(ConnectionTest, TestHeadHeaders)
{
  RestClient::HeaderFields headers;
  headers["Foo"] = "bar";
  headers["Bla"] = "lol";
  conn->SetHeaders(headers);
  RestClient::Response res = conn->head("/headers");
  EXPECT_EQ(200, res.code);
  EXPECT_EQ("", res.body);

  RestClient::HeaderFields headers_returned = conn->GetHeaders();
  EXPECT_EQ("bar", headers_returned["Foo"]);
  EXPECT_EQ("lol", headers_returned["Bla"]);
}

TEST_F(ConnectionTest, TestNoSignal)
{
  conn->SetNoSignal(true);
  RestClient::Response res = conn->get("/get");
  EXPECT_EQ(200, res.code);
}

TEST_F(ConnectionTest, TestProxy)
{
  conn->SetProxy("127.0.0.1:3128");
  RestClient::Response res = conn->get("/get");
  EXPECT_EQ(200, res.code);
}

TEST_F(ConnectionTest, TestProxyAddressPrefixed)
{
  conn->SetProxy("https://127.0.0.1:3128");
  RestClient::Response res = conn->get("/get");
  EXPECT_EQ(200, res.code);
}

TEST_F(ConnectionTest, TestInvalidProxy)
{
  conn->SetProxy("127.0.0.1:666");
  RestClient::Response res = conn->get("/get");
  EXPECT_EQ("Failed to query.", res.body);
  EXPECT_EQ(-1, res.code);
}
<commit_msg>change prefixed address for proxy to HTTP<commit_after>#include "restclient-cpp/restclient.h"
#include "restclient-cpp/connection.h"
#include <gtest/gtest.h>
#include <json/json.h>
#include <string>

class ConnectionTest : public ::testing::Test
{
 protected:

    RestClient::Connection* conn;

    ConnectionTest()
    {
      conn = NULL;
    }

    virtual ~ConnectionTest()
    {
    }

    virtual void SetUp()
    {
      conn = new RestClient::Connection("https://httpbin.org");
      conn->SetTimeout(10);
    }

    virtual void TearDown()
    {
      delete conn;
    }

};

TEST_F(ConnectionTest, TestTimeout)
{
  std::string uri = "/delay/5";
  conn->SetTimeout(2);
  RestClient::Response res = conn->get(uri);
  EXPECT_EQ(28, res.code);
}

TEST_F(ConnectionTest, TestFailForInvalidCA)
{
  // set a non-existing file for the CA file and it should fail to verify the peer
  conn->SetCAInfoFilePath("non-existent file");
  RestClient::Response res = conn->get("/get");

  EXPECT_EQ("Failed to query.", res.body);
  EXPECT_EQ(-1, res.code);
}

TEST_F(ConnectionTest, TestDefaultUserAgent)
{
  RestClient::Response res = conn->get("/get");
  Json::Value root;
  std::istringstream str(res.body);
  str >> root;

  EXPECT_EQ("https://httpbin.org/get", root.get("url", "no url set").asString());
  EXPECT_EQ("restclient-cpp/" RESTCLIENT_VERSION,
      root["headers"].get("User-Agent", "nope/nope").asString());
}

TEST_F(ConnectionTest, TestCustomUserAgent)
{
  conn->SetUserAgent("foobar/1.2.3");
  RestClient::Response res = conn->get("/get");
  Json::Value root;
  std::istringstream str(res.body);
  str >> root;

  EXPECT_EQ("https://httpbin.org/get", root.get("url", "no url set").asString());
  EXPECT_EQ("foobar/1.2.3 restclient-cpp/" RESTCLIENT_VERSION,
      root["headers"].get("User-Agent", "nope/nope").asString());
}

TEST_F(ConnectionTest, TestBasicAuth)
{
  RestClient::Response res = conn->get("/basic-auth/foo/bar");
  EXPECT_EQ(401, res.code);

  conn->SetBasicAuth("foo", "bar");
  res = conn->get("/basic-auth/foo/bar");
  EXPECT_EQ(200, res.code);

  Json::Value root;
  std::istringstream str(res.body);
  str >> root;

  EXPECT_EQ("foo", root.get("user", "no user").asString());
  EXPECT_EQ(true, root.get("authenticated", false).asBool());

}

TEST_F(ConnectionTest, TestSSLCert)
{
  conn->SetCertPath("non-existent file");
  conn->SetKeyPath("non-existent key path");
  conn->SetKeyPassword("imaginary_password");
  conn->SetCertType("invalid cert type");
  RestClient::Response res = conn->get("/get");

  EXPECT_EQ(58, res.code);
}

TEST_F(ConnectionTest, TestSetHeaders)
{
  RestClient::HeaderFields headers;
  headers["Foo"] = "bar";
  headers["Bla"] = "lol";
  conn->SetHeaders(headers);
  RestClient::Response res = conn->get("/headers");
  EXPECT_EQ(200, res.code);

  Json::Value root;
  std::istringstream str(res.body);
  str >> root;
  EXPECT_EQ("bar", root["headers"].get("Foo", "").asString());
  EXPECT_EQ("lol", root["headers"].get("Bla", "").asString());

  // let's replace the headers now
  RestClient::HeaderFields headers_again;
  headers_again["foo"] = "bob";
  conn->SetHeaders(headers_again);
  res = conn->get("/headers");
  EXPECT_EQ(200, res.code);

  std::istringstream str2(res.body);
  str2 >> root;
  EXPECT_EQ("bob", root["headers"].get("Foo", "").asString());
  // this shouldn't be set anymore
  EXPECT_EQ("", root["headers"].get("Bla", "").asString());
}

TEST_F(ConnectionTest, TestGetHeaders)
{
  RestClient::HeaderFields headers;
  headers["Foo"] = "bar";
  headers["Bla"] = "lol";
  conn->SetHeaders(headers);
  RestClient::Response res = conn->get("/headers");
  EXPECT_EQ(200, res.code);

  RestClient::HeaderFields headers_returned = conn->GetHeaders();
  EXPECT_EQ("bar", headers_returned["Foo"]);
  EXPECT_EQ("lol", headers_returned["Bla"]);

}

TEST_F(ConnectionTest, TestGetInfo)
{
  RestClient::HeaderFields headers;
  headers["Foo"] = "bar";
  headers["Bla"] = "lol";
  conn->SetHeaders(headers);
  conn->SetBasicAuth("foo", "bar");
  conn->SetTimeout(2);
  conn->SetUserAgent("foobar/1.2.3");
  conn->get("/get");
  RestClient::Connection::Info info = conn->GetInfo();
  EXPECT_EQ("bar", info.headers["Foo"]);
  EXPECT_EQ("lol", info.headers["Bla"]);
  EXPECT_EQ("foo", info.basicAuth.username);
  EXPECT_EQ("bar", info.basicAuth.password);
  EXPECT_EQ("foobar/1.2.3", info.customUserAgent);
  EXPECT_EQ(2, info.timeout);
  EXPECT_EQ("https://httpbin.org", info.baseUrl);
  EXPECT_NE(0, info.lastRequest.totalTime);
  EXPECT_NE(0, info.lastRequest.connectTime);
  EXPECT_NE(0, info.lastRequest.nameLookupTime);
  EXPECT_NE(0, info.lastRequest.appConnectTime);
  EXPECT_NE(0, info.lastRequest.preTransferTime);
  EXPECT_NE(0, info.lastRequest.startTransferTime);
  EXPECT_EQ(0, info.lastRequest.redirectTime);
  EXPECT_EQ(0, info.lastRequest.redirectCount);
}

TEST_F(ConnectionTest, TestFollowRedirect)
{
  RestClient::Response res = conn->get("/redirect/2");
  EXPECT_EQ(302, res.code);
  conn->FollowRedirects(true);
  res = conn->get("/redirect/2");
  EXPECT_EQ(200, res.code);
}

TEST_F(ConnectionTest, TestGetInfoFromRedirect)
{
  conn->FollowRedirects(true);
  RestClient::Response res = conn->get("/redirect/2");
  EXPECT_EQ(200, res.code);
  RestClient::Connection::Info info = conn->GetInfo();
  EXPECT_NE(0, info.lastRequest.redirectTime);
  EXPECT_NE(0, info.lastRequest.redirectCount);
}

TEST_F(ConnectionTest, TestHeadHeaders)
{
  RestClient::HeaderFields headers;
  headers["Foo"] = "bar";
  headers["Bla"] = "lol";
  conn->SetHeaders(headers);
  RestClient::Response res = conn->head("/headers");
  EXPECT_EQ(200, res.code);
  EXPECT_EQ("", res.body);

  RestClient::HeaderFields headers_returned = conn->GetHeaders();
  EXPECT_EQ("bar", headers_returned["Foo"]);
  EXPECT_EQ("lol", headers_returned["Bla"]);
}

TEST_F(ConnectionTest, TestNoSignal)
{
  conn->SetNoSignal(true);
  RestClient::Response res = conn->get("/get");
  EXPECT_EQ(200, res.code);
}

TEST_F(ConnectionTest, TestProxy)
{
  conn->SetProxy("127.0.0.1:3128");
  RestClient::Response res = conn->get("/get");
  EXPECT_EQ(200, res.code);
}

TEST_F(ConnectionTest, TestProxyAddressPrefixed)
{
  conn->SetProxy("http://127.0.0.1:3128");
  RestClient::Response res = conn->get("/get");
  EXPECT_EQ(200, res.code);
}

TEST_F(ConnectionTest, TestInvalidProxy)
{
  conn->SetProxy("127.0.0.1:666");
  RestClient::Response res = conn->get("/get");
  EXPECT_EQ("Failed to query.", res.body);
  EXPECT_EQ(-1, res.code);
}
<|endoftext|>


<commit_before>//=======================================================================// Copyright Baptiste Wicht 2013-2014.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#ifndef STRING_H
#define STRING_H

#include <types.hpp>
#include <algorithms.hpp>
#include <vector.hpp>
#include <unique_ptr.hpp>

namespace std {

inline uint64_t str_len(const char* a){
    uint64_t length = 0;
    while(*a++){
        ++length;
    }
    return length;
}

template<typename CharT>
struct base_long {
    size_t capacity;
    unique_ptr<CharT[]> data;

    base_long() = default;

    base_long(size_t capacity, CharT* array) : capacity(capacity), data(array) {}

    base_long(base_long&) = delete;
    base_long& operator=(base_long&) = delete;

    base_long(base_long&&) = default;
    base_long& operator=(base_long&&) = default;
};

static constexpr const size_t min_capacity = 16;
static constexpr const size_t words = min_capacity / sizeof(size_t);

template<typename CharT>
struct base_short {
    CharT data[min_capacity];

    base_short() = default;

    base_short(base_short&) = delete;
    base_short& operator=(base_short&) = delete;

    base_short(base_short&&) = default;
    base_short& operator=(base_short&&) = default;
};

struct base_raw {
    size_t data[words];

    base_raw() = delete;

    base_raw(base_raw&) = delete;
    base_raw& operator=(base_raw&) = delete;

    base_raw(base_raw&&) = delete;
    base_raw& operator=(base_raw&&) = delete;
};

template<typename CharT>
union base_storage {
    base_short<CharT> small;
    base_long<CharT> big;
    base_raw raw;

    base_storage(){
        //Default construction: Nothing to do
    }

    ~base_storage() {}
};

static_assert(min_capacity == sizeof(base_short<char>), "base_short must be the correct SSO size");
static_assert(min_capacity == sizeof(base_long<char>), "base_long must be the correct SSO size");
static_assert(min_capacity == sizeof(base_raw), "base_raw must be the correct SSO size");

template<typename CharT>
struct basic_string {
public:
    typedef CharT*             iterator;
    typedef const CharT*       const_iterator;

    static constexpr const size_t npos = -1;

private:
    size_t _size;

    base_storage<CharT> storage;

    void set_long(bool small){
        if(small){
            _size |= (1UL << 63);
        } else {
            _size &= ~(1UL << 63);
        }
    }

    void set_small(bool small){
        set_long(!small);
    }

    void set_size(size_t size){
        if(is_long()){
            _size = size | (1UL << 63);
        } else {
            _size = size;
        }
    }

    bool is_long() const {
        return _size & (1UL << 63);
    }

    bool is_small() const {
        return !is_long();
    }

    void zero(){
        for(size_t i = 0; i < words; ++i){
            storage.raw.data[i] = 0;
        }
    }

public:
    //Constructors

    basic_string() : _size(0){
        set_small(true);

        (*this)[0] = '\0';
    }

    basic_string(const CharT* s) : _size(str_len(s)) {
        auto capacity = size() + 1;

        set_small(capacity <= 16);

        if(!is_small()){
            new (&storage.big) base_long<CharT>(capacity, new CharT[capacity]);
        }

        std::copy_n(begin(), s, capacity);
    }

    explicit basic_string(size_t __capacity) : _size(0) {
        set_small(__capacity <= 16);

        if(!is_small()){
            new (&storage.big) base_long<CharT>(__capacity, new CharT[__capacity]);
        }

        (*this)[0] = '\0';
    }

    //Copy

    basic_string(const basic_string& rhs) : _size(rhs._size) {
        if(!is_small()){
            new (&storage.big) base_long<CharT>(size() + 1, new CharT[size() + 1]);
        }

        std::copy_n(begin(), rhs.begin(), size() + 1);
    }

    basic_string& operator=(const basic_string& rhs){
        if(this != &rhs){
            set_size(rhs.size());

            if(capacity() < rhs.capacity()){
                auto capacity = rhs.capacity();

                if(is_small()){
                    new (&storage.big) base_long<CharT>(capacity, new CharT[capacity]);

                    set_small(false);
                } else {
                    storage.big.capacity = capacity;
                    storage.big.data.reset(new CharT[capacity]);
                }
            }

            std::copy_n(begin(), rhs.begin(), size() + 1);
        }

        return *this;
    }

    //Move

    basic_string(basic_string&& rhs) : _size(rhs._size) {
        if(is_small()){
            new (&storage.small) base_short<CharT>(std::move(rhs.storage.small));
        } else {
            new (&storage.big) base_long<CharT>(std::move(rhs.storage.big));
        }

        rhs._size = 0;
        rhs.zero();
    }

    basic_string& operator=(basic_string&& rhs){
        auto was_small = is_small();
        auto was_long = !was_small;

        auto small = rhs.is_small();
        auto lng = !small;

        set_size(rhs.size());

        if(was_small && small){
            storage.small = std::move(rhs.storage.small);
        } else if(was_long && lng){
            storage.big = std::move(rhs.storage.big);
        } else if(was_small && lng){
            new (&storage.big) base_long<CharT>(std::move(rhs.storage.big));

            set_small(false);
        } else if(was_long && small){
            ensure_capacity(rhs.size() + 1);

            std::copy_n(begin(), rhs.begin(), size() + 1);
        }

        rhs._size = 0;
        rhs.zero();

        return *this;
    }

    //Destructors

    ~basic_string(){
        if(is_long()){
            storage.big.~base_long();
        }
    }

    //Modifiers

    void adjust_size(size_t size){
        set_size(size);
    }

    void clear(){
        set_size(0);
        (*this)[0] = '\0';
    }

    void pop_back(){
        set_size(size() - 1);
        (*this)[size()] = '\0';
    }

    void reserve(size_t new_capacity){
        ensure_capacity(new_capacity);
    }

    basic_string operator+(CharT c) const {
        basic_string copy(*this);

        copy += c;

        return move(copy);
    }

    basic_string& operator+=(CharT c){
        ensure_capacity(size() + 2);

        (*this)[size()] = c;
        (*this)[size() + 1] = '\0';

        set_size(size() + 1);

        return *this;
    }

    void ensure_capacity(size_t new_capacity){
        if(new_capacity > 0 && (capacity() < new_capacity)){
            auto new_cap = capacity() * 2;

            if(new_cap < new_capacity){
                new_cap = new_capacity;
            }

            auto new_data = new CharT[new_cap];

            std::copy_n(new_data, begin(), size() + 1);

            if(is_small()){
                new (&storage.big) base_long<CharT>(new_cap, new_data);

                set_small(false);
            } else {
                storage.big.data.reset(new_data);
                storage.big.capacity = new_cap;
            }
        }
    }

    basic_string& operator+=(const char* rhs){
        auto len = str_len(rhs);

        ensure_capacity(size() + len + 1);

        std::copy_n(begin() + size(), rhs, len);

        set_size(size() + len);

        (*this)[size()] = '\0';

        return *this;
    }

    basic_string& operator+=(const basic_string& rhs){
        ensure_capacity(size() + rhs.size() + 1);

        std::copy_n(begin() + size(), rhs.begin(), rhs.size());

        set_size(size() + rhs.size());

        (*this)[size()] = '\0';

        return *this;
    }

    //Accessors

    size_t size() const {
        return _size & ~(1UL << 63);
    }

    size_t capacity() const {
        if(is_small()){
            return 16;
        } else {
            return storage.big.capacity;
        }
    }

    bool empty() const {
        return size() == 0;
    }

    CharT* data_ptr(){
        if(is_small()){
            return &storage.small.data[0];
        } else {
            return storage.big.data.get();
        }
    }

    const CharT* data_ptr() const {
        if(is_small()){
            return &storage.small.data[0];
        } else {
            return storage.big.data.get();
        }
    }

    CharT* c_str(){
        return data_ptr();
    }

    const CharT* c_str() const {
        return data_ptr();
    }

    CharT& operator[](size_t i){
        return *(data_ptr() + i);
    }

    const CharT& operator[](size_t i) const {
        return *(data_ptr() + i);
    }

    size_t find(char c) const {
        for(size_t i = 0; i < size(); ++i){
            if((*this)[i] == c){
                return i;
            }
        }

        return npos;
    }

    //Operators

    bool operator==(const CharT* s) const {
        if(size() != str_len(s)){
            return false;
        }

        for(size_t i = 0; i < size(); ++i){
            if((*this)[i] != s[i]){
                return false;
            }
        }

        return true;
    }

    bool operator!=(const CharT* s) const {
        return !(*this == s);
    }

    bool operator==(const basic_string& rhs) const {
        if(size() != rhs.size()){
            return false;
        }

        for(size_t i = 0; i < size(); ++i){
            if((*this)[i] != rhs[i]){
                return false;
            }
        }

        return true;
    }

    bool operator!=(const basic_string& rhs) const {
        return !(*this == rhs);
    }

    //Iterators

    iterator begin(){
        return iterator(data_ptr());
    }

    iterator end(){
        return iterator(data_ptr() + size());
    }

    const_iterator begin() const {
        return const_iterator(data_ptr());
    }

    const_iterator end() const {
        return const_iterator(data_ptr() + size());
    }
};

template<typename C>
basic_string<C> operator+(const basic_string<C>& lhs, const basic_string<C>& rhs){
    basic_string<C> result;
    result += lhs;
    result += rhs;
    return std::move(result);
}

template<typename C>
basic_string<C> operator+(const C* lhs, const basic_string<C>& rhs){
    basic_string<C> result;
    result += lhs;
    result += rhs;
    return std::move(result);
}

template<typename C>
basic_string<C> operator+(const basic_string<C>& lhs, const C* rhs){
    basic_string<C> result;
    result += lhs;
    result += rhs;
    return std::move(result);
}

typedef basic_string<char> string;

static_assert(sizeof(string) == 24, "The size of a string must always be 24 bytes");

inline uint64_t parse(const char* it, const char* end){
    int i = end - it - 1;

    uint64_t factor = 1;
    uint64_t acc = 0;

    for(; i >= 0; --i){
        acc += (it[i] - '0') * factor;
        factor *= 10;
    }

    return acc;
}

inline uint64_t parse(const char* str){
    int i = 0;

    const char* it = str;
    while(*++it){
        ++i;
    }

    uint64_t factor = 1;
    uint64_t acc = 0;

    for(; i >= 0; --i){
        acc += (str[i] - '0') * factor;
        factor *= 10;
    }

    return acc;
}

inline uint64_t parse(const string& str){
    return parse(str.begin(), str.end());
}

template<typename N>
size_t digits(N number){
    if(number < 10){
        return 1;
    }

    size_t i = 0;

    while(number != 0){
        number /= 10;
        ++i;
    }

    return i;
}

template<typename Char>
std::vector<std::basic_string<Char>> split(const std::basic_string<Char>& s, char sep = ' '){
    std::vector<std::basic_string<Char>> parts;

    std::basic_string<Char> current(s.size());

    for(char c : s){
        if(c == sep && !current.empty()){
            parts.push_back(current);
            current.clear();
        } else if(c == sep){
            continue;
        } else {
            current += c;
        }
    }

    if(!current.empty()){
        parts.push_back(current);
    }

    return std::move(parts);
}

template<typename T>
std::string to_string(const T& value);

template<>
inline std::string to_string<uint64_t>(const uint64_t& value){
    if(value == 0){
        return "0";
    }

    std::string s;

    char buffer[20];
    int i = 0;
    auto rem = value;

    while(rem != 0){
        buffer[i++] = '0' + rem  % 10;
        rem /= 10;
    }

    --i;

    for(; i >= 0; --i){
        s += buffer[i];
    }

    return std::move(s);
}

template<>
inline std::string to_string<int64_t>(const int64_t& value){
    if(value < 0){
        std::string s("-");
        s += to_string(static_cast<uint64_t>(value));
        return std::move(s);
    } else {
        return to_string(static_cast<uint64_t>(value));
    }
}

template<>
inline std::string to_string<uint8_t>(const uint8_t& value){
    return to_string(static_cast<uint64_t>(value));
}

template<>
inline std::string to_string<uint16_t>(const uint16_t& value){
    return to_string(static_cast<uint64_t>(value));
}

template<>
inline std::string to_string<uint32_t>(const uint32_t& value){
    return to_string(static_cast<uint64_t>(value));
}

template<>
inline std::string to_string<int8_t>(const int8_t& value){
    return to_string(static_cast<int64_t>(value));
}

template<>
inline std::string to_string<int16_t>(const int16_t& value){
    return to_string(static_cast<int64_t>(value));
}

template<>
inline std::string to_string<int32_t>(const int32_t& value){
    return to_string(static_cast<int64_t>(value));
}

} //end of namespace std

#endif
<commit_msg>Add note<commit_after>//=======================================================================// Copyright Baptiste Wicht 2013-2014.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#ifndef STRING_H
#define STRING_H

#include <types.hpp>
#include <algorithms.hpp>
#include <vector.hpp>
#include <unique_ptr.hpp>

namespace std {

inline uint64_t str_len(const char* a){
    uint64_t length = 0;
    while(*a++){
        ++length;
    }
    return length;
}

template<typename CharT>
struct base_long {
    size_t capacity;
    unique_ptr<CharT[]> data;

    base_long() = default;

    base_long(size_t capacity, CharT* array) : capacity(capacity), data(array) {}

    base_long(base_long&) = delete;
    base_long& operator=(base_long&) = delete;

    base_long(base_long&&) = default;
    base_long& operator=(base_long&&) = default;
};

static constexpr const size_t min_capacity = 16;
static constexpr const size_t words = min_capacity / sizeof(size_t);

//TODO Store size into base and use only one unsigned char for base_short

template<typename CharT>
struct base_short {
    CharT data[min_capacity];

    base_short() = default;

    base_short(base_short&) = delete;
    base_short& operator=(base_short&) = delete;

    base_short(base_short&&) = default;
    base_short& operator=(base_short&&) = default;
};

struct base_raw {
    size_t data[words];

    base_raw() = delete;

    base_raw(base_raw&) = delete;
    base_raw& operator=(base_raw&) = delete;

    base_raw(base_raw&&) = delete;
    base_raw& operator=(base_raw&&) = delete;
};

template<typename CharT>
union base_storage {
    base_short<CharT> small;
    base_long<CharT> big;
    base_raw raw;

    base_storage(){
        //Default construction: Nothing to do
    }

    ~base_storage() {}
};

static_assert(min_capacity == sizeof(base_short<char>), "base_short must be the correct SSO size");
static_assert(min_capacity == sizeof(base_long<char>), "base_long must be the correct SSO size");
static_assert(min_capacity == sizeof(base_raw), "base_raw must be the correct SSO size");

template<typename CharT>
struct basic_string {
public:
    typedef CharT*             iterator;
    typedef const CharT*       const_iterator;

    static constexpr const size_t npos = -1;

private:
    size_t _size;

    base_storage<CharT> storage;

    void set_long(bool small){
        if(small){
            _size |= (1UL << 63);
        } else {
            _size &= ~(1UL << 63);
        }
    }

    void set_small(bool small){
        set_long(!small);
    }

    void set_size(size_t size){
        if(is_long()){
            _size = size | (1UL << 63);
        } else {
            _size = size;
        }
    }

    bool is_long() const {
        return _size & (1UL << 63);
    }

    bool is_small() const {
        return !is_long();
    }

    void zero(){
        for(size_t i = 0; i < words; ++i){
            storage.raw.data[i] = 0;
        }
    }

public:
    //Constructors

    basic_string() : _size(0){
        set_small(true);

        (*this)[0] = '\0';
    }

    basic_string(const CharT* s) : _size(str_len(s)) {
        auto capacity = size() + 1;

        set_small(capacity <= 16);

        if(!is_small()){
            new (&storage.big) base_long<CharT>(capacity, new CharT[capacity]);
        }

        std::copy_n(begin(), s, capacity);
    }

    explicit basic_string(size_t __capacity) : _size(0) {
        set_small(__capacity <= 16);

        if(!is_small()){
            new (&storage.big) base_long<CharT>(__capacity, new CharT[__capacity]);
        }

        (*this)[0] = '\0';
    }

    //Copy

    basic_string(const basic_string& rhs) : _size(rhs._size) {
        if(!is_small()){
            new (&storage.big) base_long<CharT>(size() + 1, new CharT[size() + 1]);
        }

        std::copy_n(begin(), rhs.begin(), size() + 1);
    }

    basic_string& operator=(const basic_string& rhs){
        if(this != &rhs){
            set_size(rhs.size());

            if(capacity() < rhs.capacity()){
                auto capacity = rhs.capacity();

                if(is_small()){
                    new (&storage.big) base_long<CharT>(capacity, new CharT[capacity]);

                    set_small(false);
                } else {
                    storage.big.capacity = capacity;
                    storage.big.data.reset(new CharT[capacity]);
                }
            }

            std::copy_n(begin(), rhs.begin(), size() + 1);
        }

        return *this;
    }

    //Move

    basic_string(basic_string&& rhs) : _size(rhs._size) {
        if(is_small()){
            new (&storage.small) base_short<CharT>(std::move(rhs.storage.small));
        } else {
            new (&storage.big) base_long<CharT>(std::move(rhs.storage.big));
        }

        rhs._size = 0;
        rhs.zero();
    }

    basic_string& operator=(basic_string&& rhs){
        auto was_small = is_small();
        auto was_long = !was_small;

        auto small = rhs.is_small();
        auto lng = !small;

        set_size(rhs.size());

        if(was_small && small){
            storage.small = std::move(rhs.storage.small);
        } else if(was_long && lng){
            storage.big = std::move(rhs.storage.big);
        } else if(was_small && lng){
            new (&storage.big) base_long<CharT>(std::move(rhs.storage.big));

            set_small(false);
        } else if(was_long && small){
            ensure_capacity(rhs.size() + 1);

            std::copy_n(begin(), rhs.begin(), size() + 1);
        }

        rhs._size = 0;
        rhs.zero();

        return *this;
    }

    //Destructors

    ~basic_string(){
        if(is_long()){
            storage.big.~base_long();
        }
    }

    //Modifiers

    void adjust_size(size_t size){
        set_size(size);
    }

    void clear(){
        set_size(0);
        (*this)[0] = '\0';
    }

    void pop_back(){
        set_size(size() - 1);
        (*this)[size()] = '\0';
    }

    void reserve(size_t new_capacity){
        ensure_capacity(new_capacity);
    }

    basic_string operator+(CharT c) const {
        basic_string copy(*this);

        copy += c;

        return move(copy);
    }

    basic_string& operator+=(CharT c){
        ensure_capacity(size() + 2);

        (*this)[size()] = c;
        (*this)[size() + 1] = '\0';

        set_size(size() + 1);

        return *this;
    }

    void ensure_capacity(size_t new_capacity){
        if(new_capacity > 0 && (capacity() < new_capacity)){
            auto new_cap = capacity() * 2;

            if(new_cap < new_capacity){
                new_cap = new_capacity;
            }

            auto new_data = new CharT[new_cap];

            std::copy_n(new_data, begin(), size() + 1);

            if(is_small()){
                new (&storage.big) base_long<CharT>(new_cap, new_data);

                set_small(false);
            } else {
                storage.big.data.reset(new_data);
                storage.big.capacity = new_cap;
            }
        }
    }

    basic_string& operator+=(const char* rhs){
        auto len = str_len(rhs);

        ensure_capacity(size() + len + 1);

        std::copy_n(begin() + size(), rhs, len);

        set_size(size() + len);

        (*this)[size()] = '\0';

        return *this;
    }

    basic_string& operator+=(const basic_string& rhs){
        ensure_capacity(size() + rhs.size() + 1);

        std::copy_n(begin() + size(), rhs.begin(), rhs.size());

        set_size(size() + rhs.size());

        (*this)[size()] = '\0';

        return *this;
    }

    //Accessors

    size_t size() const {
        return _size & ~(1UL << 63);
    }

    size_t capacity() const {
        if(is_small()){
            return 16;
        } else {
            return storage.big.capacity;
        }
    }

    bool empty() const {
        return size() == 0;
    }

    CharT* data_ptr(){
        if(is_small()){
            return &storage.small.data[0];
        } else {
            return storage.big.data.get();
        }
    }

    const CharT* data_ptr() const {
        if(is_small()){
            return &storage.small.data[0];
        } else {
            return storage.big.data.get();
        }
    }

    CharT* c_str(){
        return data_ptr();
    }

    const CharT* c_str() const {
        return data_ptr();
    }

    CharT& operator[](size_t i){
        return *(data_ptr() + i);
    }

    const CharT& operator[](size_t i) const {
        return *(data_ptr() + i);
    }

    size_t find(char c) const {
        for(size_t i = 0; i < size(); ++i){
            if((*this)[i] == c){
                return i;
            }
        }

        return npos;
    }

    //Operators

    bool operator==(const CharT* s) const {
        if(size() != str_len(s)){
            return false;
        }

        for(size_t i = 0; i < size(); ++i){
            if((*this)[i] != s[i]){
                return false;
            }
        }

        return true;
    }

    bool operator!=(const CharT* s) const {
        return !(*this == s);
    }

    bool operator==(const basic_string& rhs) const {
        if(size() != rhs.size()){
            return false;
        }

        for(size_t i = 0; i < size(); ++i){
            if((*this)[i] != rhs[i]){
                return false;
            }
        }

        return true;
    }

    bool operator!=(const basic_string& rhs) const {
        return !(*this == rhs);
    }

    //Iterators

    iterator begin(){
        return iterator(data_ptr());
    }

    iterator end(){
        return iterator(data_ptr() + size());
    }

    const_iterator begin() const {
        return const_iterator(data_ptr());
    }

    const_iterator end() const {
        return const_iterator(data_ptr() + size());
    }
};

template<typename C>
basic_string<C> operator+(const basic_string<C>& lhs, const basic_string<C>& rhs){
    basic_string<C> result;
    result += lhs;
    result += rhs;
    return std::move(result);
}

template<typename C>
basic_string<C> operator+(const C* lhs, const basic_string<C>& rhs){
    basic_string<C> result;
    result += lhs;
    result += rhs;
    return std::move(result);
}

template<typename C>
basic_string<C> operator+(const basic_string<C>& lhs, const C* rhs){
    basic_string<C> result;
    result += lhs;
    result += rhs;
    return std::move(result);
}

typedef basic_string<char> string;

static_assert(sizeof(string) == 24, "The size of a string must always be 24 bytes");

inline uint64_t parse(const char* it, const char* end){
    int i = end - it - 1;

    uint64_t factor = 1;
    uint64_t acc = 0;

    for(; i >= 0; --i){
        acc += (it[i] - '0') * factor;
        factor *= 10;
    }

    return acc;
}

inline uint64_t parse(const char* str){
    int i = 0;

    const char* it = str;
    while(*++it){
        ++i;
    }

    uint64_t factor = 1;
    uint64_t acc = 0;

    for(; i >= 0; --i){
        acc += (str[i] - '0') * factor;
        factor *= 10;
    }

    return acc;
}

inline uint64_t parse(const string& str){
    return parse(str.begin(), str.end());
}

template<typename N>
size_t digits(N number){
    if(number < 10){
        return 1;
    }

    size_t i = 0;

    while(number != 0){
        number /= 10;
        ++i;
    }

    return i;
}

template<typename Char>
std::vector<std::basic_string<Char>> split(const std::basic_string<Char>& s, char sep = ' '){
    std::vector<std::basic_string<Char>> parts;

    std::basic_string<Char> current(s.size());

    for(char c : s){
        if(c == sep && !current.empty()){
            parts.push_back(current);
            current.clear();
        } else if(c == sep){
            continue;
        } else {
            current += c;
        }
    }

    if(!current.empty()){
        parts.push_back(current);
    }

    return std::move(parts);
}

template<typename T>
std::string to_string(const T& value);

template<>
inline std::string to_string<uint64_t>(const uint64_t& value){
    if(value == 0){
        return "0";
    }

    std::string s;

    char buffer[20];
    int i = 0;
    auto rem = value;

    while(rem != 0){
        buffer[i++] = '0' + rem  % 10;
        rem /= 10;
    }

    --i;

    for(; i >= 0; --i){
        s += buffer[i];
    }

    return std::move(s);
}

template<>
inline std::string to_string<int64_t>(const int64_t& value){
    if(value < 0){
        std::string s("-");
        s += to_string(static_cast<uint64_t>(value));
        return std::move(s);
    } else {
        return to_string(static_cast<uint64_t>(value));
    }
}

template<>
inline std::string to_string<uint8_t>(const uint8_t& value){
    return to_string(static_cast<uint64_t>(value));
}

template<>
inline std::string to_string<uint16_t>(const uint16_t& value){
    return to_string(static_cast<uint64_t>(value));
}

template<>
inline std::string to_string<uint32_t>(const uint32_t& value){
    return to_string(static_cast<uint64_t>(value));
}

template<>
inline std::string to_string<int8_t>(const int8_t& value){
    return to_string(static_cast<int64_t>(value));
}

template<>
inline std::string to_string<int16_t>(const int16_t& value){
    return to_string(static_cast<int64_t>(value));
}

template<>
inline std::string to_string<int32_t>(const int32_t& value){
    return to_string(static_cast<int64_t>(value));
}

} //end of namespace std

#endif
<|endoftext|>


<commit_before><commit_msg>I fixed a few bugs, but the visualiation scripts are still all reading 0...<commit_after><|endoftext|>