<commit_before>/***********************************************************************
    created:    Sat Jul 19 2014
    author:     Timotei Dolean <timotei21@gmail.com>
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2014 Paul D Turner & The CEGUI Development Team
 *
 *   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 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 "CEGUI/widgets/ListWidget.h"

namespace CEGUI
{

//----------------------------------------------------------------------------//
ListWidgetItem& indexToWidgetItem(const ModelIndex& index)
{
    return *(static_cast<ListWidgetItem*>(index.d_modelData));
}

//----------------------------------------------------------------------------//
const String ListWidget::EventNamespace("ListWidget");
const String ListWidget::WidgetTypeName("CEGUI/ListWidget");

//----------------------------------------------------------------------------//
ListWidget::ListWidget(const String& type, const String& name) :
    ListView(type, name)
{
}

//----------------------------------------------------------------------------//
ListWidget::~ListWidget()
{
}

//----------------------------------------------------------------------------//
ListWidgetItem::ListWidgetItem()
{

}

//----------------------------------------------------------------------------//
ListWidgetItem::~ListWidgetItem()
{
}

//----------------------------------------------------------------------------//
bool ListWidgetItem::operator==(const ListWidgetItem& other) const
{
    return getText() == other.getText();
}

//----------------------------------------------------------------------------//
bool ListWidgetItem::operator<(const ListWidgetItem& other) const
{
    return getText() < other.getText();
}

//----------------------------------------------------------------------------//
bool ListWidget::isValidIndex(const ModelIndex& model_index) const
{
    return model_index.d_modelData != 0 && getChildId(model_index) != -1;
}

//----------------------------------------------------------------------------//
ModelIndex ListWidget::makeIndex(size_t child, const ModelIndex& parent_index)
{
    if (child >= d_widgetItems.size())
        return ModelIndex();

    return ModelIndex(&d_widgetItems[child]);
}

//----------------------------------------------------------------------------//
bool ListWidget::areIndicesEqual(const ModelIndex& index1, const ModelIndex& index2) const
{
    return compareIndices(index1, index2) == 0;
}

//----------------------------------------------------------------------------//
int ListWidget::compareIndices(const ModelIndex& index1, const ModelIndex& index2) const
{
    if (!isValidIndex(index1) || !isValidIndex(index2))
        return false;

    return indexToWidgetItem(index1) < indexToWidgetItem(index2);
}

//----------------------------------------------------------------------------//
ModelIndex ListWidget::getParentIndex(const ModelIndex& model_index) const
{
    return getRootIndex();
}

//----------------------------------------------------------------------------//
int ListWidget::getChildId(const ModelIndex& model_index) const
{
    std::vector<ListWidgetItem>::const_iterator itor =
        std::find(d_widgetItems.begin(), d_widgetItems.end(), indexToWidgetItem(model_index));

    if (itor == d_widgetItems.end())
        return -1;

    return std::distance(d_widgetItems.begin(), itor);
}

//----------------------------------------------------------------------------//
ModelIndex ListWidget::getRootIndex() const
{
    return ModelIndex();
}

//----------------------------------------------------------------------------//
size_t ListWidget::getChildCount(const ModelIndex& model_index) const
{
    return d_widgetItems.size();
}

//----------------------------------------------------------------------------//
String ListWidget::getData(const ModelIndex& model_index, ItemDataRole role /*= IDR_Text*/)
{
    if (!isValidIndex(model_index))
        return "";

    return indexToWidgetItem(model_index).getText();
}

//----------------------------------------------------------------------------//
void ListWidget::addItem(String text)
{
    ListWidgetItem item;
    item.setText(text);

    addItem(item);
}

//----------------------------------------------------------------------------//
void ListWidget::addItem(const ListWidgetItem& item)
{
    d_widgetItems.push_back(item);
    notifyChildrenAdded(getRootIndex(), d_widgetItems.size() - 1, 1);
}

//----------------------------------------------------------------------------//
void ListWidget::initialiseComponents()
{
    ListView::initialiseComponents();
    setModel(this);
}
}
<commit_msg>Properly implement 'compareIndices' for ListWidget<commit_after>/***********************************************************************
    created:    Sat Jul 19 2014
    author:     Timotei Dolean <timotei21@gmail.com>
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2014 Paul D Turner & The CEGUI Development Team
 *
 *   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 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 "CEGUI/widgets/ListWidget.h"

namespace CEGUI
{

//----------------------------------------------------------------------------//
ListWidgetItem& indexToWidgetItem(const ModelIndex& index)
{
    return *(static_cast<ListWidgetItem*>(index.d_modelData));
}

//----------------------------------------------------------------------------//
const String ListWidget::EventNamespace("ListWidget");
const String ListWidget::WidgetTypeName("CEGUI/ListWidget");

//----------------------------------------------------------------------------//
ListWidget::ListWidget(const String& type, const String& name) :
    ListView(type, name)
{
}

//----------------------------------------------------------------------------//
ListWidget::~ListWidget()
{
}

//----------------------------------------------------------------------------//
ListWidgetItem::ListWidgetItem()
{

}

//----------------------------------------------------------------------------//
ListWidgetItem::~ListWidgetItem()
{
}

//----------------------------------------------------------------------------//
bool ListWidgetItem::operator==(const ListWidgetItem& other) const
{
    return getText() == other.getText();
}

//----------------------------------------------------------------------------//
bool ListWidgetItem::operator<(const ListWidgetItem& other) const
{
    return getText() < other.getText();
}

//----------------------------------------------------------------------------//
bool ListWidget::isValidIndex(const ModelIndex& model_index) const
{
    return model_index.d_modelData != 0 && getChildId(model_index) != -1;
}

//----------------------------------------------------------------------------//
ModelIndex ListWidget::makeIndex(size_t child, const ModelIndex& parent_index)
{
    if (child >= d_widgetItems.size())
        return ModelIndex();

    return ModelIndex(&d_widgetItems[child]);
}

//----------------------------------------------------------------------------//
bool ListWidget::areIndicesEqual(const ModelIndex& index1, const ModelIndex& index2) const
{
    return compareIndices(index1, index2) == 0;
}

//----------------------------------------------------------------------------//
int ListWidget::compareIndices(const ModelIndex& index1, const ModelIndex& index2) const
{
    if (!isValidIndex(index1) || !isValidIndex(index2))
        return false;

    if (indexToWidgetItem(index1) < indexToWidgetItem(index2))
        return -1;

    return indexToWidgetItem(index1) == indexToWidgetItem(index2) ? 0 : 1;
}

//----------------------------------------------------------------------------//
ModelIndex ListWidget::getParentIndex(const ModelIndex& model_index) const
{
    return getRootIndex();
}

//----------------------------------------------------------------------------//
int ListWidget::getChildId(const ModelIndex& model_index) const
{
    std::vector<ListWidgetItem>::const_iterator itor =
        std::find(d_widgetItems.begin(), d_widgetItems.end(), indexToWidgetItem(model_index));

    if (itor == d_widgetItems.end())
        return -1;

    return std::distance(d_widgetItems.begin(), itor);
}

//----------------------------------------------------------------------------//
ModelIndex ListWidget::getRootIndex() const
{
    return ModelIndex();
}

//----------------------------------------------------------------------------//
size_t ListWidget::getChildCount(const ModelIndex& model_index) const
{
    return d_widgetItems.size();
}

//----------------------------------------------------------------------------//
String ListWidget::getData(const ModelIndex& model_index, ItemDataRole role /*= IDR_Text*/)
{
    if (!isValidIndex(model_index))
        return "";

    return indexToWidgetItem(model_index).getText();
}

//----------------------------------------------------------------------------//
void ListWidget::addItem(String text)
{
    ListWidgetItem item;
    item.setText(text);

    addItem(item);
}

//----------------------------------------------------------------------------//
void ListWidget::addItem(const ListWidgetItem& item)
{
    d_widgetItems.push_back(item);
    notifyChildrenAdded(getRootIndex(), d_widgetItems.size() - 1, 1);
}

//----------------------------------------------------------------------------//
void ListWidget::initialiseComponents()
{
    ListView::initialiseComponents();
    setModel(this);
}
}
<|endoftext|>


<commit_before>#include "properties/QuaternionProperty.h"

#include "i6engine/math/i6eVector.h"

#include "properties/Vec3Property.h"

#include "widgets/PropertyWindow.h"

#include <QLabel>
#include <QDoubleSpinBox>

namespace i6engine {
namespace particleEditor {
namespace properties {

	QuaternionProperty::QuaternionProperty(QWidget * par, QString label, QString name, Quaternion value) : Property(par, label, name), _layout(nullptr), _value(value), _vec3Property(nullptr), _doubleSpinBox(nullptr) {
		QWidget * widget = new QWidget(this);
		Vec3 axis;
		double angle;
		value.toAxisAngle(axis, angle);

		_layout = new QGridLayout(widget);
		widget->setLayout(_layout);
		_vec3Property = new Vec3Property(widget, "Axis", "Axis", axis.toOgre());
		_layout->addWidget(_vec3Property, 0, 0);
		connect(_vec3Property, SIGNAL(changed(QString)), this, SLOT(changedValue()));
		_vec3Property->setSizePolicy(QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Fixed);

		QLabel * l = new QLabel("Angle", widget);
		_layout->addWidget(l, 1, 0);
		_doubleSpinBox = new QDoubleSpinBox(this);
		_doubleSpinBox->setMinimum(-360.0);
		_doubleSpinBox->setMaximum(360.0);
		_doubleSpinBox->setValue(angle);
		_layout->addWidget(_doubleSpinBox, 2, 0);
		connect(_doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changedValue()));
		l->setSizePolicy(QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Fixed);
		_doubleSpinBox->setSizePolicy(QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Fixed);

		horizontalLayout->addWidget(widget);
	}

	QuaternionProperty::~QuaternionProperty() {
	}

	void QuaternionProperty::setQuaternion(Quaternion value) {
		_value = value;
		Vec3 axis;
		double angle;
		value.toAxisAngle(axis, angle);
		_vec3Property->setVector3(axis.toOgre());
		_doubleSpinBox->setValue(angle);
	}

	void QuaternionProperty::changedValue() {
		_value = Quaternion(Vec3(_vec3Property->getVector3()), _doubleSpinBox->value());
		triggerChangedSignal();
	}

} /* namespace properties */
} /* namespace particleEditor */
} /* namespace i6engine */
<commit_msg>ISIXE-1745 changing orientation in ParticleEditor doesn't crash anymore<commit_after>#include "properties/QuaternionProperty.h"

#include "i6engine/math/i6eVector.h"

#include "properties/Vec3Property.h"

#include "widgets/PropertyWindow.h"

#include <QLabel>
#include <QDoubleSpinBox>

namespace i6engine {
namespace particleEditor {
namespace properties {

	QuaternionProperty::QuaternionProperty(QWidget * par, QString label, QString name, Quaternion value) : Property(par, label, name), _layout(nullptr), _value(value), _vec3Property(nullptr), _doubleSpinBox(nullptr) {
		QWidget * widget = new QWidget(this);
		Vec3 axis;
		double angle;
		value.toAxisAngle(axis, angle);

		_layout = new QGridLayout(widget);
		widget->setLayout(_layout);
		_vec3Property = new Vec3Property(widget, "Axis", "Axis", axis.toOgre());
		_layout->addWidget(_vec3Property, 0, 0);
		connect(_vec3Property, SIGNAL(changed(QString)), this, SLOT(changedValue()));
		_vec3Property->setSizePolicy(QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Fixed);

		QLabel * l = new QLabel("Angle", widget);
		_layout->addWidget(l, 1, 0);
		_doubleSpinBox = new QDoubleSpinBox(this);
		_doubleSpinBox->setMinimum(-360.0);
		_doubleSpinBox->setMaximum(360.0);
		_doubleSpinBox->setValue(angle);
		_layout->addWidget(_doubleSpinBox, 2, 0);
		connect(_doubleSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changedValue()));
		l->setSizePolicy(QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Fixed);
		_doubleSpinBox->setSizePolicy(QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Fixed);

		horizontalLayout->addWidget(widget);
	}

	QuaternionProperty::~QuaternionProperty() {
	}

	void QuaternionProperty::setQuaternion(Quaternion value) {
		_value = value;
		Vec3 axis;
		double angle;
		value.toAxisAngle(axis, angle);
		_vec3Property->setVector3(axis.toOgre());
		_doubleSpinBox->setValue(angle);
	}

	void QuaternionProperty::changedValue() {
		_value = Quaternion(Vec3(_vec3Property->getVector3().normalisedCopy()), _doubleSpinBox->value());
		triggerChangedSignal();
	}

} /* namespace properties */
} /* namespace particleEditor */
} /* namespace i6engine */
<|endoftext|>


<commit_before>/* -*- mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
// vim:sts=8:sw=8:ts=8:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
//#include "goto-def.h"

/* Copyright (c) FFLAS-FFPACK
* Written by Clément Pernet <clement.pernet@imag.fr>
* ========LICENCE========
* This file is part of the library FFLAS-FFPACK.
*
* FFLAS-FFPACK is free software: you can redistribute it and/or modify
* it under the terms of the  GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
* ========LICENCE========
*/
#define __FFLASFFPACK_USE_OPENMP4
#include <iostream>

#include "fflas-ffpack/config-blas.h"
#include "fflas-ffpack/fflas/fflas.h"
#include "fflas-ffpack/field/modular-balanced.h"
#include "fflas-ffpack/utils/timer.h"
#include "fflas-ffpack/utils/Matio.h"
#include "fflas-ffpack/utils/args-parser.h"
#include "tests/test-utils.h"
#include "libkomp.h"
using namespace std;

#ifdef __FFLASFFPACK_USE_OPENMP4

template<class Element>
void Initialize(Element * C, int BS, size_t m, size_t n)
{
//#pragma omp parallel for collapse(2) schedule(runtime)
	BS=std::max(BS, __FFLASFFPACK_WINOTHRESHOLD_BAL );
	PAR_REGION{
	for(size_t p=0; p<m; p+=BS) ///row
		for(size_t pp=0; pp<n; pp+=BS) //column
		{
			size_t M=BS, MM=BS;
			if(!(p+BS<m))
				M=m-p;
			if(!(pp+BS<n))
				MM=n-pp;
#pragma omp task
			{
			for(size_t j=0; j<M; j++)
				for(size_t jj=0; jj<MM; jj++)
					C[(p+j)*n+pp+jj]=0;
			}
		}
	#pragma omp taskwait
	}
	// printf("A = \n");
	// for (size_t i=0; i<m; i+=128)
	//  {
	//  	for (size_t j=0; j<n; j+=128)
	//  	{
	//  		int ld = komp_get_locality_domain_num_for( &C[i*n+j] );
	//  		printf("%i ", ld);
	//  	}
	//  	printf("\n");
	//  }

}
#endif
int main(int argc, char** argv) {

	size_t iter = 3 ;
	int q = 131071 ;
	size_t m = 2000 ;
	size_t k = 2000 ;
	size_t n = 2000 ;
	int nbw = -1 ;
	int p=0;
	int t=MAX_THREADS;
	int NBK = -1;
	Argument as[] = {
		{ 'q', "-q Q", "Set the field characteristic (-1 for random).",         TYPE_INT , &q },
		{ 'm', "-m M", "Set the row dimension of A.",      TYPE_INT , &m },
		{ 'k', "-k K", "Set the col dimension of A.",      TYPE_INT , &k },
		{ 'n', "-n N", "Set the col dimension of B.",      TYPE_INT , &n },
		{ 'w', "-w N", "Set the number of winograd levels (-1 for random).",    TYPE_INT , &nbw },
		{ 'i', "-i R", "Set number of repetitions.",            TYPE_INT , &iter },
		{ 'p', "-p P", "0 for sequential, 1 for 2D iterative, 2 for 2D rec, 3 for 2D rec adaptive, 4 for 3D rc in-place, 5 for 3D rec, 6 for 3D rec adaptive.", TYPE_INT , &p },
		{ 't', "-t T", "number of virtual threads to drive the partition.", TYPE_INT , &t },
		{ 'b', "-b B", "number of numa blocks per dimension for the numa placement", TYPE_INT , &NBK },
		END_OF_ARGUMENTS
	};

	FFLAS::parseArguments(argc,argv,as);

	if (NBK==-1) NBK = t;
  typedef FFPACK::ModularBalanced<double> Field;
//  typedef FFPACK::ModularBalanced<float> Field;
  typedef Field::Element Element;

  Field F(q);

  FFLAS::Timer chrono, freidvals;
  double time=0.0, timev=0.0;

  Element * A, * B, * C;
  Element *v, *w, *y, *x;

  Field::RandIter G(F);
  A = FFLAS::fflas_new(F,m,k,Alignment::PAGESIZE);
//#pragma omp parallel for collapse(2) schedule(runtime)
  Initialize(A,m/NBK,m,k);
  for (size_t i=0; i<(size_t)m; ++i)
	  for (size_t j=0; j<(size_t)k; ++j)
		  G.random (*(A+i*k+j));

  B = FFLAS::fflas_new(F,k,n,Alignment::PAGESIZE);
//#pragma omp parallel for collapse(2) schedule(runtime)
  Initialize(B,k/NBK,k,n);
  for (size_t i=0; i<(size_t)k; ++i)
	  for (size_t j=0; j<(size_t)n; ++j)
		  G.random(*(B+i*n+j));

  C = FFLAS::fflas_new(F,m,n,Alignment::PAGESIZE);
//#pragma omp parallel for collapse(2) schedule(runtime)
  Initialize(C,m/NBK,m,n);
  for (size_t i=0; i<(size_t)m; ++i)
	  for (size_t j=0; j<(size_t)n; ++j)
		  G.random (*(C+i*n+j));

  for (size_t i=0;i<=iter;++i){

	  // if (argc > 4){
	  // 	  A = read_field (F, argv[4], &n, &n);
	  // }
	  // else{

      v = FFLAS::fflas_new<Element>(n);

      Field::RandIter G(F);
      for(size_t j=0; j<(size_t)n; ++j)
              G.random(*(v+j));

      w = FFLAS::fflas_new<Element>(m);
      x = FFLAS::fflas_new<Element>(m);
      y = FFLAS::fflas_new<Element>(k);

      chrono.clear();
      if (i) chrono.start();
      if (p){
	      FFLAS::CuttingStrategy meth;
	      switch (p){
		  case 1: meth = FFLAS::BLOCK_THREADS;break;
		  case 2: meth = FFLAS::TWO_D;break;
		  case 3: meth = FFLAS::TWO_D_ADAPT;break;
		  case 4: meth = FFLAS::THREE_D_INPLACE;break;
		  case 5: meth = FFLAS::THREE_D;break;
		  case 6: meth = FFLAS::THREE_D_ADAPT;break;
		  default: meth = FFLAS::BLOCK_THREADS;break;
	      }
	      FFLAS::MMHelper<Field,FFLAS::MMHelperAlgo::Winograd,
			      typename FFLAS::FieldTraits<Field>::value,
			      FFLAS::ParSeqHelper::Parallel>
		      WH (F, nbw, FFLAS::ParSeqHelper::Parallel(t, meth));
	      PAR_REGION{
		      FFLAS::fgemm (F, FFLAS::FflasNoTrans, FFLAS::FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n,WH);
	      }
      }else{
	      FFLAS::MMHelper<Field,FFLAS::MMHelperAlgo::Winograd>//,
			  //typename FFLAS::FieldTraits<Field>::value,
			  //FFLAS::ParSeqHelper::Parallel>
	      WH (F, nbw);

	      FFLAS::fgemm (F, FFLAS::FflasNoTrans, FFLAS::FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n,WH);
      }
      if (i) {chrono.stop(); time+=chrono.realtime();}

      freidvals.clear();
      freidvals.start();
      FFLAS::fgemv(F, FFLAS::FflasNoTrans,m,n, F.one,
                   C, n, v, 1, F.zero, w, 1);
      FFLAS::fgemv(F, FFLAS::FflasNoTrans, k,n, F.one,
                   B, n, v, 1, F.zero, y, 1);
      FFLAS::fgemv(F, FFLAS::FflasNoTrans, m,k, F.one,
                   A, k, y, 1, F.zero, x, 1);
      bool pass=true;
      for(size_t j=0; j<(size_t)m; ++j) pass &= ( *(w+j) == *(x+j) );
      freidvals.stop();
      timev+=freidvals.usertime();
      if (!pass)
	      std::cerr<<"FAILED"<<std::endl;
	  //std::cerr << *A << ' ' << *B << ' ' << *C << ' '<< pass << std::endl;
  }
  FFLAS::fflas_delete( A);
  FFLAS::fflas_delete( B);
  FFLAS::fflas_delete( C);

  std::cerr<<"m: "<<m<<" k: "<<k<<" n: "<<n<<" q: "<<q<<" time: "<<time/(double)iter<<" Gfops: "<<(2.*double(m)/1000.*double(n)/1000.*double(k)/1000.0/*-m/1000.*n/1000.*/)/time*double(iter)<<std::endl;

      //std::cerr<<"Freidvals vtime: "<<timev/(double)iter<<std::endl;

  return 0;
}

<commit_msg>protect libkomp with KAAPI macro<commit_after>/* -*- mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
// vim:sts=8:sw=8:ts=8:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
//#include "goto-def.h"

/* Copyright (c) FFLAS-FFPACK
* Written by Clément Pernet <clement.pernet@imag.fr>
* ========LICENCE========
* This file is part of the library FFLAS-FFPACK.
*
* FFLAS-FFPACK is free software: you can redistribute it and/or modify
* it under the terms of the  GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
* ========LICENCE========
*/
#define __FFLASFFPACK_USE_OPENMP4
#include <iostream>

#include "fflas-ffpack/config-blas.h"
#include "fflas-ffpack/fflas/fflas.h"
#include "fflas-ffpack/field/modular-balanced.h"
#include "fflas-ffpack/utils/timer.h"
#include "fflas-ffpack/utils/Matio.h"
#include "fflas-ffpack/utils/args-parser.h"
#include "tests/test-utils.h"
#ifdef __FFLASFFPACK_USE_KAAPI
#include "libkomp.h"
#endif
using namespace std;

#ifdef __FFLASFFPACK_USE_OPENMP4

template<class Element>
void Initialize(Element * C, int BS, size_t m, size_t n)
{
//#pragma omp parallel for collapse(2) schedule(runtime)
	BS=std::max(BS, __FFLASFFPACK_WINOTHRESHOLD_BAL );
	PAR_REGION{
	for(size_t p=0; p<m; p+=BS) ///row
		for(size_t pp=0; pp<n; pp+=BS) //column
		{
			size_t M=BS, MM=BS;
			if(!(p+BS<m))
				M=m-p;
			if(!(pp+BS<n))
				MM=n-pp;
#pragma omp task
			{
			for(size_t j=0; j<M; j++)
				for(size_t jj=0; jj<MM; jj++)
					C[(p+j)*n+pp+jj]=0;
			}
		}
	#pragma omp taskwait
	}
	// printf("A = \n");
	// for (size_t i=0; i<m; i+=128)
	//  {
	//  	for (size_t j=0; j<n; j+=128)
	//  	{
	//  		int ld = komp_get_locality_domain_num_for( &C[i*n+j] );
	//  		printf("%i ", ld);
	//  	}
	//  	printf("\n");
	//  }

}
#endif
int main(int argc, char** argv) {

	size_t iter = 3 ;
	int q = 131071 ;
	size_t m = 2000 ;
	size_t k = 2000 ;
	size_t n = 2000 ;
	int nbw = -1 ;
	int p=0;
	int t=MAX_THREADS;
	int NBK = -1;
	Argument as[] = {
		{ 'q', "-q Q", "Set the field characteristic (-1 for random).",         TYPE_INT , &q },
		{ 'm', "-m M", "Set the row dimension of A.",      TYPE_INT , &m },
		{ 'k', "-k K", "Set the col dimension of A.",      TYPE_INT , &k },
		{ 'n', "-n N", "Set the col dimension of B.",      TYPE_INT , &n },
		{ 'w', "-w N", "Set the number of winograd levels (-1 for random).",    TYPE_INT , &nbw },
		{ 'i', "-i R", "Set number of repetitions.",            TYPE_INT , &iter },
		{ 'p', "-p P", "0 for sequential, 1 for 2D iterative, 2 for 2D rec, 3 for 2D rec adaptive, 4 for 3D rc in-place, 5 for 3D rec, 6 for 3D rec adaptive.", TYPE_INT , &p },
		{ 't', "-t T", "number of virtual threads to drive the partition.", TYPE_INT , &t },
		{ 'b', "-b B", "number of numa blocks per dimension for the numa placement", TYPE_INT , &NBK },
		END_OF_ARGUMENTS
	};

	FFLAS::parseArguments(argc,argv,as);

	if (NBK==-1) NBK = t;
  typedef FFPACK::ModularBalanced<double> Field;
//  typedef FFPACK::ModularBalanced<float> Field;
  typedef Field::Element Element;

  Field F(q);

  FFLAS::Timer chrono, freidvals;
  double time=0.0, timev=0.0;

  Element * A, * B, * C;
  Element *v, *w, *y, *x;

  Field::RandIter G(F);
  A = FFLAS::fflas_new(F,m,k,Alignment::PAGESIZE);
//#pragma omp parallel for collapse(2) schedule(runtime)
  Initialize(A,m/NBK,m,k);
  for (size_t i=0; i<(size_t)m; ++i)
	  for (size_t j=0; j<(size_t)k; ++j)
		  G.random (*(A+i*k+j));

  B = FFLAS::fflas_new(F,k,n,Alignment::PAGESIZE);
//#pragma omp parallel for collapse(2) schedule(runtime)
  Initialize(B,k/NBK,k,n);
  for (size_t i=0; i<(size_t)k; ++i)
	  for (size_t j=0; j<(size_t)n; ++j)
		  G.random(*(B+i*n+j));

  C = FFLAS::fflas_new(F,m,n,Alignment::PAGESIZE);
//#pragma omp parallel for collapse(2) schedule(runtime)
  Initialize(C,m/NBK,m,n);
  for (size_t i=0; i<(size_t)m; ++i)
	  for (size_t j=0; j<(size_t)n; ++j)
		  G.random (*(C+i*n+j));

  for (size_t i=0;i<=iter;++i){

	  // if (argc > 4){
	  // 	  A = read_field (F, argv[4], &n, &n);
	  // }
	  // else{

      v = FFLAS::fflas_new<Element>(n);

      Field::RandIter G(F);
      for(size_t j=0; j<(size_t)n; ++j)
              G.random(*(v+j));

      w = FFLAS::fflas_new<Element>(m);
      x = FFLAS::fflas_new<Element>(m);
      y = FFLAS::fflas_new<Element>(k);

      chrono.clear();
      if (i) chrono.start();
      if (p){
	      FFLAS::CuttingStrategy meth;
	      switch (p){
		  case 1: meth = FFLAS::BLOCK_THREADS;break;
		  case 2: meth = FFLAS::TWO_D;break;
		  case 3: meth = FFLAS::TWO_D_ADAPT;break;
		  case 4: meth = FFLAS::THREE_D_INPLACE;break;
		  case 5: meth = FFLAS::THREE_D;break;
		  case 6: meth = FFLAS::THREE_D_ADAPT;break;
		  default: meth = FFLAS::BLOCK_THREADS;break;
	      }
	      FFLAS::MMHelper<Field,FFLAS::MMHelperAlgo::Winograd,
			      typename FFLAS::FieldTraits<Field>::value,
			      FFLAS::ParSeqHelper::Parallel>
		      WH (F, nbw, FFLAS::ParSeqHelper::Parallel(t, meth));
	      PAR_REGION{
		      FFLAS::fgemm (F, FFLAS::FflasNoTrans, FFLAS::FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n,WH);
	      }
      }else{
	      FFLAS::MMHelper<Field,FFLAS::MMHelperAlgo::Winograd>//,
			  //typename FFLAS::FieldTraits<Field>::value,
			  //FFLAS::ParSeqHelper::Parallel>
	      WH (F, nbw);

	      FFLAS::fgemm (F, FFLAS::FflasNoTrans, FFLAS::FflasNoTrans, m,n,k, F.one, A, k, B, n, F.zero, C,n,WH);
      }
      if (i) {chrono.stop(); time+=chrono.realtime();}

      freidvals.clear();
      freidvals.start();
      FFLAS::fgemv(F, FFLAS::FflasNoTrans,m,n, F.one,
                   C, n, v, 1, F.zero, w, 1);
      FFLAS::fgemv(F, FFLAS::FflasNoTrans, k,n, F.one,
                   B, n, v, 1, F.zero, y, 1);
      FFLAS::fgemv(F, FFLAS::FflasNoTrans, m,k, F.one,
                   A, k, y, 1, F.zero, x, 1);
      bool pass=true;
      for(size_t j=0; j<(size_t)m; ++j) pass &= ( *(w+j) == *(x+j) );
      freidvals.stop();
      timev+=freidvals.usertime();
      if (!pass)
	      std::cerr<<"FAILED"<<std::endl;
	  //std::cerr << *A << ' ' << *B << ' ' << *C << ' '<< pass << std::endl;
  }
  FFLAS::fflas_delete( A);
  FFLAS::fflas_delete( B);
  FFLAS::fflas_delete( C);

  std::cerr<<"m: "<<m<<" k: "<<k<<" n: "<<n<<" q: "<<q<<" time: "<<time/(double)iter<<" Gfops: "<<(2.*double(m)/1000.*double(n)/1000.*double(k)/1000.0/*-m/1000.*n/1000.*/)/time*double(iter)<<std::endl;

      //std::cerr<<"Freidvals vtime: "<<timev/(double)iter<<std::endl;

  return 0;
}

<|endoftext|>


<commit_before>#include <QtCore/QFile>

#include <QtTest/QtTest>

#include <QMimeDatabase>

#include "../../src/qmimedatabase_p.h"

class tst_QMimeType : public QObject
{
    Q_OBJECT

public:
    tst_QMimeType();
    ~tst_QMimeType();

private Q_SLOTS:
    void initTestCase();

    void findByName_data();
    void findByName();

    void findByData_data();
    void findByData();

    void findByFile_data();
    void findByFile();

private:
    QMimeDatabase database;
    QMimeDatabaseBuilder databaseBuilder;
};

tst_QMimeType::tst_QMimeType() :
        database(),
        databaseBuilder()
{
}

tst_QMimeType::~tst_QMimeType()
{
}

void tst_QMimeType::initTestCase()
{
    QString errorMessage;
    QVERIFY(databaseBuilder.addMimeTypes(SRCDIR "../../freedesktop.org.xml", &errorMessage));
    QVERIFY(errorMessage.isEmpty());
}

void tst_QMimeType::findByName_data()
{
    QTest::addColumn<QString>("filePath");
    QTest::addColumn<QString>("mimeType");
    QTest::addColumn<QString>("xFail");

    QString prefix = QLatin1String(SRCDIR "testfiles/");

    QFile f(prefix + QLatin1String("list"));
    QVERIFY(f.open(QIODevice::ReadOnly));

    QByteArray line(1024, Qt::Uninitialized);

    while (!f.atEnd()) {
        int len = f.readLine(line.data(), 1023);

        if (len <= 2 || line.at(0) == '#')
            continue;

        QString string = QString::fromLatin1(line.constData(), len - 1).trimmed();
        QStringList list = string.split(QLatin1Char(' '), QString::SkipEmptyParts);
        QVERIFY(list.size() >= 2);

        QString filePath = list.at(0);
        QString mimeType = list.at(1);
        QString xFail;
        if (list.size() == 3)
            xFail = list.at(2);

        QTest::newRow(filePath.toLatin1().constData()) << prefix + filePath << mimeType << xFail;
    }
}

void tst_QMimeType::findByName()
{
    QFETCH(QString, filePath);
    QFETCH(QString, mimeType);
    QFETCH(QString, xFail);

    if (xFail.length() >= 1 && xFail.at(0) == QLatin1Char('x'))
        QEXPECT_FAIL("", "Expected to fail", Continue);

    QCOMPARE(database.findByName(filePath).type(), mimeType);
}

void tst_QMimeType::findByData_data()
{
    findByName_data();
}

void tst_QMimeType::findByData()
{
    QFETCH(QString, filePath);
    QFETCH(QString, mimeType);
    QFETCH(QString, xFail);

    QFile f(filePath);
    QVERIFY(f.open(QIODevice::ReadOnly));
    QByteArray data = f.readAll();

    if (xFail.length() >= 2 && xFail.at(1) == QLatin1Char('x'))
        QEXPECT_FAIL("", "Expected to fail", Continue);

    QCOMPARE(database.findByData(data).type(), mimeType);
}

void tst_QMimeType::findByFile_data()
{
    findByName_data();
}

void tst_QMimeType::findByFile()
{
    QFETCH(QString, filePath);
    QFETCH(QString, mimeType);
    QFETCH(QString, xFail);

    if (xFail.length() >= 3 && xFail.at(2) == QLatin1Char('x'))
        QEXPECT_FAIL("", "Expected to fail", Continue);

    QCOMPARE(database.findByFile(QFileInfo(filePath)).type(), mimeType);
}

QTEST_APPLESS_MAIN(tst_QMimeType)

#include "tst_qmimetype.moc"
<commit_msg>Make test output more silent by not using QEXPECT_FAIL<commit_after>#include <QtCore/QFile>

#include <QtTest/QtTest>

#include <QMimeDatabase>

#include "../../src/qmimedatabase_p.h"

class tst_QMimeType : public QObject
{
    Q_OBJECT

public:
    tst_QMimeType();
    ~tst_QMimeType();

private Q_SLOTS:
    void initTestCase();

    void findByName_data();
    void findByName();

    void findByData_data();
    void findByData();

    void findByFile_data();
    void findByFile();

private:
    QMimeDatabase database;
    QMimeDatabaseBuilder databaseBuilder;
};

tst_QMimeType::tst_QMimeType() :
        database(),
        databaseBuilder()
{
}

tst_QMimeType::~tst_QMimeType()
{
}

void tst_QMimeType::initTestCase()
{
    QString errorMessage;
    QVERIFY(databaseBuilder.addMimeTypes(SRCDIR "../../freedesktop.org.xml", &errorMessage));
    QVERIFY(errorMessage.isEmpty());
}

void tst_QMimeType::findByName_data()
{
    QTest::addColumn<QString>("filePath");
    QTest::addColumn<QString>("mimeType");
    QTest::addColumn<QString>("xFail");

    QString prefix = QLatin1String(SRCDIR "testfiles/");

    QFile f(prefix + QLatin1String("list"));
    QVERIFY(f.open(QIODevice::ReadOnly));

    QByteArray line(1024, Qt::Uninitialized);

    while (!f.atEnd()) {
        int len = f.readLine(line.data(), 1023);

        if (len <= 2 || line.at(0) == '#')
            continue;

        QString string = QString::fromLatin1(line.constData(), len - 1).trimmed();
        QStringList list = string.split(QLatin1Char(' '), QString::SkipEmptyParts);
        QVERIFY(list.size() >= 2);

        QString filePath = list.at(0);
        QString mimeType = list.at(1);
        QString xFail;
        if (list.size() == 3)
            xFail = list.at(2);

        QTest::newRow(filePath.toLatin1().constData()) << prefix + filePath << mimeType << xFail;
    }
}

void tst_QMimeType::findByName()
{
    QFETCH(QString, filePath);
    QFETCH(QString, mimeType);
    QFETCH(QString, xFail);

    const QString resultMimeType = database.findByName(filePath).type();
    if (xFail.length() >= 1 && xFail.at(0) == QLatin1Char('x'))
        // Expected to fail
        QVERIFY2(resultMimeType != mimeType, qPrintable(resultMimeType));
    else
        QCOMPARE(resultMimeType, mimeType);
}

void tst_QMimeType::findByData_data()
{
    findByName_data();
}

void tst_QMimeType::findByData()
{
    QFETCH(QString, filePath);
    QFETCH(QString, mimeType);
    QFETCH(QString, xFail);

    QFile f(filePath);
    QVERIFY(f.open(QIODevice::ReadOnly));
    QByteArray data = f.readAll();

    const QString resultMimeType = database.findByData(data).type();
    if (xFail.length() >= 2 && xFail.at(1) == QLatin1Char('x'))
        // Expected to fail
        QVERIFY2(resultMimeType != mimeType, qPrintable(resultMimeType));
    else
        QCOMPARE(resultMimeType, mimeType);
}

void tst_QMimeType::findByFile_data()
{
    findByName_data();
}

void tst_QMimeType::findByFile()
{
    QFETCH(QString, filePath);
    QFETCH(QString, mimeType);
    QFETCH(QString, xFail);

    const QString resultMimeType = database.findByFile(QFileInfo(filePath)).type();
    if (xFail.length() >= 3 && xFail.at(2) == QLatin1Char('x'))
        // Expected to fail
        QVERIFY2(resultMimeType != mimeType, qPrintable(resultMimeType));
    else
        QCOMPARE(resultMimeType, mimeType);
}

QTEST_APPLESS_MAIN(tst_QMimeType)

#include "tst_qmimetype.moc"
<|endoftext|>


<commit_before>#include "sf_client.h"
#include <cpprest/http_client.h>

#define TRACE if (tracing) {                    \
    cerr << "\n|trace|" << __FILE__ << ":" << __LINE__ << "|\n"; }

using namespace web;
using namespace http;
using namespace std;

sf_client::sf_client(std::string apikey)
  : sf_client(move(apikey), "https://api.stockfighter.io")
{}

sf_client::sf_client(string apikey, string host)
  : m_apikey(move(apikey)), m_client(make_unique<web::http::client::http_client>(host))
{
  tracing = false;
}

sf_client::~sf_client() {}

optional<unit> sf_client::api_heartbeat() {
  TRACE;
  optional<unit> ret;

  auto res = m_client->request("GET", "/ob/api/heartbeat").get();
  auto doc = res.extract_json().get();
  auto& obj = doc.as_object();
  ret.ok = obj["ok"].as_bool() ? OK : ERROR;
  switch (ret.ok) {
  case OK: break;
  case ERROR:
    ret.err = obj["error"].as_string();
    break;
  }

  TRACE;
  return ret;
}

optional<symbolslist_t> sf_client::venue_stocks(const std::string& venue) {
  TRACE;
  optional<symbolslist_t> ret;

  auto res = m_client->request("GET", "/ob/api/venues/"+venue+"/stocks").get();
  auto doc = res.extract_json().get();
  auto& obj = doc.as_object();
  ret.ok = obj["ok"].as_bool() ? OK : ERROR;
  switch (ret.ok) {
  case ERROR:
    ret.err = obj["error"].as_string();
    break;
  case OK: {
    auto& arr = obj["symbols"].as_array();
    for (auto&& sym : arr) {
      auto& symobj = sym.as_object();
      ret.data.symbols.push_back(symboldef_t{
	  symobj["symbol"].as_string(),
	    symobj["name"].as_string()
	    });
    }
    break;
  }
  }

  TRACE;
  return ret;
}

void parse_into(const json::array& arr, std::vector<request_t>& reqs) {
  for (auto&& req : arr) {
    auto& reqobj = req.as_object();
    reqs.push_back(request_t{
	reqobj.at("price").as_number().to_uint64(),
	  reqobj.at("qty").as_number().to_uint64()});
  }
}

optional<orderbook_t> sf_client::orderbook_for_venue(const std::string& venue, const std::string& stock) {
  TRACE;
  optional<orderbook_t> ret;

  auto res = m_client->request("GET", "/ob/api/venues/"+venue+"/stocks/"+stock).get();
  auto doc = res.extract_json().get();

  auto& obj = doc.as_object();
  ret.ok = obj["ok"].as_bool() ? OK : ERROR;
  switch (ret.ok) {
  case ERROR:
    ret.err = obj["error"].as_string();
    break;
  case OK: {
    if (!obj["bids"].is_null()) parse_into(obj["bids"].as_array(), ret.data.bids);
    if (!obj["asks"].is_null()) parse_into(obj["asks"].as_array(), ret.data.asks);
    ret.data.timestamp = obj["ts"].as_string();
    break;
  }
  }

  TRACE;
  return ret;
}

json::value order_to_json(const order_request_t& order) {
  std::vector<std::pair<std::string, json::value>> fields;
  fields.emplace_back("account", json::value::string(order.account));
  fields.emplace_back("venue", json::value::string(order.venue));
  fields.emplace_back("stock", json::value::string(order.symbol));
  fields.emplace_back("price", json::value::number(order.req.price));
  fields.emplace_back("qty", json::value::number(order.req.qty));
  fields.emplace_back("direction", json::value::string(order.direction == BUY ? "buy" : "sell"));
  fields.emplace_back("orderType", json::value::string(stringify(order.type)));
  return json::value::object(move(fields));
}

template<class F>
vector<result_of_t<F(const json::value&)>> map(const json::value& v, F f) {
  using v_t = vector<result_of_t<F(const json::value&)>>;
  v_t ret;

  if (v.is_null())
    return ret;

  for (auto&& e : v.as_array())
    ret.push_back(f(e));

  return ret;
}

// This is a parser based on return type deduction.
// I am not sure how I feel about this... but it does make for very elegant code.
struct parser {
  const json::value& val;

  parser at(size_t sz) const {
    return parser{val.at(sz)};
  }
  parser at(const std::string& key) const {
    return parser{val.at(key)};
  }

  explicit operator string() const {
    return val.as_string().c_str();
  }

  operator uint64_t() const {
    return val.as_number().to_uint64();
  }

  template<class T>
  operator vector<T>() const {
    vector<T> ret;
    if (val.is_null())
      return ret;
    for (auto&& e : val.as_array())
      ret.push_back(parser{e});

    return ret;
  }

  operator ok_t() const {
    return val.as_bool() ? OK : ERROR;
  }

  operator fill_t() const {
    fill_t ret;
    ret.req.price = at("price");
    ret.req.qty = at("qty");
    ret.timestamp = string(at("ts"));
    return ret;
  }

  operator direction_t() const {
    return val.as_string() == "buy" ? BUY : SELL;
  }

  operator open_t() const {
    return val.as_bool() ? OPEN : CLOSED;
  }

  operator order_response_t() const {
    order_response_t ret;
    ret.id = at("id");
    ret.status = *this;
    return ret;
  }

  operator order_status_t() const {
    order_status_t ret;
    ret.original_qty = at("originalQty");
    ret.outstanding_qty = at("qty");
    ret.filled_qty = at("totalFilled");
    ret.direction = at("direction");
    ret.open = at("open");
    ret.timestamp = string(at("ts"));

    // fills
    ret.fills = at("fills");

    return ret;
  }

  template<class T>
  operator optional<T>() const {
    optional<T> ret;
    ret.ok = at("ok");
    if (ret.ok == ERROR) {
      ret.err = string(at("error"));
      return ret;
    }

    ret.data = *this;
    return ret;
  }
};

optional<order_response_t> sf_client::post_order(const order_request_t& order) {
  TRACE;
  optional<order_response_t> ret;
  auto uri = "/ob/api/venues/"+order.venue+"/stocks/"+order.symbol+"/orders";

  http_request req("POST");
  req.set_request_uri(uri);
  req.headers().add("X-Starfighter-Authorization", m_apikey);
  req.set_body(order_to_json(order));

  auto res = m_client->request(req).get();
  auto doc = res.extract_json().get();

  TRACE;
  return parser{doc};
}

optional<order_response_t> sf_client::cancel_order(const std::string& venue,
                                                   const std::string& symbol,
                                                   uint64_t id) {
  TRACE;
  optional<order_response_t> ret;
  auto uri = "/ob/api/venues/"+venue+"/stocks/"+symbol+"/orders/"+to_string(id);

  cerr << "uri:" << uri << endl;

  http_request req("DELETE");
  req.set_request_uri(uri);
  req.headers().add("X-Starfighter-Authorization", m_apikey);

  auto res = m_client->request(req).get();
  auto doc = res.extract_json().get();

  TRACE;
  return parser{doc};
}

vector<string> parse_stringarr(const json::value& v) {
  vector<string> ret;
  for (auto&& e : v.as_array()) {
    ret.push_back(e.as_string());
  }
  return ret;
}

optional<gm_start_level_t> sf_client::start_level(const std::string& level) {
  TRACE;
  optional<gm_start_level_t> ret;

  auto uri = "/gm/levels/" + level;

  http_request req("POST");
  req.set_request_uri(uri);
  req.headers().add("X-Starfighter-Authorization", m_apikey);

  auto res = m_client->request(req).get();
  auto doc = res.extract_json().get();

  auto& obj = doc.as_object();
  ret.ok = obj["ok"].as_bool() ? OK : ERROR;

  switch (ret.ok) {
  case ERROR:
    ret.err = obj["error"].as_string();
    break;
  case OK: {
    ret->account = obj["account"].as_string();
    ret->instance = obj["instanceId"].as_number().to_uint64();
    // TODO instructions
    ret->seconds_per_day = obj["secondsPerTradingDay"].as_number().to_uint64();
    ret->tickers = parse_stringarr(obj["tickers"]);
    ret->venues = parse_stringarr(obj["venues"]);
    break;
  }
  }

  TRACE;
  return ret;
}

optional<gm_start_level_t> sf_client::restart_level(uint64_t id) {
  TRACE;
  optional<gm_start_level_t> ret;

  auto uri = "/gm/instances/" + to_string(id) + "/restart";

  http_request req("POST");
  req.set_request_uri(uri);
  req.headers().add("X-Starfighter-Authorization", m_apikey);

  auto res = m_client->request(req).get();
  auto doc = res.extract_json().get();

  auto& obj = doc.as_object();
  ret.ok = obj["ok"].as_bool() ? OK : ERROR;

  switch (ret.ok) {
  case ERROR:
    ret.err = obj["error"].as_string();
    break;
  case OK: {
    ret->account = obj["account"].as_string();
    ret->instance = obj["instanceId"].as_number().to_uint64();
    // TODO instructions
    ret->seconds_per_day = obj["secondsPerTradingDay"].as_number().to_uint64();
    ret->tickers = parse_stringarr(obj["tickers"]);
    ret->venues = parse_stringarr(obj["venues"]);
    break;
  }
  }

  TRACE;
  return ret;
}
<commit_msg>Refactoring more into rval parser<commit_after>#include "sf_client.h"
#include <cpprest/http_client.h>

#define TRACE if (tracing) {                    \
    cerr << "\n|trace|" << __FILE__ << ":" << __LINE__ << "|\n"; }

using namespace web;
using namespace http;
using namespace std;

sf_client::sf_client(std::string apikey)
  : sf_client(move(apikey), "https://api.stockfighter.io")
{}

sf_client::sf_client(string apikey, string host)
  : m_apikey(move(apikey)), m_client(make_unique<web::http::client::http_client>(host))
{
  tracing = false;
}

sf_client::~sf_client() {}

// This is a parser based on return type deduction.
// I am not sure how I feel about this... but it does make for very elegant code.
struct parser {
  const json::value& val;

  parser at(size_t sz) const {
    return parser{val.at(sz)};
  }
  parser at(const std::string& key) const {
    return parser{val.at(key)};
  }

  explicit operator string() const {
    return val.as_string().c_str();
  }

  operator unit() const { return unit(); }

  operator uint64_t() const {
    return val.as_number().to_uint64();
  }

  operator vector<string>() const {
    vector<string> ret;
    if (val.is_null())
      return ret;
    for (auto&& e : val.as_array())
      ret.push_back(string(parser{e}));

    return ret;
  }

  template<class T>
  operator vector<T>() const {
    vector<T> ret;
    if (val.is_null())
      return ret;
    for (auto&& e : val.as_array())
      ret.push_back(parser{e});

    return ret;
  }

  operator ok_t() const {
    return val.as_bool() ? OK : ERROR;
  }

  operator fill_t() const {
    fill_t ret;
    ret.req.price = at("price");
    ret.req.qty = at("qty");
    ret.timestamp = string(at("ts"));
    return ret;
  }

  operator direction_t() const {
    return val.as_string() == "buy" ? BUY : SELL;
  }

  operator open_t() const {
    return val.as_bool() ? OPEN : CLOSED;
  }

  operator order_response_t() const {
    order_response_t ret;
    ret.id = at("id");
    ret.status = *this;
    return ret;
  }

  operator order_status_t() const {
    order_status_t ret;
    ret.original_qty = at("originalQty");
    ret.outstanding_qty = at("qty");
    ret.filled_qty = at("totalFilled");
    ret.direction = at("direction");
    ret.open = at("open");
    ret.timestamp = string(at("ts"));

    // fills
    ret.fills = at("fills");

    return ret;
  }

  template<class T>
  operator optional<T>() const {
    optional<T> ret;
    ret.ok = at("ok");
    if (ret.ok == ERROR) {
      ret.err = string(at("error"));
      return ret;
    }

    ret.data = *this;
    return ret;
  }

  operator symboldef_t() const {
    symboldef_t ret;
    ret.symbol = string(at("symbol"));
    ret.name = string(at("name"));
    return ret;
  }

  operator symbolslist_t() const {
    symbolslist_t ret;
    ret.symbols = at("symbols");
    return ret;
  }

  operator gm_start_level_t() const {
    gm_start_level_t ret;
    ret.account = string(at("account"));
    ret.instance = at("instanceId");
    // TODO instructions
    ret.seconds_per_day = at("secondsPerTradingDay");
    ret.tickers = at("tickers");
    ret.venues = at("venues");
    return ret;
  }
};

optional<unit> sf_client::api_heartbeat() {
  TRACE;
  optional<unit> ret;

  auto res = m_client->request("GET", "/ob/api/heartbeat").get();
  auto doc = res.extract_json().get();
  TRACE;
  return parser{doc};
}

optional<symbolslist_t> sf_client::venue_stocks(const std::string& venue) {
  TRACE;
  optional<symbolslist_t> ret;

  auto res = m_client->request("GET", "/ob/api/venues/"+venue+"/stocks").get();
  auto doc = res.extract_json().get();

  TRACE;
  return parser{doc};
}

void parse_into(const json::array& arr, std::vector<request_t>& reqs) {
  for (auto&& req : arr) {
    auto& reqobj = req.as_object();
    reqs.push_back(request_t{
	reqobj.at("price").as_number().to_uint64(),
	  reqobj.at("qty").as_number().to_uint64()});
  }
}

optional<orderbook_t> sf_client::orderbook_for_venue(const std::string& venue, const std::string& stock) {
  TRACE;
  optional<orderbook_t> ret;

  auto res = m_client->request("GET", "/ob/api/venues/"+venue+"/stocks/"+stock).get();
  auto doc = res.extract_json().get();

  auto& obj = doc.as_object();
  ret.ok = obj["ok"].as_bool() ? OK : ERROR;
  switch (ret.ok) {
  case ERROR:
    ret.err = obj["error"].as_string();
    break;
  case OK: {
    if (!obj["bids"].is_null()) parse_into(obj["bids"].as_array(), ret.data.bids);
    if (!obj["asks"].is_null()) parse_into(obj["asks"].as_array(), ret.data.asks);
    ret.data.timestamp = obj["ts"].as_string();
    break;
  }
  }

  TRACE;
  return ret;
}

json::value order_to_json(const order_request_t& order) {
  std::vector<std::pair<std::string, json::value>> fields;
  fields.emplace_back("account", json::value::string(order.account));
  fields.emplace_back("venue", json::value::string(order.venue));
  fields.emplace_back("stock", json::value::string(order.symbol));
  fields.emplace_back("price", json::value::number(order.req.price));
  fields.emplace_back("qty", json::value::number(order.req.qty));
  fields.emplace_back("direction", json::value::string(order.direction == BUY ? "buy" : "sell"));
  fields.emplace_back("orderType", json::value::string(stringify(order.type)));
  return json::value::object(move(fields));
}

template<class F>
vector<result_of_t<F(const json::value&)>> map(const json::value& v, F f) {
  using v_t = vector<result_of_t<F(const json::value&)>>;
  v_t ret;

  if (v.is_null())
    return ret;

  for (auto&& e : v.as_array())
    ret.push_back(f(e));

  return ret;
}

optional<order_response_t> sf_client::post_order(const order_request_t& order) {
  TRACE;
  optional<order_response_t> ret;
  auto uri = "/ob/api/venues/"+order.venue+"/stocks/"+order.symbol+"/orders";

  http_request req("POST");
  req.set_request_uri(uri);
  req.headers().add("X-Starfighter-Authorization", m_apikey);
  req.set_body(order_to_json(order));

  auto res = m_client->request(req).get();
  auto doc = res.extract_json().get();

  TRACE;
  return parser{doc};
}

optional<order_response_t> sf_client::cancel_order(const std::string& venue,
                                                   const std::string& symbol,
                                                   uint64_t id) {
  TRACE;
  optional<order_response_t> ret;
  auto uri = "/ob/api/venues/"+venue+"/stocks/"+symbol+"/orders/"+to_string(id);

  cerr << "uri:" << uri << endl;

  http_request req("DELETE");
  req.set_request_uri(uri);
  req.headers().add("X-Starfighter-Authorization", m_apikey);

  auto res = m_client->request(req).get();
  auto doc = res.extract_json().get();

  TRACE;
  return parser{doc};
}

optional<gm_start_level_t> sf_client::start_level(const std::string& level) {
  TRACE;
  optional<gm_start_level_t> ret;

  auto uri = "/gm/levels/" + level;

  http_request req("POST");
  req.set_request_uri(uri);
  req.headers().add("X-Starfighter-Authorization", m_apikey);

  auto res = m_client->request(req).get();
  auto doc = res.extract_json().get();

  TRACE;
  return parser{doc};
}

optional<gm_start_level_t> sf_client::restart_level(uint64_t id) {
  TRACE;
  optional<gm_start_level_t> ret;

  auto uri = "/gm/instances/" + to_string(id) + "/restart";

  http_request req("POST");
  req.set_request_uri(uri);
  req.headers().add("X-Starfighter-Authorization", m_apikey);

  auto res = m_client->request(req).get();
  auto doc = res.extract_json().get();

  TRACE;
  return parser{doc};
}
<|endoftext|>


<commit_before>/*
 @ Kingsley Chen
*/

#include "kbase/files/file_path.h"

#include <cassert>
#include <cstdlib>

#include <algorithm>
#include <functional>
#include <stdexcept>

#include "kbase/strings/string_util.h"

namespace kbase {

typedef FilePath::PathChar PathChar;
typedef FilePath::PathString PathString;

const FilePath::PathChar FilePath::kSeparators[] = L"\\/";
const size_t FilePath::kSeparatorsLength = _countof(FilePath::kSeparators);
const FilePath::PathChar FilePath::kCurrentDir[] = L".";
const FilePath::PathChar FilePath::kParentDir[] = L"..";
const FilePath::PathChar FilePath::kExtensionSeparator = L'.';
const FilePath::PathChar FilePath::kStringTerminator = L'\0';

namespace {

// If the |path| contains a drive letter specification, returns the position of the
// last character of the specification; otherwise, return npos.
PathString::size_type FindDriveLetter(const PathString& path)
{
    if (path.length() >= 2 && path[1] == L':' &&
        ((path[0] >= L'A' && path[0] <= L'Z') ||
         (path[0] >= L'a' && path[0] <= L'z'))) {
        return 1;
    }

    return PathString::npos;
}

inline bool EqualPathString(const PathString& x, const PathString& y)
{
    return !kbase::SysStringCompareCaseInsensitive(x, y);
}

// This function adheres the equality stipulated for two FilePath objects:
// They can differ in the case, which is permitted by Windows.
bool EqualDriveLetterCaseInsensitive(const PathString& x, const PathString& y)
{
    auto letter_pos_x = FindDriveLetter(x);
    auto letter_pos_y = FindDriveLetter(y);

    // if only one contains a drive letter, the comparison result is same as
    // x == y
    if (letter_pos_x == PathString::npos || letter_pos_y == PathString::npos) {
        return EqualPathString(x, y);
    }

    PathString&& letter_x = x.substr(0, letter_pos_x + 1);
    PathString&& letter_y = y.substr(0, letter_pos_y + 1);
    if (!EqualPathString(letter_x, letter_y)) {
        return false;
    }

    PathString&& rest_x = x.substr(letter_pos_x + 1);
    PathString&& rest_y = y.substr(letter_pos_y + 1);
    return EqualPathString(rest_x, rest_y);
}

}   // namespace

FilePath::FilePath()
{}

FilePath::FilePath(const FilePath& other)
 : path_(other.path_)
{}

FilePath::FilePath(const PathString& path)
 : path_(path)
{
    //TODO: what if path has someting after \0 ?
}

FilePath& FilePath::operator=(const FilePath& other)
{
    path_ = other.path_;
    return *this;
}

FilePath::~FilePath()
{}

bool operator==(const FilePath& lhs, const FilePath& rhs)
{
    return EqualDriveLetterCaseInsensitive(lhs.value(), rhs.value());
}

bool operator!=(const FilePath& lhs, const FilePath& rhs)
{
    return !EqualDriveLetterCaseInsensitive(lhs.value(), rhs.value());
}

bool operator<(const FilePath& lhs, const FilePath& rhs)
{
    return (kbase::SysStringCompareCaseInsensitive(lhs.value(), rhs.value()) < 0);
}

// static
bool FilePath::IsSeparator(PathChar ch)
{
    using std::placeholders::_1;
    using std::equal_to;

    return std::any_of(std::begin(kSeparators), std::end(kSeparators),
                       std::bind(equal_to<PathChar>(), ch, _1));
}

void FilePath::StripTrailingSeparatorsInternal()
{
    // start always points to the position one-offset past the leading separator
    PathString::size_type start = FindDriveLetter(path_) + 2;

    PathString::size_type last_stripped = PathString::npos;
    PathString::size_type pos = path_.length();
    for (; pos > start && IsSeparator(path_[pos-1]); --pos) {
        if (pos != start + 1 ||
            !IsSeparator(path_[start-1]) ||
            last_stripped != PathString::npos) {
            last_stripped = pos;
        } else {
            break;
        }
    }

    path_.resize(pos);
}

FilePath FilePath::StripTrailingSeparators() const
{
    FilePath new_path(path_);
    new_path.StripTrailingSeparatorsInternal();

    return new_path;
}

FilePath FilePath::DirName() const
{
    FilePath new_path(path_);
    new_path.StripTrailingSeparatorsInternal();

    auto letter = FindDriveLetter(new_path.path_);
    auto last_separator = new_path.path_.find_last_of(kSeparators, PathString::npos,
                                                      kSeparatorsLength - 1);

    // there might be a drive letter in the path
    if (last_separator == PathString::npos) {
        // in current dir
        new_path.path_.resize(letter + 1);
    } else if (last_separator == letter + 1) {
        // in root dir
        new_path.path_.resize(letter + 2);
    } else if (last_separator == letter + 2 &&
               IsSeparator(new_path.path_[letter+1])) {
        // preserves the leading double-separator
        new_path.path_.resize(letter + 3);
    } else {
        new_path.path_.resize(last_separator);
    }

    new_path.StripTrailingSeparatorsInternal();
    if (new_path.path_.empty()) {
        new_path.path_ = kCurrentDir;
    }

    return new_path;
}

FilePath FilePath::BaseName() const
{
    FilePath new_path(path_);
    new_path.StripTrailingSeparatorsInternal();

    auto letter = FindDriveLetter(new_path.path_);
    if (letter != PathString::npos) {
        new_path.path_.erase(0, letter + 1);
    }

    auto last_separator = new_path.path_.find_last_of(kSeparators, PathString::npos,
                                                      kSeparatorsLength - 1);
    if (last_separator != PathString::npos &&
        last_separator < new_path.path_.length() - 1) {
        new_path.path_.erase(0, last_separator + 1);
    }

    return new_path;
}

void FilePath::GetComponents(std::vector<PathString>* components) const
{
    assert(components);
    if (!components) {
        throw std::invalid_argument("components cannot be NULL!");
    }

    components->clear();

    if (path_.empty()) {
        return;
    }

    std::vector<PathString> parts;
    FilePath current(path_);
    FilePath base;

    auto AreAllSeparators = [](const PathString& path) -> bool {
        return std::all_of(path.cbegin(), path.cend(), FilePath::IsSeparator);
    };

    // main body
    while (current != current.DirName()) {
        base = current.BaseName();
        if (!AreAllSeparators(base.value())) {
            parts.push_back(base.value());
        }
        current = current.DirName();
    }

    // root
    base = current.BaseName();
    if (!base.empty() && base.value() != kCurrentDir) {
        parts.push_back(base.value());
    }

    // drive letter
    auto letter = FindDriveLetter(current.value());
    if (letter != PathString::npos) {
        parts.push_back(current.value().substr(0, letter + 1));
    }

    std::copy(parts.crbegin(), parts.crend(), std::back_inserter(*components));
}

void FilePath::Append(const PathString& components)
{
    const PathString* need_appended = &components;
    PathString without_null;

    PathString::size_type null_pos = need_appended->find(kStringTerminator);
    if (null_pos != PathString::npos) {
        without_null = components.substr(0, null_pos);
        need_appended = &without_null;
    }

    //TODO: assert(!IsPathAbsolute(*need_appended));

    // If appends to the current dir, just set the path as the components.
    if (path_ == kCurrentDir) {
        path_ = *need_appended;
        return;
    }

    StripTrailingSeparatorsInternal();

    // If the path is empty, that indicates current directory.
    // If the path component is empty, that indicates nothing to append.
    if (!need_appended->empty() && !path_.empty()) {
        // Don't append separator, if there is already one.
        if (!IsSeparator(path_[path_.length()-1])) {
            // Don't append separator, if the path is a drive letter,
            // which is a valid relative path.
            if (FindDriveLetter(path_) + 1 != path_.length()) {
                path_.append(1, kSeparators[0]);
            }
        }
    }

    path_.append(*need_appended);
}

void FilePath::Append(const FilePath& components)
{
    Append(components.value());
}

bool FilePath::AppendRelativePath(const FilePath& child, FilePath* path) const
{
    std::vector<PathString> current_components;
    std::vector<PathString> child_components;
    GetComponents(&current_components);
    child.GetComponents(&child_components);

    if (current_components.empty() ||
        current_components.size() >= child_components.size()) {
        return false;
    }

    auto current_iter = current_components.cbegin();
    auto child_iter = child_components.cbegin();
    for (; current_iter != current_components.cend(); ++current_iter, ++child_iter) {
        if (!EqualPathString(*current_iter, *child_iter)) {
            return false;
        }
    }

    if (path) {
        for (; child_iter != child_components.cend(); ++child_iter) {
            path->Append(*child_iter);
        }
    }

    return true;
}

}   // namespace kbase<commit_msg>file_path: 1.+ function IsParent 2.* checks null-terminator existence when constructs from a raw string<commit_after>/*
 @ Kingsley Chen
*/

#include "kbase/files/file_path.h"

#include <cassert>
#include <cstdlib>

#include <algorithm>
#include <functional>
#include <stdexcept>

#include "kbase/strings/string_util.h"

namespace kbase {

typedef FilePath::PathChar PathChar;
typedef FilePath::PathString PathString;

const FilePath::PathChar FilePath::kSeparators[] = L"\\/";
const size_t FilePath::kSeparatorsLength = _countof(FilePath::kSeparators);
const FilePath::PathChar FilePath::kCurrentDir[] = L".";
const FilePath::PathChar FilePath::kParentDir[] = L"..";
const FilePath::PathChar FilePath::kExtensionSeparator = L'.';
const FilePath::PathChar FilePath::kStringTerminator = L'\0';

namespace {

// If the |path| contains a drive letter specification, returns the position of the
// last character of the specification; otherwise, return npos.
PathString::size_type FindDriveLetter(const PathString& path)
{
    if (path.length() >= 2 && path[1] == L':' &&
        ((path[0] >= L'A' && path[0] <= L'Z') ||
         (path[0] >= L'a' && path[0] <= L'z'))) {
        return 1;
    }

    return PathString::npos;
}

inline bool EqualPathString(const PathString& x, const PathString& y)
{
    return !kbase::SysStringCompareCaseInsensitive(x, y);
}

// This function adheres the equality stipulated for two FilePath objects:
// They can differ in the case, which is permitted by Windows.
bool EqualDriveLetterCaseInsensitive(const PathString& x, const PathString& y)
{
    auto letter_pos_x = FindDriveLetter(x);
    auto letter_pos_y = FindDriveLetter(y);

    // if only one contains a drive letter, the comparison result is same as
    // x == y
    if (letter_pos_x == PathString::npos || letter_pos_y == PathString::npos) {
        return EqualPathString(x, y);
    }

    PathString&& letter_x = x.substr(0, letter_pos_x + 1);
    PathString&& letter_y = y.substr(0, letter_pos_y + 1);
    if (!EqualPathString(letter_x, letter_y)) {
        return false;
    }

    PathString&& rest_x = x.substr(letter_pos_x + 1);
    PathString&& rest_y = y.substr(letter_pos_y + 1);
    return EqualPathString(rest_x, rest_y);
}

}   // namespace

FilePath::FilePath()
{}

FilePath::FilePath(const FilePath& other)
 : path_(other.path_)
{}

FilePath::FilePath(const PathString& path)
 : path_(path)
{
    // The null-terminator '\0' indicates the end of a path.
    PathString::size_type null_pos = path_.find(kStringTerminator);
    if (null_pos != PathString::npos) {
        path_ = path_.substr(0, null_pos);
    }
}

FilePath& FilePath::operator=(const FilePath& other)
{
    path_ = other.path_;
    return *this;
}

FilePath::~FilePath()
{}

bool operator==(const FilePath& lhs, const FilePath& rhs)
{
    return EqualDriveLetterCaseInsensitive(lhs.value(), rhs.value());
}

bool operator!=(const FilePath& lhs, const FilePath& rhs)
{
    return !EqualDriveLetterCaseInsensitive(lhs.value(), rhs.value());
}

bool operator<(const FilePath& lhs, const FilePath& rhs)
{
    return (kbase::SysStringCompareCaseInsensitive(lhs.value(), rhs.value()) < 0);
}

// static
bool FilePath::IsSeparator(PathChar ch)
{
    using std::placeholders::_1;
    using std::equal_to;

    return std::any_of(std::begin(kSeparators), std::end(kSeparators),
                       std::bind(equal_to<PathChar>(), ch, _1));
}

void FilePath::StripTrailingSeparatorsInternal()
{
    // start always points to the position one-offset past the leading separator
    PathString::size_type start = FindDriveLetter(path_) + 2;

    PathString::size_type last_stripped = PathString::npos;
    PathString::size_type pos = path_.length();
    for (; pos > start && IsSeparator(path_[pos-1]); --pos) {
        if (pos != start + 1 ||
            !IsSeparator(path_[start-1]) ||
            last_stripped != PathString::npos) {
            last_stripped = pos;
        } else {
            break;
        }
    }

    path_.resize(pos);
}

FilePath FilePath::StripTrailingSeparators() const
{
    FilePath new_path(path_);
    new_path.StripTrailingSeparatorsInternal();

    return new_path;
}

FilePath FilePath::DirName() const
{
    FilePath new_path(path_);
    new_path.StripTrailingSeparatorsInternal();

    auto letter = FindDriveLetter(new_path.path_);
    auto last_separator = new_path.path_.find_last_of(kSeparators, PathString::npos,
                                                      kSeparatorsLength - 1);

    // there might be a drive letter in the path
    if (last_separator == PathString::npos) {
        // in current dir
        new_path.path_.resize(letter + 1);
    } else if (last_separator == letter + 1) {
        // in root dir
        new_path.path_.resize(letter + 2);
    } else if (last_separator == letter + 2 &&
               IsSeparator(new_path.path_[letter+1])) {
        // preserves the leading double-separator
        new_path.path_.resize(letter + 3);
    } else {
        new_path.path_.resize(last_separator);
    }

    new_path.StripTrailingSeparatorsInternal();
    if (new_path.path_.empty()) {
        new_path.path_ = kCurrentDir;
    }

    return new_path;
}

FilePath FilePath::BaseName() const
{
    FilePath new_path(path_);
    new_path.StripTrailingSeparatorsInternal();

    auto letter = FindDriveLetter(new_path.path_);
    if (letter != PathString::npos) {
        new_path.path_.erase(0, letter + 1);
    }

    auto last_separator = new_path.path_.find_last_of(kSeparators, PathString::npos,
                                                      kSeparatorsLength - 1);
    if (last_separator != PathString::npos &&
        last_separator < new_path.path_.length() - 1) {
        new_path.path_.erase(0, last_separator + 1);
    }

    return new_path;
}

void FilePath::GetComponents(std::vector<PathString>* components) const
{
    assert(components);
    if (!components) {
        throw std::invalid_argument("components cannot be NULL!");
    }

    components->clear();

    if (path_.empty()) {
        return;
    }

    std::vector<PathString> parts;
    FilePath current(path_);
    FilePath base;

    auto AreAllSeparators = [](const PathString& path) -> bool {
        return std::all_of(path.cbegin(), path.cend(), FilePath::IsSeparator);
    };

    // main body
    while (current != current.DirName()) {
        base = current.BaseName();
        if (!AreAllSeparators(base.value())) {
            parts.push_back(base.value());
        }
        current = current.DirName();
    }

    // root
    base = current.BaseName();
    if (!base.empty() && base.value() != kCurrentDir) {
        parts.push_back(base.value());
    }

    // drive letter
    auto letter = FindDriveLetter(current.value());
    if (letter != PathString::npos) {
        parts.push_back(current.value().substr(0, letter + 1));
    }

    std::copy(parts.crbegin(), parts.crend(), std::back_inserter(*components));
}

void FilePath::Append(const PathString& components)
{
    const PathString* need_appended = &components;
    PathString without_null;

    PathString::size_type null_pos = need_appended->find(kStringTerminator);
    if (null_pos != PathString::npos) {
        without_null = components.substr(0, null_pos);
        need_appended = &without_null;
    }

    //TODO: assert(!IsPathAbsolute(*need_appended));

    // If appends to the current dir, just set the path as the components.
    if (path_ == kCurrentDir) {
        path_ = *need_appended;
        return;
    }

    StripTrailingSeparatorsInternal();

    // If the path is empty, that indicates current directory.
    // If the path component is empty, that indicates nothing to append.
    if (!need_appended->empty() && !path_.empty()) {
        // Don't append separator, if there is already one.
        if (!IsSeparator(path_[path_.length()-1])) {
            // Don't append separator, if the path is a drive letter,
            // which is a valid relative path.
            if (FindDriveLetter(path_) + 1 != path_.length()) {
                path_.append(1, kSeparators[0]);
            }
        }
    }

    path_.append(*need_appended);
}

void FilePath::Append(const FilePath& components)
{
    Append(components.value());
}

bool FilePath::AppendRelativePath(const FilePath& child, FilePath* path) const
{
    std::vector<PathString> current_components;
    std::vector<PathString> child_components;
    GetComponents(&current_components);
    child.GetComponents(&child_components);

    if (current_components.empty() ||
        current_components.size() >= child_components.size()) {
        return false;
    }

    auto current_iter = current_components.cbegin();
    auto child_iter = child_components.cbegin();
    for (; current_iter != current_components.cend(); ++current_iter, ++child_iter) {
        if (!EqualPathString(*current_iter, *child_iter)) {
            return false;
        }
    }

    if (path) {
        for (; child_iter != child_components.cend(); ++child_iter) {
            path->Append(*child_iter);
        }
    }

    return true;
}

bool FilePath::IsParent(const FilePath& child) const
{
    return AppendRelativePath(child, nullptr);
}

}   // namespace kbase<|endoftext|>


<commit_before>/**
 * @file h5_pool.cpp
 * @brief implementation of #h5_pool_iface
 * @author Oleg Borschuk
 * @version 1.0
 * @date 2011-03-05
*/
#include <hdf5.h>
#include <stdio.h>
#include <iomanip>

#include "h5_pool.h"
#include "h5_helper.h"

using namespace std;
using namespace boost::python;

namespace blue_sky
{
  h5_pool::h5_pool (bs_type_ctor_param)
        : h5_pool_iface ()
    {
      init_all ();
      mute_flag = 0;

    }
  h5_pool::h5_pool (const h5_pool & /*src*/) : bs_refcounter ()
    {
      init_all ();
      mute_flag = 0;
    }

  herr_t
  h5_pool::it_group (hid_t g_id, const char *name, const H5L_info_t * /*info*/, void * m)
    {
      hsize_t dims_[10];
      int n_dims;
      hid_t dset;
      hid_t dspace;
      hid_t dtype;

      dset = H5Dopen (g_id, name);
      if (dset < 0)
        {
          // TODO: report error
          throw;
        }
      dspace = H5Dget_space (dset);
      dtype = H5Dget_type (dset);
      n_dims = H5Sget_simple_extent_dims (dspace, dims_, NULL);
      ((h5_pool *)m)->add_node (std::string (name), dset, dspace, dtype, n_dims, dims_);
      return 0;
    }

  template <class T> h5_pool::map_t::iterator
  h5_pool::add_node (const std::string &name, const hid_t dset, const hid_t dspace,
                     const hid_t dtype, const int n_dims, const T *dims)
    {
      pair_t p;
      //printf ("Add node");

      p.first = name;
      p.second.dset = dset;
      p.second.dspace = dspace;
      p.second.dtype = dtype;
      p.second.n_dims = n_dims;
      for (int i = 0; i < n_dims; ++i)
        {
          p.second.py_dims[i] = (npy_intp)dims[i];
          p.second.h5_dims[i] = (hsize_t)dims[i];
        }
      return h5_map.insert (p).first;
    }

  void
  h5_pool::fill_map ()
    {
      clear_map ();
      if (group_id <= 0)
        {
          // TODO: report error
          throw;
        }
      H5Literate (group_id, H5_INDEX_NAME, H5_ITER_NATIVE, NULL, &(h5_pool::it_group), this);

    }

  void
  h5_pool::close_node (h5_pair &p)
    {
      H5Dclose (p.dset);
      H5Sclose (p.dspace);
      H5Tclose (p.dtype);
    }

  void
  h5_pool::clear_map ()
    {
      map_t::iterator i, e;
      e = h5_map.end ();
      for (i = h5_map.begin (); i != e; ++i)
        {
          close_node (i->second);
        }
      h5_map.clear ();

    }
  void
  h5_pool::open_file (const std::string &fname_, const std::string &path_)
    {
      if (file_id)
        {
          close_file ();
        }
      if (file_exists (fname_))
        {
          htri_t ret = H5Fis_hdf5 (fname_.c_str ());
          if (ret > 0)
            {
              file_id = H5Fopen (fname_.c_str (), H5F_ACC_RDWR, H5P_DEFAULT);
              if (file_id < 0)
                {
                  // TODO: report error
                  throw;
                }
            }
          else
            {
              // TODO: report error
              throw;
            }
        }
      else
        // file dose not exist already, create it
        {
          file_id = H5Fcreate (fname_.c_str (), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
          if (file_id < 0)
            {
              // TODO: report error
              throw;
            }
        }
      fname = fname_;

      mute ();
      // create or open group
      group_id = H5Gopen (file_id, path_.c_str ());
      un_mute ();
      if (group_id < 0)
        {
          group_id = H5Gcreate (file_id, path_.c_str (), -1);
          if (group_id < 0)
            {
              // TODO: report error
              throw;
            }
        }
      path = path_;
      fill_map ();
    }

  void
  h5_pool::close_file ()
    {
      clear_map ();
      if (group_id > 0)
        {
          H5Gclose (group_id);
        }
      if (file_id > 0)
        {
          H5Fclose (file_id);
        }
      init_all ();
    }

  spv_float
  h5_pool::get_fp_data (const std::string &name)
    {
      map_t::iterator it;
      t_long n;
      spv_float a;

      if (group_id <= 0)
        {
          // TODO: report error
          throw;
        }
      it = h5_map.find (name);
      if (it == h5_map.end ())
        {
          // TODO: report error
          throw;
        }
      n = H5Sget_simple_extent_npoints (it->second.dspace);

      a = BS_KERNEL.create_object (v_float::bs_type ());
      a->resize (n);
      a->reshape (it->second.n_dims, it->second.py_dims);
      if (sizeof (t_float) == sizeof (float))
        {
          H5Dread (it->second.dset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*a)[0]);
        }
      else if (sizeof (t_float) == sizeof (double))
        {
          H5Dread (it->second.dset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*a)[0]);
        }
      else
        {
          //TODO: print error message
          throw;
        }
      return a;
    }

  spv_int
  h5_pool::get_i_data (const std::string &name)
    {
      map_t::iterator it;
      t_long n;
      spv_int a;

      if (group_id <= 0)
        {
          // TODO: report error
          throw;
        }
      it = h5_map.find (name);
      if (it == h5_map.end ())
        {
          // TODO: report error
          throw;
        }
      n = H5Sget_simple_extent_npoints (it->second.dspace);

      a = BS_KERNEL.create_object (v_int::bs_type ());
      a->resize (n);
      a->reshape (it->second.n_dims, it->second.py_dims);
      if (sizeof (t_int) == sizeof (int))
        {
          H5Dread (it->second.dset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*a)[0]);
        }
      else if (sizeof (t_int) == sizeof (long))
        {
          H5Dread (it->second.dset, H5T_NATIVE_LONG, H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*a)[0]);
        }
      else
        {
          //TODO: print error message
          throw;
        }
      return a;
    }

  int
  h5_pool::set_i_data (const std::string &name, spv_int data)
    {
      t_int ndims;
      const npy_intp *dims;
      map_t::iterator it, e;

      if (group_id <= 0)
        {
          // TODO: report error
          throw;
        }

      ndims = data->ndim ();
      dims = data->dims ();

      it = h5_map.find (name);
      if (it != h5_map.end ())
        {
          if (it->second.n_dims == ndims)
            {
              int flg = 0;
              for (int i = 0; i < ndims; ++i)
                {
                  if (it->second.py_dims[i] != dims[i])
                    {
                      flg = 1;
                      break;
                    }
                }
              if (!flg)
                {
                  //printf ("array OK\n");
                  if (sizeof (t_int) == sizeof (int))
                    {
                      H5Dwrite (it->second.dset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
                                H5P_DEFAULT, &(*data)[0]);
                    }
                  else if (sizeof (t_int) == sizeof (long))
                    {
                      H5Dwrite (it->second.dset, H5T_NATIVE_LONG, H5S_ALL, H5S_ALL,
                                H5P_DEFAULT, &(*data)[0]);
                    }
                  else
                    {
                      //TODO: print error message
                      throw;
                    }
                  return 0;
                }
            }
          // erase element
          H5Ldelete (group_id, it->first.c_str (), H5P_DEFAULT);
          close_node (it->second);
          h5_map.erase (it);
        }
      // create new
      {
        printf ("Create %s\n", name.c_str ());

        map_t::iterator new_it = add_node (name, 0, 0, 0, ndims, dims);

        new_it->second.dspace = H5Screate_simple (ndims, new_it->second.h5_dims, NULL);

        if (sizeof (t_int) == sizeof (int))
          {
            new_it->second.dtype = H5T_NATIVE_INT;
          }
        else if (sizeof (t_int) == sizeof (long))
          {
            new_it->second.dtype = H5T_NATIVE_LONG;
          }
        else
          {
            //TODO: print error message
            throw;
          }
        new_it->second.dset = H5Dcreate (group_id, name.c_str (),
                                         new_it->second.dtype,
                                         new_it->second.dspace,
                                         H5P_DEFAULT);
        H5Dwrite (new_it->second.dset, new_it->second.dtype,
                  H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*data)[0]);
      }
      return 0;
    }

  int
  h5_pool::set_fp_data (const std::string &name, spv_float data)
    {
      t_int ndims;
      const npy_intp *dims;
      map_t::iterator it, e;

      if (group_id <= 0)
        {
          // TODO: report error
          throw;
        }

      ndims = data->ndim ();
      dims = data->dims ();

      it = h5_map.find (name);
      if (it != h5_map.end ())
        {
          if (it->second.n_dims == ndims)
            {
              int flg = 0;
              for (int i = 0; i < ndims; ++i)
                {
                  if (it->second.py_dims[i] != dims[i])
                    {
                      flg = 1;
                      break;
                    }
                }
              if (!flg)
                {
                  //printf ("array OK\n");
                  if (sizeof (t_float) == sizeof (float))
                    {
                      H5Dwrite (it->second.dset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL,
                                H5P_DEFAULT, &(*data)[0]);
                    }
                  else if (sizeof (t_float) == sizeof (double))
                    {
                      H5Dwrite (it->second.dset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL,
                                H5P_DEFAULT, &(*data)[0]);
                    }
                  else
                    {
                      //TODO: print error message
                      throw;
                    }
                  return 0;
                }
            }
          // erase element
          H5Ldelete (group_id, it->first.c_str (), H5P_DEFAULT);
          close_node (it->second);
          h5_map.erase (it);
        }
      // create new
      {
        printf ("Create %s\n", name.c_str ());

        map_t::iterator new_it = add_node (name, 0, 0, 0, ndims, dims);

        new_it->second.dspace = H5Screate_simple (ndims, new_it->second.h5_dims, NULL);

        if (sizeof (t_float) == sizeof (float))
          {
            new_it->second.dtype = H5T_NATIVE_FLOAT;
          }
        else if (sizeof (t_float) == sizeof (double))
          {
            new_it->second.dtype = H5T_NATIVE_DOUBLE;
          }
        else
          {
            //TODO: print error message
            throw;
          }
        new_it->second.dset = H5Dcreate (group_id, name.c_str (),
                                         new_it->second.dtype,
                                         new_it->second.dspace,
                                         H5P_DEFAULT);
        H5Dwrite (new_it->second.dset, new_it->second.dtype,
                  H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*data)[0]);
      }
      return 0;
    }

  void
  h5_pool::mute ()
    {
      if (!mute_flag)
        {
          /* Save old error handler */
          H5Eget_auto2 (H5E_DEFAULT, &old_func, &old_client_data);

          /* Turn off error handling */
          H5Eset_auto2 (H5E_DEFAULT, NULL, NULL);

          mute_flag = 1;
        }
    }

  void
  h5_pool::un_mute ()
    {
      if (mute_flag)
        {
          /* Restore previous error handler */
          H5Eset_auto2 (H5E_DEFAULT, old_func, old_client_data);
          mute_flag = 0;
        }
    }

#ifdef BSPY_EXPORTING_PLUGIN
  std::string
  h5_pool::py_str () const
    {
      std::stringstream s;
      std::string ss;
      map_t::const_iterator i, e;
      H5T_class_t dt;

      e = h5_map.end ();
      s << "H5_pool: " << h5_map.size () << std::endl;
      s << "-----------------------------------------------------------\n";
      for (i = h5_map.begin (); i != e; ++i)
        {
          std::stringstream sdim;
          s << std::setw (15) <<i->first << "\t [";
          sdim  << i->second.py_dims[0];
          for (int j = 1; j < i->second.n_dims; ++j)
            sdim << ", " <<i->second.py_dims[j];
          s << std::setw (15) << sdim.str () << "]\t";
          dt =  H5Tget_class (i->second.dtype);
          if (dt == H5T_INTEGER)
            ss = "Integer ";
          else if (dt == H5T_FLOAT)
            ss = "Float ";
          else
            ss = "Unknown";

          s << std::setw (8) << ss << H5Tget_precision (i->second.dtype);
          s << std::endl;
        }
      s << "-----------------------------------------------------------\n";
      return s.str ();
    }
#endif //BSPY_EXPORTING_PLUGIN
/////////////////////////////////BS Register
/////////////////////////////////Stuff//////////////////////////

  BLUE_SKY_TYPE_STD_CREATE (h5_pool);
  BLUE_SKY_TYPE_STD_COPY (h5_pool);

  BLUE_SKY_TYPE_IMPL (h5_pool, h5_pool_iface, "h5_pool", "Array pool stored in hdf5 file", "Array pool stored in HDF5 file");
}  // blue_sky namespace
<commit_msg>fix bugs in h5_pool<commit_after>/**
 * @file h5_pool.cpp
 * @brief implementation of #h5_pool_iface
 * @author Oleg Borschuk
 * @version 1.0
 * @date 2011-03-05
*/
#include <hdf5.h>
#include <stdio.h>
#include <iomanip>

#include "h5_pool.h"
#include "h5_helper.h"

using namespace std;
using namespace boost::python;

namespace blue_sky
{
  h5_pool::h5_pool (bs_type_ctor_param)
        : h5_pool_iface ()
    {
      init_all ();
      mute_flag = 0;

    }
  h5_pool::h5_pool (const h5_pool & /*src*/) : bs_refcounter ()
    {
      init_all ();
      mute_flag = 0;
    }

  herr_t
  h5_pool::it_group (hid_t g_id, const char *name, const H5L_info_t * /*info*/, void * m)
    {
      hsize_t dims_[10];
      int n_dims;
      hid_t dset;
      hid_t dspace;
      hid_t dtype;

      dset = H5Dopen (g_id, name);
      if (dset < 0)
        {
          // TODO: report error
          throw;
        }
      dspace = H5Dget_space (dset);
      dtype = H5Dget_type (dset);
      n_dims = H5Sget_simple_extent_dims (dspace, dims_, NULL);
      ((h5_pool *)m)->add_node (std::string (name), dset, dspace, dtype, n_dims, dims_);
      return 0;
    }

  template <class T> h5_pool::map_t::iterator
  h5_pool::add_node (const std::string &name, const hid_t dset, const hid_t dspace,
                     const hid_t dtype, const int n_dims, const T *dims)
    {
      pair_t p;
      //printf ("Add node");

      p.first = name;
      p.second.dset = dset;
      p.second.dspace = dspace;
      p.second.dtype = dtype;
      p.second.n_dims = n_dims;
      for (int i = 0; i < n_dims; ++i)
        {
          p.second.py_dims[i] = (npy_intp)dims[i];
          p.second.h5_dims[i] = (hsize_t)dims[i];
        }
      return h5_map.insert (p).first;
    }

  void
  h5_pool::fill_map ()
    {
      clear_map ();
      if (group_id <= 0)
        {
          // TODO: report error
          throw;
        }
      H5Literate (group_id, H5_INDEX_NAME, H5_ITER_NATIVE, NULL, &(h5_pool::it_group), this);

    }

  void
  h5_pool::close_node (h5_pair &p)
    {
      H5Dclose (p.dset);
      H5Sclose (p.dspace);
      H5Tclose (p.dtype);
    }

  void
  h5_pool::clear_map ()
    {
      map_t::iterator i, e;
      e = h5_map.end ();
      for (i = h5_map.begin (); i != e; ++i)
        {
          close_node (i->second);
        }
      h5_map.clear ();

    }
  void
  h5_pool::open_file (const std::string &fname_, const std::string &path_)
    {
      if (file_id)
        {
          close_file ();
        }
      if (file_exists (fname_))
        {
          htri_t ret = H5Fis_hdf5 (fname_.c_str ());
          if (ret > 0)
            {
              file_id = H5Fopen (fname_.c_str (), H5F_ACC_RDWR, H5P_DEFAULT);
              if (file_id < 0)
                {
                  // TODO: report error
                  throw;
                }
            }
          else
            {
              file_id = H5Fcreate (fname_.c_str (), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
              if (file_id < 0)
                {
                  // TODO: report error
                  throw;
                }
            }
        }
      else
        // file dose not exist already, create it
        {
          file_id = H5Fcreate (fname_.c_str (), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
          if (file_id < 0)
            {
              // TODO: report error
              throw;
            }
        }
      fname = fname_;

      mute ();
      // create or open group
      group_id = H5Gopen (file_id, path_.c_str ());
      un_mute ();
      if (group_id < 0)
        {
          group_id = H5Gcreate (file_id, path_.c_str (), -1);
          if (group_id < 0)
            {
              // TODO: report error
              throw;
            }
        }
      path = path_;
      fill_map ();
    }

  void
  h5_pool::close_file ()
    {
      clear_map ();
      if (group_id > 0)
        {
          H5Gclose (group_id);
        }
      if (file_id > 0)
        {
          H5Fclose (file_id);
        }
      init_all ();
    }

  spv_float
  h5_pool::get_fp_data (const std::string &name)
    {
      map_t::iterator it;
      t_long n;
      spv_float a;

      if (group_id <= 0)
        {
          // TODO: report error
          return spv_float ();
        }
      it = h5_map.find (name);
      if (it == h5_map.end ())
        {
          // TODO: report error
          return spv_float ();
        }
      n = H5Sget_simple_extent_npoints (it->second.dspace);

      a = BS_KERNEL.create_object (v_float::bs_type ());
      a->resize (n);
      a->reshape (it->second.n_dims, it->second.py_dims);
      if (sizeof (t_float) == sizeof (float))
        {
          H5Dread (it->second.dset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*a)[0]);
        }
      else if (sizeof (t_float) == sizeof (double))
        {
          H5Dread (it->second.dset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*a)[0]);
        }
      else
        {
          //TODO: print error message
          return spv_float ();
        }
      return a;
    }

  spv_int
  h5_pool::get_i_data (const std::string &name)
    {
      map_t::iterator it;
      t_long n;
      spv_int a;

      if (group_id <= 0)
        {
          // TODO: report error
          return spv_int ();
        }
      it = h5_map.find (name);
      if (it == h5_map.end ())
        {
          // TODO: report error
          return spv_int ();
        }
      n = H5Sget_simple_extent_npoints (it->second.dspace);

      a = BS_KERNEL.create_object (v_int::bs_type ());
      a->resize (n);
      a->reshape (it->second.n_dims, it->second.py_dims);
      if (sizeof (t_int) == sizeof (int))
        {
          H5Dread (it->second.dset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*a)[0]);
        }
      else if (sizeof (t_int) == sizeof (long))
        {
          H5Dread (it->second.dset, H5T_NATIVE_LONG, H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*a)[0]);
        }
      else
        {
          //TODO: print error message
          return spv_int ();
        }
      return a;
    }

  int
  h5_pool::set_i_data (const std::string &name, spv_int data)
    {
      t_int ndims;
      const npy_intp *dims;
      map_t::iterator it, e;

      if (group_id <= 0)
        {
          // TODO: report error
          throw;
        }

      ndims = data->ndim ();
      dims = data->dims ();

      it = h5_map.find (name);
      if (it != h5_map.end ())
        {
          if (it->second.n_dims == ndims)
            {
              int flg = 0;
              for (int i = 0; i < ndims; ++i)
                {
                  if (it->second.py_dims[i] != dims[i])
                    {
                      flg = 1;
                      break;
                    }
                }
              if (!flg)
                {
                  //printf ("array OK\n");
                  if (sizeof (t_int) == sizeof (int))
                    {
                      H5Dwrite (it->second.dset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
                                H5P_DEFAULT, &(*data)[0]);
                    }
                  else if (sizeof (t_int) == sizeof (long))
                    {
                      H5Dwrite (it->second.dset, H5T_NATIVE_LONG, H5S_ALL, H5S_ALL,
                                H5P_DEFAULT, &(*data)[0]);
                    }
                  else
                    {
                      //TODO: print error message
                      throw;
                    }
                  return 0;
                }
            }
          // erase element
          H5Ldelete (group_id, it->first.c_str (), H5P_DEFAULT);
          close_node (it->second);
          h5_map.erase (it);
        }
      // create new
      {
        printf ("Create %s\n", name.c_str ());

        map_t::iterator new_it = add_node (name, 0, 0, 0, ndims, dims);

        new_it->second.dspace = H5Screate_simple (ndims, new_it->second.h5_dims, NULL);

        if (sizeof (t_int) == sizeof (int))
          {
            new_it->second.dtype = H5T_NATIVE_INT;
          }
        else if (sizeof (t_int) == sizeof (long))
          {
            new_it->second.dtype = H5T_NATIVE_LONG;
          }
        else
          {
            //TODO: print error message
            throw;
          }
        new_it->second.dset = H5Dcreate (group_id, name.c_str (),
                                         new_it->second.dtype,
                                         new_it->second.dspace,
                                         H5P_DEFAULT);
        H5Dwrite (new_it->second.dset, new_it->second.dtype,
                  H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*data)[0]);
      }
      return 0;
    }

  int
  h5_pool::set_fp_data (const std::string &name, spv_float data)
    {
      t_int ndims;
      const npy_intp *dims;
      map_t::iterator it, e;

      if (group_id <= 0)
        {
          // TODO: report error
          throw;
        }

      ndims = data->ndim ();
      dims = data->dims ();

      it = h5_map.find (name);
      if (it != h5_map.end ())
        {
          if (it->second.n_dims == ndims)
            {
              int flg = 0;
              for (int i = 0; i < ndims; ++i)
                {
                  if (it->second.py_dims[i] != dims[i])
                    {
                      flg = 1;
                      break;
                    }
                }
              if (!flg)
                {
                  //printf ("array OK\n");
                  if (sizeof (t_float) == sizeof (float))
                    {
                      H5Dwrite (it->second.dset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL,
                                H5P_DEFAULT, &(*data)[0]);
                    }
                  else if (sizeof (t_float) == sizeof (double))
                    {
                      H5Dwrite (it->second.dset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL,
                                H5P_DEFAULT, &(*data)[0]);
                    }
                  else
                    {
                      //TODO: print error message
                      throw;
                    }
                  return 0;
                }
            }
          // erase element
          H5Ldelete (group_id, it->first.c_str (), H5P_DEFAULT);
          close_node (it->second);
          h5_map.erase (it);
        }
      // create new
      {
        printf ("Create %s\n", name.c_str ());

        map_t::iterator new_it = add_node (name, 0, 0, 0, ndims, dims);

        new_it->second.dspace = H5Screate_simple (ndims, new_it->second.h5_dims, NULL);

        if (sizeof (t_float) == sizeof (float))
          {
            new_it->second.dtype = H5T_NATIVE_FLOAT;
          }
        else if (sizeof (t_float) == sizeof (double))
          {
            new_it->second.dtype = H5T_NATIVE_DOUBLE;
          }
        else
          {
            //TODO: print error message
            throw;
          }
        new_it->second.dset = H5Dcreate (group_id, name.c_str (),
                                         new_it->second.dtype,
                                         new_it->second.dspace,
                                         H5P_DEFAULT);
        H5Dwrite (new_it->second.dset, new_it->second.dtype,
                  H5S_ALL, H5S_ALL, H5P_DEFAULT, &(*data)[0]);
      }
      return 0;
    }

  void
  h5_pool::mute ()
    {
      if (!mute_flag)
        {
          /* Save old error handler */
          H5Eget_auto2 (H5E_DEFAULT, &old_func, &old_client_data);

          /* Turn off error handling */
          H5Eset_auto2 (H5E_DEFAULT, NULL, NULL);

          mute_flag = 1;
        }
    }

  void
  h5_pool::un_mute ()
    {
      if (mute_flag)
        {
          /* Restore previous error handler */
          H5Eset_auto2 (H5E_DEFAULT, old_func, old_client_data);
          mute_flag = 0;
        }
    }

#ifdef BSPY_EXPORTING_PLUGIN
  std::string
  h5_pool::py_str () const
    {
      std::stringstream s;
      std::string ss;
      map_t::const_iterator i, e;
      H5T_class_t dt;

      e = h5_map.end ();
      s << "H5_pool: " << h5_map.size () << std::endl;
      s << "-----------------------------------------------------------\n";
      for (i = h5_map.begin (); i != e; ++i)
        {
          std::stringstream sdim;
          s << std::setw (15) <<i->first << "\t [";
          sdim  << i->second.py_dims[0];
          for (int j = 1; j < i->second.n_dims; ++j)
            sdim << ", " <<i->second.py_dims[j];
          s << std::setw (15) << sdim.str () << "]\t";
          dt =  H5Tget_class (i->second.dtype);
          if (dt == H5T_INTEGER)
            ss = "Integer ";
          else if (dt == H5T_FLOAT)
            ss = "Float ";
          else
            ss = "Unknown";

          s << std::setw (8) << ss << H5Tget_precision (i->second.dtype);
          s << std::endl;
        }
      s << "-----------------------------------------------------------\n";
      return s.str ();
    }
#endif //BSPY_EXPORTING_PLUGIN
/////////////////////////////////BS Register
/////////////////////////////////Stuff//////////////////////////

  BLUE_SKY_TYPE_STD_CREATE (h5_pool);
  BLUE_SKY_TYPE_STD_COPY (h5_pool);

  BLUE_SKY_TYPE_IMPL (h5_pool, h5_pool_iface, "h5_pool", "Array pool stored in hdf5 file", "Array pool stored in HDF5 file");
}  // blue_sky namespace
<|endoftext|>