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

#include "ospray_environment.h"

OSPRayEnvironment::OSPRayEnvironment(int argc, char **argv) : dumpImg(false),
  rendererType("scivis"),
  imgSize( {
  1920,1080
}),
deviceType("default"),
baselineDir("baseline"),
failedDir("failed")

{
  ParsArgs(argc, argv);
  device = ospNewDevice(GetDeviceType().c_str());
  if(device == NULL) {
    std::cout << "Faild to init the ospray device"
              << std::endl << std::flush;
    std::exit(EXIT_FAILURE);
  }
  ospDeviceCommit(device);
  ospSetCurrentDevice(device);
}

void OSPRayEnvironment::ParsArgs(int argc, char **argv) {
  std::vector<std::string> testArgs;
  for(int idx=0; idx<argc; ++idx) {
    testArgs.push_back(argv[idx]);
  }
  for(int idx=0; idx < testArgs.size(); ++idx) {
    if (testArgs.at(idx) == "--help") {
      std::cout << "--help : display this help msg\n" <<
                "--dump-img : dump the rendered image to file\n"  <<
                "--imgsize-x=XX : change the length of an image\n" <<
                "--imgsize-y=XX : change the height of an image\n" <<
                "--device-type=XX : change the device type which is used by OSPRay\n" <<
                "--renderer-type=XX : change the renderer used for tests\n" <<
                "--baseline-dir=XX : Change the directory used for baseline images during tests\n";
      std::exit(EXIT_SUCCESS);
    } else if(testArgs.at(idx) == "--dump-img") {
      dumpImg = true;
    } else if (testArgs.at(idx).find("--renderer-type=") == 0) {
      rendererType = GetStrArgValue(&testArgs.at(idx));
    } else if (testArgs.at(idx).find("--imgsize-x=") == 0) {
      imgSize.x = GetNumArgValue(&testArgs.at(idx));
    } else if (testArgs.at(idx).find("--imgsize-y=") == 0) {
      imgSize.y = GetNumArgValue(&testArgs.at(idx));
    } else if (testArgs.at(idx).find("--device-type=") == 0) {
      deviceType = GetStrArgValue(&testArgs.at(idx));
    } else if (testArgs.at(idx).find("--baseline-dir=") == 0) {
      baselineDir = GetStrArgValue(&testArgs.at(idx));
    } else if (testArgs.at(idx).find("--failed-dir=") == 0) {
      failedDir = GetStrArgValue(&testArgs.at(idx));
    }
  }
}

int OSPRayEnvironment::GetNumArgValue(std::string *arg) const {
  int ret = 0;
  size_t valueStartPos = arg->find_first_of('=');
  if (valueStartPos != std::string::npos) {
    ret = std::stoi(arg->substr(valueStartPos + 1));
    if (ret <= 0) {
      std::cout << "Incorrect value specified for argument %s "
                << *arg << std::endl << std::flush;
    }
  }
  return ret;
}

std::string OSPRayEnvironment::GetStrArgValue(std::string *arg) const {
  std::string ret;
  size_t valueStartPos = arg->find_first_of('=');
  if (valueStartPos != std::string::npos) {
    ret = arg->substr(valueStartPos + 1);
  }
  return ret;
}

<commit_msg>load ispc device in runtime tests<commit_after>// ======================================================================== //
// Copyright 2017-2018 Intel Corporation                                    //
//                                                                          //
// Licensed under the Apache License, Version 2.0 (the "License");          //
// you may not use this file except in compliance with the License.         //
// You may obtain a copy of the License at                                  //
//                                                                          //
//     http://www.apache.org/licenses/LICENSE-2.0                           //
//                                                                          //
// Unless required by applicable law or agreed to in writing, software      //
// distributed under the License is distributed on an "AS IS" BASIS,        //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and      //
// limitations under the License.                                           //
// ======================================================================== //

#include "ospray_environment.h"

OSPRayEnvironment::OSPRayEnvironment(int argc, char **argv) : dumpImg(false),
  rendererType("scivis"),
  imgSize( {
  1920,1080
}),
deviceType("default"),
baselineDir("baseline"),
failedDir("failed")

{
  ParsArgs(argc, argv);
  ospLoadModule("ispc");
  device = ospNewDevice(GetDeviceType().c_str());
  if(device == NULL) {
    std::cout << "Faild to init the ospray device"
              << std::endl << std::flush;
    std::exit(EXIT_FAILURE);
  }
  ospDeviceCommit(device);
  ospSetCurrentDevice(device);
}

void OSPRayEnvironment::ParsArgs(int argc, char **argv) {
  std::vector<std::string> testArgs;
  for(int idx=0; idx<argc; ++idx) {
    testArgs.push_back(argv[idx]);
  }
  for(int idx=0; idx < testArgs.size(); ++idx) {
    if (testArgs.at(idx) == "--help") {
      std::cout << "--help : display this help msg\n" <<
                "--dump-img : dump the rendered image to file\n"  <<
                "--imgsize-x=XX : change the length of an image\n" <<
                "--imgsize-y=XX : change the height of an image\n" <<
                "--device-type=XX : change the device type which is used by OSPRay\n" <<
                "--renderer-type=XX : change the renderer used for tests\n" <<
                "--baseline-dir=XX : Change the directory used for baseline images during tests\n";
      std::exit(EXIT_SUCCESS);
    } else if(testArgs.at(idx) == "--dump-img") {
      dumpImg = true;
    } else if (testArgs.at(idx).find("--renderer-type=") == 0) {
      rendererType = GetStrArgValue(&testArgs.at(idx));
    } else if (testArgs.at(idx).find("--imgsize-x=") == 0) {
      imgSize.x = GetNumArgValue(&testArgs.at(idx));
    } else if (testArgs.at(idx).find("--imgsize-y=") == 0) {
      imgSize.y = GetNumArgValue(&testArgs.at(idx));
    } else if (testArgs.at(idx).find("--device-type=") == 0) {
      deviceType = GetStrArgValue(&testArgs.at(idx));
    } else if (testArgs.at(idx).find("--baseline-dir=") == 0) {
      baselineDir = GetStrArgValue(&testArgs.at(idx));
    } else if (testArgs.at(idx).find("--failed-dir=") == 0) {
      failedDir = GetStrArgValue(&testArgs.at(idx));
    }
  }
}

int OSPRayEnvironment::GetNumArgValue(std::string *arg) const {
  int ret = 0;
  size_t valueStartPos = arg->find_first_of('=');
  if (valueStartPos != std::string::npos) {
    ret = std::stoi(arg->substr(valueStartPos + 1));
    if (ret <= 0) {
      std::cout << "Incorrect value specified for argument %s "
                << *arg << std::endl << std::flush;
    }
  }
  return ret;
}

std::string OSPRayEnvironment::GetStrArgValue(std::string *arg) const {
  std::string ret;
  size_t valueStartPos = arg->find_first_of('=');
  if (valueStartPos != std::string::npos) {
    ret = arg->substr(valueStartPos + 1);
  }
  return ret;
}

<|endoftext|>


<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "test_precomp.hpp"
#include "opencv2/photo.hpp"
#include <string>

using namespace cv;
using namespace std;

static const double numerical_precision = 1.;

TEST(Photo_NPR_EdgePreserveSmoothing_RecursiveFilter, regression)
{
    string folder = string(cvtest::TS::ptr()->get_data_path()) + "npr/";
    string original_path = folder + "test1.png";

    Mat source = imread(original_path, IMREAD_COLOR);

    ASSERT_FALSE(source.empty()) << "Could not load input image " << original_path;

    Mat result;
    edgePreservingFilter(source,result,1);

    Mat reference = imread(folder + "smoothened_RF_reference.png");
    double error = norm(reference, result, NORM_L1);
    EXPECT_LE(error, numerical_precision);
}

TEST(Photo_NPR_EdgePreserveSmoothing_NormConvFilter, regression)
{
    string folder = string(cvtest::TS::ptr()->get_data_path()) + "npr/";
    string original_path = folder + "test1.png";

    Mat source = imread(original_path, IMREAD_COLOR);

    ASSERT_FALSE(source.empty()) << "Could not load input image " << original_path;

    Mat result;
    edgePreservingFilter(source,result,2);

    Mat reference = imread(folder + "smoothened_NCF_reference.png");
    double error = norm(reference, result, NORM_L1);
    EXPECT_LE(error, numerical_precision);

}

TEST(Photo_NPR_DetailEnhance, regression)
{
    string folder = string(cvtest::TS::ptr()->get_data_path()) + "npr/";
    string original_path = folder + "test1.png";

    Mat source = imread(original_path, IMREAD_COLOR);

    ASSERT_FALSE(source.empty()) << "Could not load input image " << original_path;

    Mat result;
    detailEnhance(source,result);

    Mat reference = imread(folder + "detail_enhanced_reference.png");
    double error = norm(reference, result, NORM_L1);
    EXPECT_LE(error, numerical_precision);
}

TEST(Photo_NPR_PencilSketch, regression)
{
    string folder = string(cvtest::TS::ptr()->get_data_path()) + "npr/";
    string original_path = folder + "test1.png";

    Mat source = imread(original_path, IMREAD_COLOR);

    ASSERT_FALSE(source.empty()) << "Could not load input image " << original_path;

    Mat pencil_result, color_pencil_result;
    pencilSketch(source,pencil_result, color_pencil_result, 10, 0.1f, 0.03f);

    Mat pencil_reference = imread(folder + "pencil_sketch_reference.png");
    double pencil_error = norm(pencil_reference, pencil_result, NORM_L1);
    EXPECT_LE(pencil_error, numerical_precision);

    Mat color_pencil_reference = imread(folder + "color_pencil_sketch_reference.png");
    double color_pencil_error = norm(color_pencil_reference, color_pencil_result, NORM_L1);
    EXPECT_LE(color_pencil_error, numerical_precision);
}

TEST(Photo_NPR_Stylization, regression)
{
    string folder = string(cvtest::TS::ptr()->get_data_path()) + "npr/";
    string original_path = folder + "test1.png";

    Mat source = imread(original_path, IMREAD_COLOR);

    ASSERT_FALSE(source.empty()) << "Could not load input image " << original_path;

    Mat result;
    stylization(source,result);

    Mat stylized_reference = imread(folder + "stylized_reference.png");
    double stylized_error = norm(stylized_reference, result, NORM_L1);
    EXPECT_LE(stylized_error, numerical_precision);

}
<commit_msg>fix grayscale loading<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "test_precomp.hpp"
#include "opencv2/photo.hpp"
#include <string>

using namespace cv;
using namespace std;

static const double numerical_precision = 1.;

TEST(Photo_NPR_EdgePreserveSmoothing_RecursiveFilter, regression)
{
    string folder = string(cvtest::TS::ptr()->get_data_path()) + "npr/";
    string original_path = folder + "test1.png";

    Mat source = imread(original_path, IMREAD_COLOR);

    ASSERT_FALSE(source.empty()) << "Could not load input image " << original_path;

    Mat result;
    edgePreservingFilter(source,result,1);

    Mat reference = imread(folder + "smoothened_RF_reference.png");
    double error = norm(reference, result, NORM_L1);
    EXPECT_LE(error, numerical_precision);
}

TEST(Photo_NPR_EdgePreserveSmoothing_NormConvFilter, regression)
{
    string folder = string(cvtest::TS::ptr()->get_data_path()) + "npr/";
    string original_path = folder + "test1.png";

    Mat source = imread(original_path, IMREAD_COLOR);

    ASSERT_FALSE(source.empty()) << "Could not load input image " << original_path;

    Mat result;
    edgePreservingFilter(source,result,2);

    Mat reference = imread(folder + "smoothened_NCF_reference.png");
    double error = norm(reference, result, NORM_L1);
    EXPECT_LE(error, numerical_precision);

}

TEST(Photo_NPR_DetailEnhance, regression)
{
    string folder = string(cvtest::TS::ptr()->get_data_path()) + "npr/";
    string original_path = folder + "test1.png";

    Mat source = imread(original_path, IMREAD_COLOR);

    ASSERT_FALSE(source.empty()) << "Could not load input image " << original_path;

    Mat result;
    detailEnhance(source,result);

    Mat reference = imread(folder + "detail_enhanced_reference.png");
    double error = norm(reference, result, NORM_L1);
    EXPECT_LE(error, numerical_precision);
}

TEST(Photo_NPR_PencilSketch, regression)
{
    string folder = string(cvtest::TS::ptr()->get_data_path()) + "npr/";
    string original_path = folder + "test1.png";

    Mat source = imread(original_path, IMREAD_COLOR);

    ASSERT_FALSE(source.empty()) << "Could not load input image " << original_path;

    Mat pencil_result, color_pencil_result;
    pencilSketch(source,pencil_result, color_pencil_result, 10, 0.1f, 0.03f);

    Mat pencil_reference = imread(folder + "pencil_sketch_reference.png", 0 /* == grayscale*/);
    double pencil_error = norm(pencil_reference, pencil_result, NORM_L1);
    EXPECT_LE(pencil_error, numerical_precision);

    Mat color_pencil_reference = imread(folder + "color_pencil_sketch_reference.png");
    double color_pencil_error = norm(color_pencil_reference, color_pencil_result, NORM_L1);
    EXPECT_LE(color_pencil_error, numerical_precision);
}

TEST(Photo_NPR_Stylization, regression)
{
    string folder = string(cvtest::TS::ptr()->get_data_path()) + "npr/";
    string original_path = folder + "test1.png";

    Mat source = imread(original_path, IMREAD_COLOR);

    ASSERT_FALSE(source.empty()) << "Could not load input image " << original_path;

    Mat result;
    stylization(source,result);

    Mat stylized_reference = imread(folder + "stylized_reference.png");
    double stylized_error = norm(stylized_reference, result, NORM_L1);
    EXPECT_LE(stylized_error, numerical_precision);

}
<|endoftext|>


<commit_before>/**
 * Appcelerator Kroll - licensed under the Apache Public License 2
 * see LICENSE in the root folder for details on the license.
 * Copyright (c) 2008 Appcelerator, Inc. All Rights Reserved.
 */
#include "python_module.h"

namespace kroll
{
	SharedBoundObject PythonUtils::scope;

	const char * PythonUtils::ToString(PyObject* value)
	{
		if (PyString_Check(value))
		{
			return PyString_AsString(value);
		}
		return "";
	}

	bool PythonBoolToBool(PyObject* value)
	{
		if (PyBool_Check(value))
		{
			return PyObject_IsTrue(value);
		}
		return false;
	}

	int PythonFixnumToInt(PyObject* value)
	{
		if (PyInt_Check(value))
		{
			return (int)PyInt_AsLong(value);
		}
		return 0;
	}

	double PythonFloatToDouble(PyObject* value)
	{
		if (PyFloat_Check(value))
		{
			return PyFloat_AsDouble(value);
		}
		return 0.0;
	}

	class PythonEvaluator : public BoundMethod
	{
	public:
		virtual SharedValue Call(const ValueList& args) {
			if (args.size() == 3 && args[1]->IsString()) {

				// strip the beginning so we have some sense of tab normalization
				std::string code = args[1]->ToString();
				size_t startpos = code.find_first_not_of(" \t\n");
				if (std::string::npos != startpos)
					code = code.substr(startpos);

				std::cout << "Evaluating python source code:\n" << code << std::endl;
				SharedBoundObject context = args[2]->ToObject();
				PyObject *py_context = PythonUtils::ToObject(NULL, NULL, context);

				PyObject *main_module = PyImport_AddModule("__main__");
				PyObject *main_dict = PyModule_GetDict(main_module);

				PyDict_SetItemString(main_dict, "window", py_context);
				PyObject *returnValue = PyRun_StringFlags(code.c_str(), Py_file_input, main_dict, main_dict, NULL);
				if (returnValue == NULL) {
					PyErr_Print();
					//FIXME - throw error message here
					throw Value::NewString("error evaluating python");
				}
				Py_DECREF(returnValue);
			}
			return Value::Null;
		}

		virtual void Set(const char *name, SharedValue value) {}
		virtual SharedValue Get(const char *name) { return Value::Null; }
		virtual SharedStringList GetPropertyNames() { return SharedStringList(); }
	};

	SharedBoundMethod PythonUtils::evaluator = SharedBoundMethod(new PythonEvaluator());

	void PythonUtils::InitializeDefaultBindings (Host *host)
	{
		PyObject* mod = PyImport_ImportModule("__builtin__");

		if (mod)
		{
			// we bind the special module "api" to the global
			// variable defined in PRODUCT_NAME to give the
			// Python runtime access to it
			SharedValue api = host->GetGlobalObject()->Get("API");
			if (api->IsObject())
			{
				// we're going to clone the methods from api into our
				// own python scoped object
				SharedBoundObject hostobj = host->GetGlobalObject();
				SharedBoundObject apiobj = api->ToObject();
				scope = ScopeMethodDelegate::CreateDelegate(hostobj, apiobj);
				scope->Set("evaluate", Value::NewMethod(evaluator));
				PyObject *pyapi = PythonUtils::ToObject(NULL,NULL,hostobj);
				printf("binding %s into Python __builtin__\n", PRODUCT_NAME);
				PyObject_SetAttrString(mod,PRODUCT_NAME,pyapi);
				// now bind our new scope to python module
				SharedValue scopeRef = Value::NewObject(scope);
				host->GetGlobalObject()->Set((const char*)"Python",scopeRef);
				// don't release the scope
			}
			else
			{
				std::cerr << "! Couldn't find API module to bind Python module to" << std::endl;
			}
			Py_DECREF(mod);
		}
	}
	// PyObject* ValueListToPythonArray(const ValueList& list)
	// {
	// 	int size = list.size();
	//
	// 	if (size == 0)
	// 	{
	// 		Py_INCREF(Py_None);
	// 		return Py_None;
	// 	}
	//
	// 	PyObject *array = PyTuple_New(size);
	// 	for (int c=0;c<size;c++)
	// 	{
	// 		Value *value = list.at(c);
	// 		PyTuple_SET_ITEM(array,c,ValueToPythonBoundObject(value));
	// 	}
	// 	return array;
	// }
	static void PyDeleteBoundMethod(void *p)
	{
		// std::cout << "PyDeleteBoundMethod being called for " << p << std::endl;
		SharedBoundMethod* method = static_cast< SharedBoundMethod* >(p);
		delete method;
	}

	static PyObject *BoundMethodDispatcher (PyObject *s, PyObject *args)
	{
		void *sp = PyCObject_AsVoidPtr(s);
		SharedBoundMethod* method = static_cast<SharedBoundMethod*>(sp);
		ValueList a;
		// std::cout << "calling BoundMethodDispatcher for "  << sp << std::endl;
		Py_INCREF(s);
		try
		{
			for (int c=0;c<PyTuple_Size(args);c++)
			{
				PyObject *arg=PyTuple_GET_ITEM(args,c);
				SharedValue argument = PythonUtils::ToValue(arg,NULL);
				a.push_back(argument);
			}
			SharedBoundMethod m = (*method);
			SharedValue result = m->Call(a);
			Py_DECREF(s);
			return PythonUtils::ToObject(result);
		}
		catch (SharedValue ex)
		{
			PyErr_SetObject(PyExc_Exception,PythonUtils::ToObject(ex));
			Py_INCREF(Py_None);
			Py_DECREF(s);
			return Py_None;
		}
	}

	static PyMethodDef BoundMethodDispatcherDef =
	{
			"BoundMethodDispatcher",
			&BoundMethodDispatcher,
			METH_VARARGS,
			"dispatcher for BoundMethod"
	};

	PyObject* PythonUtils::ToObject(SharedBoundMethod method)
	{
		SharedBoundMethod *m = new SharedBoundMethod(method);
		PyObject *self = PyCObject_FromVoidPtr(m,&PyDeleteBoundMethod);
		return PyCFunction_New(&BoundMethodDispatcherDef, self);
	}

	PyObject* PythonUtils::ToObject(SharedValue value)
	{
		if (value->IsBool())
		{
			return value->ToBool() ? Py_True : Py_False;
		}
		if (value->IsDouble())
		{
			return PyFloat_FromDouble(value->ToDouble());
		}
		if (value->IsInt())
		{
			return PyInt_FromLong(value->ToInt());
		}
		if (value->IsNull() || value->IsUndefined())
		{
			Py_INCREF(Py_None);
			return Py_None;
		}
		if (value->IsMethod())
		{
			SharedBoundMethod obj = value->ToMethod();
			if (typeid(obj.get()) == typeid(PythonBoundMethod*))
			{
				return (PyObject*)((PythonBoundMethod*)obj.get())->ToPython();
			}
			return PythonUtils::ToObject(value->ToMethod());
		}
		if (value->IsList())
		{
			SharedBoundList list = value->ToList();
			if (typeid(list.get()) == typeid(PythonBoundList*))
			{
				return ((PythonBoundList*)list.get())->ToPython();
			}
			return PythonUtils::ToObject(NULL,NULL,list);
		}
		if (value->IsObject())
		{
			SharedBoundObject obj = value->ToObject();
			if (typeid(obj.get()) == typeid(PythonBoundObject*))
			{
				return (PyObject*)((PythonBoundObject*)obj.get())->ToPython();
			}
			return PythonUtils::ToObject(NULL,NULL,value->ToObject());
		}
		if (value->IsString())
		{
			return PyString_FromString(value->ToString());
		}
		Py_INCREF(Py_None);
		return Py_None;
	}

	typedef struct {
		PyObject_HEAD
		SharedBoundObject* object;
	} PyBoundObject;

	static void PyBoundObject_dealloc(PyObject* self)
	{
		// std::cout << "++PyBoundObject_dealloc called for " <<(void*)self << std::endl;
		PyBoundObject *boundSelf = (PyBoundObject*) self;
		delete boundSelf->object;
		delete boundSelf;
		PyObject_Del(self);
	}

	static PyObject* PyBoundObject_getattr(PyObject *self, char *name)
	{
		PyBoundObject *boundSelf = reinterpret_cast<PyBoundObject*>(self);
	 	// std::cout << "PyBoundObject_getattr called with " << name << " for " << (void*)boundSelf << std::endl;
		Py_INCREF(boundSelf);
		SharedValue result = boundSelf->object->get()->Get(name);
		Py_DECREF(boundSelf);
		return PythonUtils::ToObject(result);
	}

	static int PyBoundObject_setattr(PyObject *self, char *name, PyObject *value)
	{
		PyBoundObject *boundSelf = (PyBoundObject*)self;
		// std::cout << KR_FUNC << " called for " <<(void*)boundSelf << std::endl;
		Py_INCREF(boundSelf);
		SharedValue tiValue = PythonUtils::ToValue(value,name);
		boundSelf->object->get()->Set(name, tiValue);
		Py_DECREF(boundSelf);
		return 0;
	}

	static PyObject* PyBoundObject_tostring(PyObject *self)
	{
		PyBoundObject *boundSelf = (PyBoundObject*)self;
		//std::cout << KR_FUNC << " called for " <<(void*)boundSelf << std::endl;
		Py_INCREF(boundSelf);
		SharedValue result = boundSelf->object->get()->Get("toString");
		Py_DECREF(boundSelf);
		if (result->IsMethod())
		{
			SharedBoundMethod method = result->ToMethod();
			ValueList args;
			SharedValue toString = method->Call(args);
			if (toString->IsString())
			{
				return PyString_FromString(toString->ToString());
			}
		}
		char str[255];
		sprintf(str,"<BoundObject %x>",(unsigned int)self);
		return PyString_FromString(str);
	}

	static PyTypeObject PyBoundObjectType =
	{
	    PyObject_HEAD_INIT(NULL)
	    0,
	    "BoundObject",
	    sizeof(PyBoundObject),
	    0,
	    PyBoundObject_dealloc, 		/*tp_dealloc*/
	    0,          	 			/*tp_print*/
	    PyBoundObject_getattr,    	/*tp_getattr*/
	    PyBoundObject_setattr,    	/*tp_setattr*/
	    0,          	 			/*tp_compare*/
	    0,          	 			/*tp_repr*/
	    0,          	 			/*tp_as_number*/
	    0,    						/*tp_as_sequence*/
	    0,     						/*tp_as_mapping*/
	    0,           	 			/*tp_hash */
		0,							/*tp_call */
		PyBoundObject_tostring,		/*tp_str */
		0,							/*tp_getattro*/
		0,							/*tp_setattro*/
		0,							/*tp_as_buffer*/
		0,							/*tp_flags*/
		0,							/*tp_doc*/
	};

	PyObject* PythonUtils::ToObject(PyObject* self, PyObject* args, SharedBoundObject bo)
	{
		//CHECK bo
		if (bo.isNull())
		{
			throw "BoundObject cannot be null";
		}
		SharedBoundList list = bo.cast<BoundList>();
		if (!list.isNull())
		{
			// convert it into a list of wrapped Value objects
			PyObject* newlist = PyList_New(list->Size());
			for (int c = 0; c < list->Size(); c++)
			{
				SharedValue value = list->At(c);
				PyObject *item = PythonUtils::ToObject(value);
				PyList_SetItem(newlist,c,item);
			}
			return newlist;
		}
		else
		{
			PyBoundObject* obj = PyObject_New(PyBoundObject, &PyBoundObjectType);
			SharedBoundObject* bo_ptr = new SharedBoundObject(bo);
			obj->object = bo_ptr;
			return (PyObject*)obj;
		}
	}

	void PythonUtils::ThrowException()
	{
		PyObject *ptype, *pvalue, *trace;
		PyErr_Fetch(&ptype,&pvalue,&trace);
		PyErr_Print();
		PyErr_Clear();
		throw PythonUtils::ToValue(pvalue,NULL);
	}

	SharedValue PythonUtils::ToValue(PyObject* value, const char *name)
	{
		//FIXME - who is going to delete ref?

		if (Py_None==value)
		{
			return Value::Undefined;
		}
		if (PyString_Check(value))
		{
			std::string s = PythonUtils::ToString(value);
			return Value::NewString(s);
		}
		if (PyBool_Check(value))
		{
			return Value::NewBool(PythonBoolToBool(value));
		}
		if (PyInt_Check(value))
		{
			return Value::NewInt(PythonFixnumToInt(value));
		}
		if (PyFloat_Check(value))
		{
			return Value::NewDouble(PythonFloatToDouble(value));
		}
		if (PyList_Check(value))
		{
			SharedBoundList l = new PythonBoundList(value);
			SharedValue til = Value::NewList(l);
			return til;
		}
		if (PyClass_Check(value))
		{
			SharedBoundObject v = new PythonBoundObject(value);
			SharedValue tiv = Value::NewObject(v);
			return tiv;
		}
		if (PyInstance_Check(value))
		{
			SharedBoundObject v = new PythonBoundObject(value);
			SharedValue tiv = Value::NewObject(v);
			return tiv;
		}
		if (PyMethod_Check(value))
		{
			SharedBoundMethod m = new PythonBoundMethod(value,name);
			SharedValue tiv = Value::NewMethod(m);
			return tiv;
		}
		if (PyFunction_Check(value))
		{
			SharedBoundMethod m = new PythonBoundMethod(value,name);
			SharedValue tiv = Value::NewMethod(m);
			return tiv;
		}
		if (PyCallable_Check(value))
		{
			SharedBoundMethod m = new PythonBoundMethod(value,name);
			SharedValue tiv = Value::NewMethod(m);
			return tiv;
		}
		if (PyObject_TypeCheck(value,&PyBoundObjectType))
		{
			PyBoundObject *o = reinterpret_cast<PyBoundObject*>(value);
			SharedValue tiv = Value::NewObject(*(o->object));
			return tiv;
		}

		std::cerr << "PythonBoundObjectToValue:nothing" << std::endl;
		PyObject_Print(value,stdout,0);
		printf("\n");

		return new Value();
	}
}

<commit_msg>python exception fixes, CRLF fix for python scripts<commit_after>/**
 * Appcelerator Kroll - licensed under the Apache Public License 2
 * see LICENSE in the root folder for details on the license.
 * Copyright (c) 2008 Appcelerator, Inc. All Rights Reserved.
 */
#include "python_module.h"

namespace kroll
{
	SharedBoundObject PythonUtils::scope;

	const char * PythonUtils::ToString(PyObject* value)
	{
		if (PyString_Check(value))
		{
			return PyString_AsString(value);
		}
		PyObject *o = PyObject_Str(value);
		const char *result = PythonUtils::ToString(o);
		Py_DECREF(o);
		return result;
	}

	bool PythonBoolToBool(PyObject* value)
	{
		if (PyBool_Check(value))
		{
			return PyObject_IsTrue(value);
		}
		return false;
	}

	int PythonFixnumToInt(PyObject* value)
	{
		if (PyInt_Check(value))
		{
			return (int)PyInt_AsLong(value);
		}
		return 0;
	}

	double PythonFloatToDouble(PyObject* value)
	{
		if (PyFloat_Check(value))
		{
			return PyFloat_AsDouble(value);
		}
		return 0.0;
	}

	void ConvertLinefeeds(std::string &code)
	{
		while (1)
		{
			std::string::size_type loc = code.find("\r\n");
			if (loc == std::string::npos) break;
			code.replace(loc,2,"\n");
		}
	}

	class PythonEvaluator : public BoundMethod
	{
	public:
		virtual SharedValue Call(const ValueList& args) {
			if (args.size() == 3 && args[1]->IsString()) {

				// strip the beginning so we have some sense of tab normalization
				std::string code = args[1]->ToString();
				ConvertLinefeeds(code);
				size_t startpos = code.find_first_not_of(" \t\n");
				if (std::string::npos != startpos)
					code = code.substr(startpos);

#ifdef DEBUG
				std::cout << "Evaluating python source code:\n" << code << std::endl;
#endif
				SharedBoundObject context = args[2]->ToObject();
				PyObject *py_context = PythonUtils::ToObject(NULL, NULL, context);

				PyObject *main_module = PyImport_AddModule("__main__");
				PyObject *main_dict = PyModule_GetDict(main_module);

				PyDict_SetItemString(main_dict, "window", py_context);
				PyObject *returnValue = PyRun_StringFlags(code.c_str(), Py_file_input, main_dict, main_dict, NULL);

				Py_DECREF(py_context);

				if (returnValue == NULL)
				{
					 PythonUtils::ThrowException();
				}
				Py_DECREF(returnValue);
			}
			return Value::Null;
		}

		virtual void Set(const char *name, SharedValue value) {}
		virtual SharedValue Get(const char *name) { return Value::Null; }
		virtual SharedStringList GetPropertyNames() { return SharedStringList(); }
	};

	SharedBoundMethod PythonUtils::evaluator = SharedBoundMethod(new PythonEvaluator());

	void PythonUtils::InitializeDefaultBindings (Host *host)
	{
		PyObject* mod = PyImport_ImportModule("__builtin__");

		if (mod)
		{
			// we bind the special module "api" to the global
			// variable defined in PRODUCT_NAME to give the
			// Python runtime access to it
			SharedValue api = host->GetGlobalObject()->Get("API");
			if (api->IsObject())
			{
				// we're going to clone the methods from api into our
				// own python scoped object
				SharedBoundObject hostobj = host->GetGlobalObject();
				SharedBoundObject apiobj = api->ToObject();
				scope = ScopeMethodDelegate::CreateDelegate(hostobj, apiobj);
				scope->Set("evaluate", Value::NewMethod(evaluator));
				PyObject *pyapi = PythonUtils::ToObject(NULL,NULL,hostobj);
				printf("binding %s into Python __builtin__\n", PRODUCT_NAME);
				PyObject_SetAttrString(mod,PRODUCT_NAME,pyapi);
				// now bind our new scope to python module
				SharedValue scopeRef = Value::NewObject(scope);
				host->GetGlobalObject()->Set((const char*)"Python",scopeRef);
				// don't release the scope
			}
			else
			{
				std::cerr << "! Couldn't find API module to bind Python module to" << std::endl;
			}
			Py_DECREF(mod);
		}
	}
	// PyObject* ValueListToPythonArray(const ValueList& list)
	// {
	// 	int size = list.size();
	//
	// 	if (size == 0)
	// 	{
	// 		Py_INCREF(Py_None);
	// 		return Py_None;
	// 	}
	//
	// 	PyObject *array = PyTuple_New(size);
	// 	for (int c=0;c<size;c++)
	// 	{
	// 		Value *value = list.at(c);
	// 		PyTuple_SET_ITEM(array,c,ValueToPythonBoundObject(value));
	// 	}
	// 	return array;
	// }
	static void PyDeleteBoundMethod(void *p)
	{
		// std::cout << "PyDeleteBoundMethod being called for " << p << std::endl;
		SharedBoundMethod* method = static_cast< SharedBoundMethod* >(p);
		delete method;
	}

	static PyObject *BoundMethodDispatcher (PyObject *s, PyObject *args)
	{
		void *sp = PyCObject_AsVoidPtr(s);
		SharedBoundMethod* method = static_cast<SharedBoundMethod*>(sp);
		ValueList a;
		// std::cout << "calling BoundMethodDispatcher for "  << sp << std::endl;
		Py_INCREF(s);
		try
		{
			for (int c=0;c<PyTuple_Size(args);c++)
			{
				PyObject *arg=PyTuple_GET_ITEM(args,c);
				SharedValue argument = PythonUtils::ToValue(arg,NULL);
				a.push_back(argument);
			}
			SharedBoundMethod m = (*method);
			SharedValue result = m->Call(a);
			Py_DECREF(s);
			return PythonUtils::ToObject(result);
		}
		catch (SharedValue ex)
		{
			PyErr_SetObject(PyExc_Exception,PythonUtils::ToObject(ex));
			Py_INCREF(Py_None);
			Py_DECREF(s);
			return Py_None;
		}
	}

	static PyMethodDef BoundMethodDispatcherDef =
	{
			"BoundMethodDispatcher",
			&BoundMethodDispatcher,
			METH_VARARGS,
			"dispatcher for BoundMethod"
	};

	PyObject* PythonUtils::ToObject(SharedBoundMethod method)
	{
		SharedBoundMethod *m = new SharedBoundMethod(method);
		PyObject *self = PyCObject_FromVoidPtr(m,&PyDeleteBoundMethod);
		return PyCFunction_New(&BoundMethodDispatcherDef, self);
	}

	PyObject* PythonUtils::ToObject(SharedValue value)
	{
		if (value->IsBool())
		{
			return value->ToBool() ? Py_True : Py_False;
		}
		if (value->IsDouble())
		{
			return PyFloat_FromDouble(value->ToDouble());
		}
		if (value->IsInt())
		{
			return PyInt_FromLong(value->ToInt());
		}
		if (value->IsNull() || value->IsUndefined())
		{
			Py_INCREF(Py_None);
			return Py_None;
		}
		if (value->IsMethod())
		{
			SharedBoundMethod obj = value->ToMethod();
			if (typeid(obj.get()) == typeid(PythonBoundMethod*))
			{
				return (PyObject*)((PythonBoundMethod*)obj.get())->ToPython();
			}
			return PythonUtils::ToObject(value->ToMethod());
		}
		if (value->IsList())
		{
			SharedBoundList list = value->ToList();
			if (typeid(list.get()) == typeid(PythonBoundList*))
			{
				return ((PythonBoundList*)list.get())->ToPython();
			}
			return PythonUtils::ToObject(NULL,NULL,list);
		}
		if (value->IsObject())
		{
			SharedBoundObject obj = value->ToObject();
			if (typeid(obj.get()) == typeid(PythonBoundObject*))
			{
				return (PyObject*)((PythonBoundObject*)obj.get())->ToPython();
			}
			return PythonUtils::ToObject(NULL,NULL,value->ToObject());
		}
		if (value->IsString())
		{
			return PyString_FromString(value->ToString());
		}
		Py_INCREF(Py_None);
		return Py_None;
	}

	typedef struct {
		PyObject_HEAD
		SharedBoundObject* object;
	} PyBoundObject;

	static void PyBoundObject_dealloc(PyObject* self)
	{
		// std::cout << "++PyBoundObject_dealloc called for " <<(void*)self << std::endl;
		PyBoundObject *boundSelf = (PyBoundObject*) self;
		delete boundSelf->object;
		delete boundSelf;
		PyObject_Del(self);
	}

	static PyObject* PyBoundObject_getattr(PyObject *self, char *name)
	{
		PyBoundObject *boundSelf = reinterpret_cast<PyBoundObject*>(self);
	 	// std::cout << "PyBoundObject_getattr called with " << name << " for " << (void*)boundSelf << std::endl;
		Py_INCREF(boundSelf);
		SharedValue result = boundSelf->object->get()->Get(name);
		Py_DECREF(boundSelf);
		return PythonUtils::ToObject(result);
	}

	static int PyBoundObject_setattr(PyObject *self, char *name, PyObject *value)
	{
		PyBoundObject *boundSelf = (PyBoundObject*)self;
		// std::cout << KR_FUNC << " called for " <<(void*)boundSelf << std::endl;
		Py_INCREF(boundSelf);
		SharedValue tiValue = PythonUtils::ToValue(value,name);
		boundSelf->object->get()->Set(name, tiValue);
		Py_DECREF(boundSelf);
		return 0;
	}

	static PyObject* PyBoundObject_tostring(PyObject *self)
	{
		PyBoundObject *boundSelf = (PyBoundObject*)self;
		//std::cout << KR_FUNC << " called for " <<(void*)boundSelf << std::endl;
		Py_INCREF(boundSelf);
		SharedValue result = boundSelf->object->get()->Get("toString");
		Py_DECREF(boundSelf);
		if (result->IsMethod())
		{
			SharedBoundMethod method = result->ToMethod();
			ValueList args;
			SharedValue toString = method->Call(args);
			if (toString->IsString())
			{
				return PyString_FromString(toString->ToString());
			}
		}
		char str[255];
		sprintf(str,"<BoundObject %x>",(unsigned int)self);
		return PyString_FromString(str);
	}

	static PyTypeObject PyBoundObjectType =
	{
	    PyObject_HEAD_INIT(NULL)
	    0,
	    "BoundObject",
	    sizeof(PyBoundObject),
	    0,
	    PyBoundObject_dealloc, 		/*tp_dealloc*/
	    0,          	 			/*tp_print*/
	    PyBoundObject_getattr,    	/*tp_getattr*/
	    PyBoundObject_setattr,    	/*tp_setattr*/
	    0,          	 			/*tp_compare*/
	    0,          	 			/*tp_repr*/
	    0,          	 			/*tp_as_number*/
	    0,    						/*tp_as_sequence*/
	    0,     						/*tp_as_mapping*/
	    0,           	 			/*tp_hash */
		0,							/*tp_call */
		PyBoundObject_tostring,		/*tp_str */
		0,							/*tp_getattro*/
		0,							/*tp_setattro*/
		0,							/*tp_as_buffer*/
		0,							/*tp_flags*/
		0,							/*tp_doc*/
	};

	PyObject* PythonUtils::ToObject(PyObject* self, PyObject* args, SharedBoundObject bo)
	{
		//CHECK bo
		if (bo.isNull())
		{
			throw "BoundObject cannot be null";
		}
		SharedBoundList list = bo.cast<BoundList>();
		if (!list.isNull())
		{
			// convert it into a list of wrapped Value objects
			PyObject* newlist = PyList_New(list->Size());
			for (int c = 0; c < list->Size(); c++)
			{
				SharedValue value = list->At(c);
				PyObject *item = PythonUtils::ToObject(value);
				PyList_SetItem(newlist,c,item);
			}
			return newlist;
		}
		else
		{
			PyBoundObject* obj = PyObject_New(PyBoundObject, &PyBoundObjectType);
			SharedBoundObject* bo_ptr = new SharedBoundObject(bo);
			obj->object = bo_ptr;
			return (PyObject*)obj;
		}
	}

	void PythonUtils::ThrowException()
	{
		PyObject *ptype, *pvalue, *trace;
		PyErr_Fetch(&ptype,&pvalue,&trace);
		PyErr_Print();
		const char *err = PythonUtils::ToString(pvalue);
		ValueException ex = ValueException::FromString(err);
		Py_XDECREF(ptype);
		Py_XDECREF(pvalue);
		Py_XDECREF(trace);
		PyErr_Clear();
		throw ex;
	}

	SharedValue PythonUtils::ToValue(PyObject* value, const char *name)
	{
		//FIXME - who is going to delete ref?

		if (Py_None==value)
		{
			return Value::Undefined;
		}
		if (PyString_Check(value))
		{
			std::string s = PythonUtils::ToString(value);
			return Value::NewString(s);
		}
		if (PyBool_Check(value))
		{
			return Value::NewBool(PythonBoolToBool(value));
		}
		if (PyInt_Check(value))
		{
			return Value::NewInt(PythonFixnumToInt(value));
		}
		if (PyFloat_Check(value))
		{
			return Value::NewDouble(PythonFloatToDouble(value));
		}
		if (PyList_Check(value))
		{
			SharedBoundList l = new PythonBoundList(value);
			SharedValue til = Value::NewList(l);
			return til;
		}
		if (PyClass_Check(value))
		{
			SharedBoundObject v = new PythonBoundObject(value);
			SharedValue tiv = Value::NewObject(v);
			return tiv;
		}
		if (PyInstance_Check(value))
		{
			SharedBoundObject v = new PythonBoundObject(value);
			SharedValue tiv = Value::NewObject(v);
			return tiv;
		}
		if (PyMethod_Check(value))
		{
			SharedBoundMethod m = new PythonBoundMethod(value,name);
			SharedValue tiv = Value::NewMethod(m);
			return tiv;
		}
		if (PyFunction_Check(value))
		{
			SharedBoundMethod m = new PythonBoundMethod(value,name);
			SharedValue tiv = Value::NewMethod(m);
			return tiv;
		}
		if (PyCallable_Check(value))
		{
			SharedBoundMethod m = new PythonBoundMethod(value,name);
			SharedValue tiv = Value::NewMethod(m);
			return tiv;
		}
		if (PyObject_TypeCheck(value,&PyBoundObjectType))
		{
			PyBoundObject *o = reinterpret_cast<PyBoundObject*>(value);
			SharedValue tiv = Value::NewObject(*(o->object));
			return tiv;
		}

		std::cerr << "PythonBoundObjectToValue:nothing" << std::endl;
		PyObject_Print(value,stdout,0);
		printf("\n");

		return new Value();
	}
}

<|endoftext|>


<commit_before>#include "core/tz.hpp"
#include "gl/impl/backend/vk2/descriptors.hpp"

void basic_descriptor_layout()
{
	using namespace tz::gl::vk2;
	PhysicalDevice pdev = get_all_devices().front();
	LogicalDeviceInfo linfo;
	linfo.physical_device = pdev;
	linfo.surface = &get_window_surface();
	linfo.features = {DeviceFeature::BindlessDescriptors};

	LogicalDevice ldev{linfo};
	{
		DescriptorLayoutBuilder builder{ldev};
		DescriptorLayoutBuilder build_all{ldev};
		DescriptorLayoutBuilderBindless build_all_bindless{ldev};
		// Firstly create a builder with no descriptors.
		DescriptorLayoutInfo dinfo1 = builder.build();

		// Now one with a couple of resources.
		builder.with_descriptor(DescriptorType::Image).with_descriptor(DescriptorType::Sampler);
		DescriptorLayoutInfo dinfo2 = builder.build();
		// Then, one with just fucking everything.
		build_all
			.with_descriptor(DescriptorType::Sampler)
			.with_descriptor(DescriptorType::Image)
			.with_descriptor(DescriptorType::ImageWithSampler)
			.with_descriptor(DescriptorType::StorageImage)
			.with_descriptor(DescriptorType::UniformBuffer)
			.with_descriptor(DescriptorType::StorageBuffer);
		DescriptorLayoutInfo dinfo3 = build_all.build();
		// Finally, same as before but bindless (with arrays of small but >1 size).
		build_all_bindless
			.with_descriptor(DescriptorType::StorageBuffer, 255)
			.with_descriptor(DescriptorType::Image, 255)
			.with_descriptor(DescriptorType::StorageImage, 255)
			.with_descriptor(DescriptorType::Sampler, 255);
		DescriptorLayoutInfo dinfo4 = build_all_bindless.build();

		// Do some testing on the dinfos
		// All but dinfo4 should be Context::Classic
		tz_assert(dinfo1.context == DescriptorContext::Classic, "DescriptorLayoutInfo has wrong context type");
		tz_assert(dinfo2.context == DescriptorContext::Classic, "DescriptorLayoutInfo has wrong context type");
		tz_assert(dinfo3.context == DescriptorContext::Classic, "DescriptorLayoutInfo has wrong context type");
		tz_assert(dinfo4.context == DescriptorContext::Bindless, "DescriptorLayoutInfo has wrong context type");
		{
			DescriptorLayout dlayout1{dinfo1};
			DescriptorLayout dlayout2{dinfo2};
			DescriptorLayout dlayout3{dinfo3};
			DescriptorLayout dlayout4{dinfo4};
		}
	}
}

int main()
{
	tz::GameInfo game{"vk_descriptor_test", tz::Version{1, 0, 0}, tz::info()};
	tz::initialise(game, tz::ApplicationType::HiddenWindowApplication);
	tz::gl::vk2::initialise(game, tz::ApplicationType::HiddenWindowApplication);
	{
		basic_descriptor_layout();
	}
	tz::gl::vk2::terminate();
	tz::terminate();
}
<commit_msg>* Split up the Bindless and Classic descriptor builder tests into separate functions within vk_descriptor_test<commit_after>#include "core/tz.hpp"
#include "gl/impl/backend/vk2/descriptors.hpp"

void basic_classic_descriptor_layout()
{
	using namespace tz::gl::vk2;
	PhysicalDevice pdev = get_all_devices().front();
	LogicalDeviceInfo linfo;
	linfo.physical_device = pdev;
	linfo.surface = &get_window_surface();

	LogicalDevice ldev{linfo};
	{
		DescriptorLayoutBuilder builder{ldev};
		DescriptorLayoutBuilder build_all{ldev};
		// Firstly create a builder with no descriptors.
		DescriptorLayoutInfo dinfo1 = builder.build();

		// Now one with a couple of resources.
		builder.with_descriptor(DescriptorType::Image).with_descriptor(DescriptorType::Sampler);
		DescriptorLayoutInfo dinfo2 = builder.build();
		// Then, one with just fucking everything.
		build_all
			.with_descriptor(DescriptorType::Sampler)
			.with_descriptor(DescriptorType::Image)
			.with_descriptor(DescriptorType::ImageWithSampler)
			.with_descriptor(DescriptorType::StorageImage)
			.with_descriptor(DescriptorType::UniformBuffer)
			.with_descriptor(DescriptorType::StorageBuffer);
		DescriptorLayoutInfo dinfo3 = build_all.build();

		// Do some testing on the dinfos
		tz_assert(dinfo1.context == DescriptorContext::Classic, "DescriptorLayoutInfo has wrong context type");
		tz_assert(dinfo2.context == DescriptorContext::Classic, "DescriptorLayoutInfo has wrong context type");
		tz_assert(dinfo3.context == DescriptorContext::Classic, "DescriptorLayoutInfo has wrong context type");
		{
			DescriptorLayout dlayout1{dinfo1};
			DescriptorLayout dlayout2{dinfo2};
			DescriptorLayout dlayout3{dinfo3};
		}
	}
}

void basic_bindless_descriptor_layout()
{
	using namespace tz::gl::vk2;
	PhysicalDevice pdev = get_all_devices().front();
	if(!pdev.get_supported_features().contains(DeviceFeature::BindlessDescriptors))
	{
		// Can't test bindless if the PhysicalDevice doesn't support it
		return;
	}
	LogicalDeviceInfo linfo;
	linfo.physical_device = pdev;
	linfo.surface = &get_window_surface();
	linfo.features = {DeviceFeature::BindlessDescriptors};

	LogicalDevice ldev{linfo};
	{
		DescriptorLayoutBuilder builder{ldev};
		DescriptorLayoutBuilder build_all{ldev};
		DescriptorLayoutBuilderBindless build_all_bindless{ldev};
		// Firstly create a builder with no descriptors.
		DescriptorLayoutInfo dinfo1 = builder.build();

		// Now one with a couple of resources.
		builder.with_descriptor(DescriptorType::Image).with_descriptor(DescriptorType::Sampler);
		DescriptorLayoutInfo dinfo2 = builder.build();
		// Then, one with just fucking everything.
		build_all
			.with_descriptor(DescriptorType::Sampler)
			.with_descriptor(DescriptorType::Image)
			.with_descriptor(DescriptorType::ImageWithSampler)
			.with_descriptor(DescriptorType::StorageImage)
			.with_descriptor(DescriptorType::UniformBuffer)
			.with_descriptor(DescriptorType::StorageBuffer);
		DescriptorLayoutInfo dinfo3 = build_all.build();
		// Finally, same as before but bindless (with arrays of small but >1 size).
		build_all_bindless
			.with_descriptor(DescriptorType::StorageBuffer, 255)
			.with_descriptor(DescriptorType::Image, 255)
			.with_descriptor(DescriptorType::StorageImage, 255)
			.with_descriptor(DescriptorType::Sampler, 255);
		DescriptorLayoutInfo dinfo4 = build_all_bindless.build();

		// Do some testing on the dinfos
		// All but dinfo4 should be Context::Classic
		tz_assert(dinfo1.context == DescriptorContext::Classic, "DescriptorLayoutInfo has wrong context type");
		tz_assert(dinfo2.context == DescriptorContext::Classic, "DescriptorLayoutInfo has wrong context type");
		tz_assert(dinfo3.context == DescriptorContext::Classic, "DescriptorLayoutInfo has wrong context type");
		tz_assert(dinfo4.context == DescriptorContext::Bindless, "DescriptorLayoutInfo has wrong context type");
		{
			DescriptorLayout dlayout1{dinfo1};
			DescriptorLayout dlayout2{dinfo2};
			DescriptorLayout dlayout3{dinfo3};
			DescriptorLayout dlayout4{dinfo4};
		}
	}
}

int main()
{
	tz::GameInfo game{"vk_descriptor_test", tz::Version{1, 0, 0}, tz::info()};
	tz::initialise(game, tz::ApplicationType::HiddenWindowApplication);
	tz::gl::vk2::initialise(game, tz::ApplicationType::HiddenWindowApplication);
	{
		basic_classic_descriptor_layout();
		basic_bindless_descriptor_layout();
	}
	tz::gl::vk2::terminate();
	tz::terminate();
}
<|endoftext|>


<commit_before>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/*
 * Copyright (C) 2019 Cloudius Systems, Ltd.
 */

#include <seastar/testing/test_case.hh>
#include <seastar/net/api.hh>
#include <seastar/net/inet_address.hh>
#include <seastar/net/ethernet.hh>
#include <seastar/net/ip.hh>
#include <seastar/core/reactor.hh>
#include <seastar/core/thread.hh>
#include <seastar/util/log.hh>

using namespace seastar;

static logger niflog("network_interface_test");

SEASTAR_TEST_CASE(list_interfaces) {
    // just verifying we have something. And can access all the stuff.
    auto interfaces = engine().net().network_interfaces();
    BOOST_REQUIRE_GT(interfaces.size(), 0);

    for (auto& nif : interfaces) {
        niflog.info("Iface: {}, index = {}, mtu = {}, loopback = {}, virtual = {}, up = {}",
            nif.name(), nif.index(), nif.mtu(), nif.is_loopback(), nif.is_virtual(), nif.is_up()
        );
        if (nif.hardware_address().size() >= 6) {
            niflog.info("   HW: {}", net::ethernet_address(nif.hardware_address().data()));
        }
        for (auto& addr : nif.addresses()) {
            niflog.info("   Addr: {}", addr);
        }
    }

    return make_ready_future();
}

SEASTAR_TEST_CASE(match_ipv6_scope) {
    auto interfaces = engine().net().network_interfaces();

    for (auto& nif : interfaces) {
        if (nif.is_loopback()) {
            continue;
        }
        auto i = std::find_if(nif.addresses().begin(), nif.addresses().end(), std::mem_fn(&net::inet_address::is_ipv6));
        if (i == nif.addresses().end()) {
            continue;
        }

        std::ostringstream ss;
        ss << net::inet_address(i->as_ipv6_address()) << "%" << nif.name();
        auto text = ss.str();

        net::inet_address na(text);

        BOOST_REQUIRE_EQUAL(na.as_ipv6_address(), i->as_ipv6_address());
        // also verify that the inet_address itself matches
        BOOST_REQUIRE_EQUAL(na, *i);
        // and that inet_address _without_ scope matches.
        BOOST_REQUIRE_EQUAL(net::inet_address(na.as_ipv6_address()), *i);
        BOOST_REQUIRE_EQUAL(na.scope(), nif.index());

        niflog.info("Org: {}, Parsed: {}, Text: {}", *i, na, text);

    }

    return make_ready_future();
}
<commit_msg>test: network_interface_test: test that as_ipv4_address throws on ipv6 address<commit_after>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/*
 * Copyright (C) 2019 Cloudius Systems, Ltd.
 */

#include <seastar/testing/test_case.hh>
#include <seastar/net/api.hh>
#include <seastar/net/inet_address.hh>
#include <seastar/net/ethernet.hh>
#include <seastar/net/ip.hh>
#include <seastar/core/reactor.hh>
#include <seastar/core/thread.hh>
#include <seastar/util/log.hh>

using namespace seastar;

static logger niflog("network_interface_test");

SEASTAR_TEST_CASE(list_interfaces) {
    // just verifying we have something. And can access all the stuff.
    auto interfaces = engine().net().network_interfaces();
    BOOST_REQUIRE_GT(interfaces.size(), 0);

    for (auto& nif : interfaces) {
        niflog.info("Iface: {}, index = {}, mtu = {}, loopback = {}, virtual = {}, up = {}",
            nif.name(), nif.index(), nif.mtu(), nif.is_loopback(), nif.is_virtual(), nif.is_up()
        );
        if (nif.hardware_address().size() >= 6) {
            niflog.info("   HW: {}", net::ethernet_address(nif.hardware_address().data()));
        }
        for (auto& addr : nif.addresses()) {
            niflog.info("   Addr: {}", addr);
        }
    }

    return make_ready_future();
}

SEASTAR_TEST_CASE(match_ipv6_scope) {
    auto interfaces = engine().net().network_interfaces();

    for (auto& nif : interfaces) {
        if (nif.is_loopback()) {
            continue;
        }
        auto i = std::find_if(nif.addresses().begin(), nif.addresses().end(), std::mem_fn(&net::inet_address::is_ipv6));
        if (i == nif.addresses().end()) {
            continue;
        }

        std::ostringstream ss;
        ss << net::inet_address(i->as_ipv6_address()) << "%" << nif.name();
        auto text = ss.str();

        net::inet_address na(text);

        BOOST_REQUIRE_EQUAL(na.as_ipv6_address(), i->as_ipv6_address());
        // also verify that the inet_address itself matches
        BOOST_REQUIRE_EQUAL(na, *i);
        // and that inet_address _without_ scope matches.
        BOOST_REQUIRE_EQUAL(net::inet_address(na.as_ipv6_address()), *i);
        BOOST_REQUIRE_EQUAL(na.scope(), nif.index());
        // and that they are not ipv4 addresses
        BOOST_REQUIRE_THROW(i->as_ipv4_address(), std::invalid_argument);
        BOOST_REQUIRE_THROW(na.as_ipv4_address(), std::invalid_argument);

        niflog.info("Org: {}, Parsed: {}, Text: {}", *i, na, text);

    }

    return make_ready_future();
}
<|endoftext|>


<commit_before>#include "AuthenticatedClient.h"

#include <gmock/gmock.h>
#include <memory>

using namespace Instagram;
using namespace testing;

TEST(UserTest, findsUserById)
{
    ClientPtr client = CreateClient("d7b1086490044ada88da482a87b073f3");

    UserPtr user = client->findUserById("1479058533");

    EXPECT_THAT(user->getId(), StrEq("1479058533"));
    EXPECT_THAT(user->getUsername(), StrEq("coconut_beard"));
    EXPECT_THAT(user->getFullName(), StrEq("CB"));
    EXPECT_THAT(user->getProfilePictureUrl(), StrEq("http://photos-c.ak.instagram.com/hphotos-ak-xaf1/10654924_727813450634146_619431088_a.jpg"));
    EXPECT_THAT(user->getBio(), StrEq("I'm bearded."));
    EXPECT_THAT(user->getWebsite(), StrEq("http://en.wikipedia.org/wiki/Beard"));
    EXPECT_THAT(user->getMediaCount(), 2);
    EXPECT_THAT(user->getFollowsCount(), 20);
    EXPECT_THAT(user->getFollowedByCount(), 10);

    user->downloadProfilePicture(user->getUsername() + ".jpg");
}

TEST(FeedTest, getsFeed)
{
    AuthenticatedClientPtr client = CreateAuthenticatedClient("1479058533.d7b1086.6abab8dee8e140afa8ee6b8b7f7318c5");

    MediaList feed = client->getFeed(10);

    for (MediaPtr media : feed)
    {
        const std::string id = media->getId();
        media->getImages()->getStandardResolution()->download(id + ".jpg");
    }
}
<commit_msg>Integration test for getting popular medias<commit_after>#include "AuthenticatedClient.h"

#include <gmock/gmock.h>
#include <memory>

using namespace Instagram;
using namespace testing;

class ClientTest : public Test
{
protected:
    virtual void SetUp()
    {
        client = CreateClient("d7b1086490044ada88da482a87b073f3");
    }

    ClientPtr client;
};

TEST_F(ClientTest, findsUserById)
{
    UserPtr user = client->findUserById("1479058533");

    EXPECT_THAT(user->getId(), StrEq("1479058533"));
    EXPECT_THAT(user->getUsername(), StrEq("coconut_beard"));
    EXPECT_THAT(user->getFullName(), StrEq("CB"));
    EXPECT_THAT(user->getProfilePictureUrl(), StrEq("http://photos-c.ak.instagram.com/hphotos-ak-xaf1/10654924_727813450634146_619431088_a.jpg"));
    EXPECT_THAT(user->getBio(), StrEq("I'm bearded."));
    EXPECT_THAT(user->getWebsite(), StrEq("http://en.wikipedia.org/wiki/Beard"));
    EXPECT_THAT(user->getMediaCount(), 2);
    EXPECT_THAT(user->getFollowsCount(), 20);
    EXPECT_THAT(user->getFollowedByCount(), 10);

    user->downloadProfilePicture(user->getUsername() + ".jpg");
}

TEST_F(ClientTest, getsPopularMedias)
{
    MediaList feed = client->getPopularMedias();

    for (MediaPtr media : feed)
    {
        const std::string id = media->getId();
        media->getImages()->getStandardResolution()->download(id + ".jpg");
    }
}

TEST(FeedTest, getsFeed)
{
    AuthenticatedClientPtr client = CreateAuthenticatedClient("1479058533.d7b1086.6abab8dee8e140afa8ee6b8b7f7318c5");

    MediaList feed = client->getFeed(10);

    for (MediaPtr media : feed)
    {
        const std::string id = media->getId();
        media->getImages()->getStandardResolution()->download(id + ".jpg");
    }
}
<|endoftext|>


<commit_before>//
//  test-MSONValueMemberParser.cc
//  snowcrash
//
//  Created by Pavan Kumar Sunkara on 10/22/14.
//  Copyright (c) 2014 Apiary Inc. All rights reserved.
//

#include "snowcrashtest.h"
#include "MSONValueMemberParser.h"

using namespace snowcrash;
using namespace snowcrashtest;

TEST_CASE("Parse canonical mson value member", "[mson][value_member]")
{
    mdp::ByteBuffer source = \
    "- red (string, required) - A color";

    ParseResult<mson::ValueMember> valueMember;
    SectionParserHelper<mson::ValueMember, MSONValueMemberParser>::parse(source, MSONValueMemberSectionType, valueMember, ExportSourcemapOption);

    REQUIRE(valueMember.report.error.code == Error::OK);
    REQUIRE(valueMember.report.warnings.empty());

    REQUIRE(valueMember.node.description == "A color");
    REQUIRE(valueMember.node.valueDefinition.values.size() == 1);
    REQUIRE(valueMember.node.valueDefinition.values[0].literal == "red");
    REQUIRE(valueMember.node.valueDefinition.typeDefinition.typeSpecification.name.base == mson::StringTypeName);
    REQUIRE(valueMember.node.valueDefinition.typeDefinition.typeSpecification.name.symbol.empty());
    REQUIRE(valueMember.node.valueDefinition.typeDefinition.typeSpecification.nestedTypes.empty());
    REQUIRE(valueMember.node.valueDefinition.typeDefinition.attributes == mson::RequiredTypeAttribute);

    SourceMapHelper::check(valueMember.sourceMap.valueDefinition.sourceMap, 0, 35);
    SourceMapHelper::check(valueMember.sourceMap.description.sourceMap, 0, 35);
}

TEST_CASE("Parse mson value member with description not on new line", "[mson][value_member]")
{
    mdp::ByteBuffer source = \
    "- red (string, required) - A color\n"\
    "  Which is also very nice\n\n";

    ParseResult<mson::ValueMember> valueMember;
    SectionParserHelper<mson::ValueMember, MSONValueMemberParser>::parse(source, MSONValueMemberSectionType, valueMember, ExportSourcemapOption);

    REQUIRE(valueMember.report.error.code == Error::OK);
    REQUIRE(valueMember.report.warnings.empty());

    REQUIRE(valueMember.node.description == "A color");
    REQUIRE(valueMember.node.valueDefinition.values.size() == 1);
    REQUIRE(valueMember.node.sections.size() == 1);
    REQUIRE(valueMember.node.sections[0].klass == mson::TypeSection::BlockDescriptionClass);
    REQUIRE(valueMember.node.sections[0].content.description == "Which is also very nice\n");
    REQUIRE(valueMember.node.sections[0].content.elements().empty());

    SourceMapHelper::check(valueMember.sourceMap.valueDefinition.sourceMap, 0, 62);
    SourceMapHelper::check(valueMember.sourceMap.description.sourceMap, 0, 62);
    REQUIRE(valueMember.sourceMap.sections.collection.size() == 1);
    SourceMapHelper::check(valueMember.sourceMap.sections.collection[0].description.sourceMap, 0, 62);
}

TEST_CASE("Parse mson value member with block description", "[mson][value_member]")
{
    mdp::ByteBuffer source = \
    "- red (string, required) - A color\n\n"\
    "    Which is also very nice\n\n"\
    "    - and awesome\n\n"\
    "and really really nice\n\n";

    ParseResult<mson::ValueMember> valueMember;
    SectionParserHelper<mson::ValueMember, MSONValueMemberParser>::parse(source, MSONValueMemberSectionType, valueMember, ExportSourcemapOption);

    REQUIRE(valueMember.report.error.code == Error::OK);
    REQUIRE(valueMember.report.warnings.empty());

    REQUIRE(valueMember.node.description == "A color");
    REQUIRE(valueMember.node.valueDefinition.values.size() == 1);
    REQUIRE(valueMember.node.valueDefinition.typeDefinition.attributes == mson::RequiredTypeAttribute);
    REQUIRE(valueMember.node.sections.size() == 1);
    REQUIRE(valueMember.node.sections[0].klass == mson::TypeSection::BlockDescriptionClass);
    REQUIRE(valueMember.node.sections[0].content.description == "Which is also very nice\n\n- and awesome\n");

    SourceMapHelper::check(valueMember.sourceMap.valueDefinition.sourceMap, 2, 34);
    SourceMapHelper::check(valueMember.sourceMap.description.sourceMap, 2, 34);
    REQUIRE(valueMember.sourceMap.sections.collection.size() == 1);
    SourceMapHelper::check(valueMember.sourceMap.sections.collection[0].description.sourceMap, 40, 24, 69, 14);
}

TEST_CASE("Parse mson value member with block description, default and sample", "[mson][value_member]")
{
    mdp::ByteBuffer source = \
    "- red (string) - A color\n\n"\
    "    Which is also very nice\n\n"\
    "    - and awesome\n\n"\
    "    - Default: yellow\n"\
    "    - Sample\n\n"\
    "        green\n";

    ParseResult<mson::ValueMember> valueMember;
    SectionParserHelper<mson::ValueMember, MSONValueMemberParser>::parse(source, MSONValueMemberSectionType, valueMember, ExportSourcemapOption);

    REQUIRE(valueMember.report.error.code == Error::OK);
    REQUIRE(valueMember.report.warnings.empty());

    REQUIRE(valueMember.node.description == "A color");
    REQUIRE(valueMember.node.valueDefinition.values.size() == 1);
    REQUIRE(valueMember.node.valueDefinition.values[0].literal == "red");
    REQUIRE(valueMember.node.sections.size() == 3);
    REQUIRE(valueMember.node.sections[0].klass == mson::TypeSection::BlockDescriptionClass);
    REQUIRE(valueMember.node.sections[0].content.description == "Which is also very nice\n\n- and awesome\n");
    REQUIRE(valueMember.node.sections[1].klass == mson::TypeSection::DefaultClass);
    REQUIRE(valueMember.node.sections[1].content.value == "yellow");
    REQUIRE(valueMember.node.sections[2].klass == mson::TypeSection::SampleClass);
    REQUIRE(valueMember.node.sections[2].content.value == "green\n");

    SourceMapHelper::check(valueMember.sourceMap.valueDefinition.sourceMap, 2, 24);
    SourceMapHelper::check(valueMember.sourceMap.description.sourceMap, 2, 24);
    REQUIRE(valueMember.sourceMap.sections.collection.size() == 3);
    SourceMapHelper::check(valueMember.sourceMap.sections.collection[0].description.sourceMap, 30, 24, 59, 14);
    SourceMapHelper::check(valueMember.sourceMap.sections.collection[1].value.sourceMap, 80, 16);
    SourceMapHelper::check(valueMember.sourceMap.sections.collection[2].value.sourceMap, 118, 6);
}

TEST_CASE("Parse mson value member array with sample", "[mson][value_member]")
{
    mdp::ByteBuffer source = \
    "- (array) - List of colors\n\n"\
    "    Lots and lots of them\n\n"\
    "    - Sample\n"\
    "        - green\n"\
    "        - red\n"\
    "        - blue\n"\
    "        - yellow\n";

    ParseResult<mson::ValueMember> valueMember;
    SectionParserHelper<mson::ValueMember, MSONValueMemberParser>::parse(source, MSONValueMemberSectionType, valueMember, ExportSourcemapOption);

    REQUIRE(valueMember.report.error.code == Error::OK);
    REQUIRE(valueMember.report.warnings.empty());

    REQUIRE(valueMember.node.description == "List of colors");
    REQUIRE(valueMember.node.valueDefinition.values.empty());
    REQUIRE(valueMember.node.sections.size() == 2);
    REQUIRE(valueMember.node.sections[0].klass == mson::TypeSection::BlockDescriptionClass);
    REQUIRE(valueMember.node.sections[0].content.description == "Lots and lots of them\n");
    REQUIRE(valueMember.node.sections[1].klass == mson::TypeSection::SampleClass);
    REQUIRE(valueMember.node.sections[1].content.elements().size() == 4);

    SourceMapHelper::check(valueMember.sourceMap.valueDefinition.sourceMap, 2, 26);
    SourceMapHelper::check(valueMember.sourceMap.description.sourceMap, 2, 26);
    REQUIRE(valueMember.sourceMap.sections.collection.size() == 2);
    SourceMapHelper::check(valueMember.sourceMap.sections.collection[0].description.sourceMap, 32, 22);
    REQUIRE(valueMember.sourceMap.sections.collection[1].elements().collection.size() == 4);
}

TEST_CASE("Parse mson value member with multiple values", "[mson][value_member]")
{
    mdp::ByteBuffer source = \
    "- 1, yellow, true";

    ParseResult<mson::ValueMember> valueMember;
    SectionParserHelper<mson::ValueMember, MSONValueMemberParser>::parse(source, MSONValueMemberSectionType, valueMember, ExportSourcemapOption);

    REQUIRE(valueMember.report.error.code == Error::OK);
    REQUIRE(valueMember.report.warnings.empty());

    REQUIRE(valueMember.node.description.empty());
    REQUIRE(valueMember.node.sections.empty());
    REQUIRE(valueMember.node.valueDefinition.values.size() == 3);
    REQUIRE(valueMember.node.valueDefinition.values[0].literal == "1");
    REQUIRE(valueMember.node.valueDefinition.values[1].literal == "yellow");
    REQUIRE(valueMember.node.valueDefinition.values[2].literal == "true");

    SourceMapHelper::check(valueMember.sourceMap.valueDefinition.sourceMap, 0, 18);
    REQUIRE(valueMember.sourceMap.description.sourceMap.empty());
    REQUIRE(valueMember.sourceMap.sections.collection.empty());
}

TEST_CASE("Parse mson value member array with items", "[mson][value_member]")
{
    mdp::ByteBuffer source = \
    "- (array)\n"\
    "    - red (string) - A sample value\n"\
    "    - green (string)";

    ParseResult<mson::ValueMember> valueMember;
    SectionParserHelper<mson::ValueMember, MSONValueMemberParser>::parse(source, MSONValueMemberSectionType, valueMember, ExportSourcemapOption);

    REQUIRE(valueMember.report.error.code == Error::OK);
    REQUIRE(valueMember.report.warnings.empty());

    REQUIRE(valueMember.node.description.empty());
    REQUIRE(valueMember.node.valueDefinition.values.empty());
    REQUIRE(valueMember.node.valueDefinition.typeDefinition.typeSpecification.name.base == mson::ArrayTypeName);
    REQUIRE(valueMember.node.sections.size() == 1);

    REQUIRE(valueMember.node.sections[0].content.description.empty());
    REQUIRE(valueMember.node.sections[0].klass == mson::TypeSection::MemberTypeClass);
    REQUIRE(valueMember.node.sections[0].content.elements().size() == 2);
    REQUIRE(valueMember.node.sections[0].content.elements().at(0).klass == mson::Element::ValueClass);
    REQUIRE(valueMember.node.sections[0].content.elements().at(0).content.value.valueDefinition.values.size() == 1);
    REQUIRE(valueMember.node.sections[0].content.elements().at(0).content.value.description == "A sample value");
    REQUIRE(valueMember.node.sections[0].content.elements().at(1).klass == mson::Element::ValueClass);
    REQUIRE(valueMember.node.sections[0].content.elements().at(1).content.value.valueDefinition.values.size() == 1);

    SourceMapHelper::check(valueMember.sourceMap.valueDefinition.sourceMap, 2, 8);
    REQUIRE(valueMember.sourceMap.sections.collection.size() == 1);
    REQUIRE(valueMember.sourceMap.sections.collection[0].elements().collection.size() == 2);

    SourceMap<mson::ValueMember> valueMemberSM;

    valueMemberSM = valueMember.sourceMap.sections.collection[0].elements().collection[0].value;
    SourceMapHelper::check(valueMemberSM.valueDefinition.sourceMap, 16, 30);
    SourceMapHelper::check(valueMemberSM.description.sourceMap, 16, 30);

    valueMemberSM = valueMember.sourceMap.sections.collection[0].elements().collection[1].value;
    SourceMapHelper::check(valueMemberSM.valueDefinition.sourceMap, 50, 17);
}

TEST_CASE("Check warnings for object in array with defined value", "[mson][value_member]")
{
    mdp::ByteBuffer source = \
    "- (array)\n"\
    "    - explicit (object)\n"\
    "    - implicit\n"\
    "        - k: v\n";

    ParseResult<mson::ValueMember> valueMember;
    SectionParserHelper<mson::ValueMember, MSONValueMemberParser>::parse(source, MSONValueMemberSectionType, valueMember, ExportSourcemapOption);

    REQUIRE(valueMember.report.error.code == Error::OK);
    REQUIRE(valueMember.report.warnings.size() == 2);

}
<commit_msg>Add test for apiaryio/snowcrash#387<commit_after>//
//  test-MSONValueMemberParser.cc
//  snowcrash
//
//  Created by Pavan Kumar Sunkara on 10/22/14.
//  Copyright (c) 2014 Apiary Inc. All rights reserved.
//

#include "snowcrashtest.h"
#include "MSONValueMemberParser.h"

using namespace snowcrash;
using namespace snowcrashtest;

TEST_CASE("Parse canonical mson value member", "[mson][value_member]")
{
    mdp::ByteBuffer source = \
    "- red (string, required) - A color";

    ParseResult<mson::ValueMember> valueMember;
    SectionParserHelper<mson::ValueMember, MSONValueMemberParser>::parse(source, MSONValueMemberSectionType, valueMember, ExportSourcemapOption);

    REQUIRE(valueMember.report.error.code == Error::OK);
    REQUIRE(valueMember.report.warnings.empty());

    REQUIRE(valueMember.node.description == "A color");
    REQUIRE(valueMember.node.valueDefinition.values.size() == 1);
    REQUIRE(valueMember.node.valueDefinition.values[0].literal == "red");
    REQUIRE(valueMember.node.valueDefinition.typeDefinition.typeSpecification.name.base == mson::StringTypeName);
    REQUIRE(valueMember.node.valueDefinition.typeDefinition.typeSpecification.name.symbol.empty());
    REQUIRE(valueMember.node.valueDefinition.typeDefinition.typeSpecification.nestedTypes.empty());
    REQUIRE(valueMember.node.valueDefinition.typeDefinition.attributes == mson::RequiredTypeAttribute);

    SourceMapHelper::check(valueMember.sourceMap.valueDefinition.sourceMap, 0, 35);
    SourceMapHelper::check(valueMember.sourceMap.description.sourceMap, 0, 35);
}

TEST_CASE("Parse mson value member with description not on new line", "[mson][value_member]")
{
    mdp::ByteBuffer source = \
    "- red (string, required) - A color\n"\
    "  Which is also very nice\n\n";

    ParseResult<mson::ValueMember> valueMember;
    SectionParserHelper<mson::ValueMember, MSONValueMemberParser>::parse(source, MSONValueMemberSectionType, valueMember, ExportSourcemapOption);

    REQUIRE(valueMember.report.error.code == Error::OK);
    REQUIRE(valueMember.report.warnings.empty());

    REQUIRE(valueMember.node.description == "A color");
    REQUIRE(valueMember.node.valueDefinition.values.size() == 1);
    REQUIRE(valueMember.node.sections.size() == 1);
    REQUIRE(valueMember.node.sections[0].klass == mson::TypeSection::BlockDescriptionClass);
    REQUIRE(valueMember.node.sections[0].content.description == "Which is also very nice\n");
    REQUIRE(valueMember.node.sections[0].content.elements().empty());

    SourceMapHelper::check(valueMember.sourceMap.valueDefinition.sourceMap, 0, 62);
    SourceMapHelper::check(valueMember.sourceMap.description.sourceMap, 0, 62);
    REQUIRE(valueMember.sourceMap.sections.collection.size() == 1);
    SourceMapHelper::check(valueMember.sourceMap.sections.collection[0].description.sourceMap, 0, 62);
}

TEST_CASE("Parse mson value member with block description", "[mson][value_member]")
{
    mdp::ByteBuffer source = \
    "- red (string, required) - A color\n\n"\
    "    Which is also very nice\n\n"\
    "    - and awesome\n\n"\
    "and really really nice\n\n";

    ParseResult<mson::ValueMember> valueMember;
    SectionParserHelper<mson::ValueMember, MSONValueMemberParser>::parse(source, MSONValueMemberSectionType, valueMember, ExportSourcemapOption);

    REQUIRE(valueMember.report.error.code == Error::OK);
    REQUIRE(valueMember.report.warnings.empty());

    REQUIRE(valueMember.node.description == "A color");
    REQUIRE(valueMember.node.valueDefinition.values.size() == 1);
    REQUIRE(valueMember.node.valueDefinition.typeDefinition.attributes == mson::RequiredTypeAttribute);
    REQUIRE(valueMember.node.sections.size() == 1);
    REQUIRE(valueMember.node.sections[0].klass == mson::TypeSection::BlockDescriptionClass);
    REQUIRE(valueMember.node.sections[0].content.description == "Which is also very nice\n\n- and awesome\n");

    SourceMapHelper::check(valueMember.sourceMap.valueDefinition.sourceMap, 2, 34);
    SourceMapHelper::check(valueMember.sourceMap.description.sourceMap, 2, 34);
    REQUIRE(valueMember.sourceMap.sections.collection.size() == 1);
    SourceMapHelper::check(valueMember.sourceMap.sections.collection[0].description.sourceMap, 40, 24, 69, 14);
}

TEST_CASE("Parse mson value member with block description, default and sample", "[mson][value_member]")
{
    mdp::ByteBuffer source = \
    "- red (string) - A color\n\n"\
    "    Which is also very nice\n\n"\
    "    - and awesome\n\n"\
    "    - Default: yellow\n"\
    "    - Sample\n\n"\
    "        green\n";

    ParseResult<mson::ValueMember> valueMember;
    SectionParserHelper<mson::ValueMember, MSONValueMemberParser>::parse(source, MSONValueMemberSectionType, valueMember, ExportSourcemapOption);

    REQUIRE(valueMember.report.error.code == Error::OK);
    REQUIRE(valueMember.report.warnings.empty());

    REQUIRE(valueMember.node.description == "A color");
    REQUIRE(valueMember.node.valueDefinition.values.size() == 1);
    REQUIRE(valueMember.node.valueDefinition.values[0].literal == "red");
    REQUIRE(valueMember.node.sections.size() == 3);
    REQUIRE(valueMember.node.sections[0].klass == mson::TypeSection::BlockDescriptionClass);
    REQUIRE(valueMember.node.sections[0].content.description == "Which is also very nice\n\n- and awesome\n");
    REQUIRE(valueMember.node.sections[1].klass == mson::TypeSection::DefaultClass);
    REQUIRE(valueMember.node.sections[1].content.value == "yellow");
    REQUIRE(valueMember.node.sections[2].klass == mson::TypeSection::SampleClass);
    REQUIRE(valueMember.node.sections[2].content.value == "green\n");

    SourceMapHelper::check(valueMember.sourceMap.valueDefinition.sourceMap, 2, 24);
    SourceMapHelper::check(valueMember.sourceMap.description.sourceMap, 2, 24);
    REQUIRE(valueMember.sourceMap.sections.collection.size() == 3);
    SourceMapHelper::check(valueMember.sourceMap.sections.collection[0].description.sourceMap, 30, 24, 59, 14);
    SourceMapHelper::check(valueMember.sourceMap.sections.collection[1].value.sourceMap, 80, 16);
    SourceMapHelper::check(valueMember.sourceMap.sections.collection[2].value.sourceMap, 118, 6);
}

TEST_CASE("Parse mson value member array with sample", "[mson][value_member]")
{
    mdp::ByteBuffer source = \
    "- (array) - List of colors\n\n"\
    "    Lots and lots of them\n\n"\
    "    - Sample\n"\
    "        - green\n"\
    "        - red\n"\
    "        - blue\n"\
    "        - yellow\n";

    ParseResult<mson::ValueMember> valueMember;
    SectionParserHelper<mson::ValueMember, MSONValueMemberParser>::parse(source, MSONValueMemberSectionType, valueMember, ExportSourcemapOption);

    REQUIRE(valueMember.report.error.code == Error::OK);
    REQUIRE(valueMember.report.warnings.empty());

    REQUIRE(valueMember.node.description == "List of colors");
    REQUIRE(valueMember.node.valueDefinition.values.empty());
    REQUIRE(valueMember.node.sections.size() == 2);
    REQUIRE(valueMember.node.sections[0].klass == mson::TypeSection::BlockDescriptionClass);
    REQUIRE(valueMember.node.sections[0].content.description == "Lots and lots of them\n");
    REQUIRE(valueMember.node.sections[1].klass == mson::TypeSection::SampleClass);
    REQUIRE(valueMember.node.sections[1].content.elements().size() == 4);

    SourceMapHelper::check(valueMember.sourceMap.valueDefinition.sourceMap, 2, 26);
    SourceMapHelper::check(valueMember.sourceMap.description.sourceMap, 2, 26);
    REQUIRE(valueMember.sourceMap.sections.collection.size() == 2);
    SourceMapHelper::check(valueMember.sourceMap.sections.collection[0].description.sourceMap, 32, 22);
    REQUIRE(valueMember.sourceMap.sections.collection[1].elements().collection.size() == 4);
}

TEST_CASE("Parse mson value member with multiple values", "[mson][value_member]")
{
    mdp::ByteBuffer source = \
    "- 1, yellow, true";

    ParseResult<mson::ValueMember> valueMember;
    SectionParserHelper<mson::ValueMember, MSONValueMemberParser>::parse(source, MSONValueMemberSectionType, valueMember, ExportSourcemapOption);

    REQUIRE(valueMember.report.error.code == Error::OK);
    REQUIRE(valueMember.report.warnings.empty());

    REQUIRE(valueMember.node.description.empty());
    REQUIRE(valueMember.node.sections.empty());
    REQUIRE(valueMember.node.valueDefinition.values.size() == 3);
    REQUIRE(valueMember.node.valueDefinition.values[0].literal == "1");
    REQUIRE(valueMember.node.valueDefinition.values[1].literal == "yellow");
    REQUIRE(valueMember.node.valueDefinition.values[2].literal == "true");

    SourceMapHelper::check(valueMember.sourceMap.valueDefinition.sourceMap, 0, 18);
    REQUIRE(valueMember.sourceMap.description.sourceMap.empty());
    REQUIRE(valueMember.sourceMap.sections.collection.empty());
}

TEST_CASE("Parse mson value member array with items", "[mson][value_member]")
{
    mdp::ByteBuffer source = \
    "- (array)\n"\
    "    - red (string) - A sample value\n"\
    "    - green (string)";

    ParseResult<mson::ValueMember> valueMember;
    SectionParserHelper<mson::ValueMember, MSONValueMemberParser>::parse(source, MSONValueMemberSectionType, valueMember, ExportSourcemapOption);

    REQUIRE(valueMember.report.error.code == Error::OK);
    REQUIRE(valueMember.report.warnings.empty());

    REQUIRE(valueMember.node.description.empty());
    REQUIRE(valueMember.node.valueDefinition.values.empty());
    REQUIRE(valueMember.node.valueDefinition.typeDefinition.typeSpecification.name.base == mson::ArrayTypeName);
    REQUIRE(valueMember.node.sections.size() == 1);

    REQUIRE(valueMember.node.sections[0].content.description.empty());
    REQUIRE(valueMember.node.sections[0].klass == mson::TypeSection::MemberTypeClass);
    REQUIRE(valueMember.node.sections[0].content.elements().size() == 2);
    REQUIRE(valueMember.node.sections[0].content.elements().at(0).klass == mson::Element::ValueClass);
    REQUIRE(valueMember.node.sections[0].content.elements().at(0).content.value.valueDefinition.values.size() == 1);
    REQUIRE(valueMember.node.sections[0].content.elements().at(0).content.value.description == "A sample value");
    REQUIRE(valueMember.node.sections[0].content.elements().at(1).klass == mson::Element::ValueClass);
    REQUIRE(valueMember.node.sections[0].content.elements().at(1).content.value.valueDefinition.values.size() == 1);

    SourceMapHelper::check(valueMember.sourceMap.valueDefinition.sourceMap, 2, 8);
    REQUIRE(valueMember.sourceMap.sections.collection.size() == 1);
    REQUIRE(valueMember.sourceMap.sections.collection[0].elements().collection.size() == 2);

    SourceMap<mson::ValueMember> valueMemberSM;

    valueMemberSM = valueMember.sourceMap.sections.collection[0].elements().collection[0].value;
    SourceMapHelper::check(valueMemberSM.valueDefinition.sourceMap, 16, 30);
    SourceMapHelper::check(valueMemberSM.description.sourceMap, 16, 30);

    valueMemberSM = valueMember.sourceMap.sections.collection[0].elements().collection[1].value;
    SourceMapHelper::check(valueMemberSM.valueDefinition.sourceMap, 50, 17);
}

TEST_CASE("Check warnings for object in array with defined value", "[mson][value_member]")
{
    mdp::ByteBuffer source = \
    "- (array)\n"\
    "    - explicit (object)\n"\
    "    - implicit\n"\
    "        - k: v\n";

    ParseResult<mson::ValueMember> valueMember;
    SectionParserHelper<mson::ValueMember, MSONValueMemberParser>::parse(source, MSONValueMemberSectionType, valueMember, ExportSourcemapOption);

    REQUIRE(valueMember.report.error.code == Error::OK);
    REQUIRE(valueMember.report.warnings.size() == 2);

}

TEST_CASE("Check warnings for object with defined value", "[mson][value_member]")
{
    mdp::ByteBuffer source = \
    "- (object)\n"\
    "    - k: v (object)\n";

    ParseResult<mson::ValueMember> valueMember;
    SectionParserHelper<mson::ValueMember, MSONValueMemberParser>::parse(source, MSONValueMemberSectionType, valueMember, ExportSourcemapOption);

    REQUIRE(valueMember.report.error.code == Error::OK);
    REQUIRE(valueMember.report.warnings.size() == 1);

}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <tightdb.h>
#include <UnitTest++.h>
#include <assert.h>
#include "../Support/mem.h"
#include "../Support/number_names.h"

#define OLD_TEST

#ifndef OLD_TEST

uint64_t rand2() {
	return (uint64_t)rand()*(uint64_t)rand()*(uint64_t)rand()*(uint64_t)rand()*rand();
}

TDB_TABLE_1(IntegerTable,
			Int,        first)

void main(void) {
	IntegerTable integers;
	UnitTest::Timer timer;
	volatile uint64_t write;

	uint64_t dummy = 0;
	int ITEMS = 10000;

	integers.Clear();
	integers.SetIndex(0);

	timer.Start();
	for (size_t i = 0; i < ITEMS; ++i) {
		dummy += rand2() + rand2() % (i + 1);
	}
	write = dummy;
	printf("Rand: %d ms\n", timer.GetTimeInMs());

	timer.Start();
	for (size_t i = 0; i < ITEMS; ++i) {
		size_t p = rand2() % (i + 1);
		integers.Add((int64_t)rand2());
	}
	printf("Add: %d ms\n", timer.GetTimeInMs());

	integers.Clear();
	timer.Start();
	for (size_t i = 0; i < ITEMS; ++i) {
		size_t p = rand2() % (i + 1);
		integers.InsertInt(0, p, (int64_t)rand2());
	}
	printf("Insert: %d ms\n", timer.GetTimeInMs());

	timer.Start();
	for (size_t i = 0; i < ITEMS; ++i) {
		size_t p = rand2() % ITEMS;
		dummy += p;
	}
	write = dummy;
	printf("Rand: %d ms\n", timer.GetTimeInMs());

	timer.Start();
	for (size_t i = 0; i < ITEMS; ++i) {
		size_t p = rand2() % ITEMS;
		dummy += integers.Get64(0, p);
	}
	write = dummy;
	printf("Get: %d ms\n", timer.GetTimeInMs());

	timer.Start();
	for (size_t i = 0; i < ITEMS; ++i) {
		size_t p = rand2() % ITEMS;
		integers.Set64(0, p, rand2());
	}
	write = dummy;
	printf("Set: %d ms\n", timer.GetTimeInMs());

	timer.Start();
	for (size_t i = 0; i < ITEMS; ++i) {
		integers.first.Find(rand2());
	}
	write = dummy;
	printf("Find: %d ms\n", timer.GetTimeInMs());

	timer.Start();
	for (size_t i = 0; i < ITEMS; ++i) {
		size_t p = rand2() % (ITEMS - i);
		integers.DeleteRow(p);
	}
	printf("Delete: %d ms\n", timer.GetTimeInMs());

	getchar();
	exit(-1);

}

#else

enum Days {
	Mon,
	Tue,
	Wed,
	Thu,
	Fri,
	Sat,
	Sun
};

TDB_TABLE_4(TestTable,
			Int,        first,
			String,     second,
			Int,        third,
			Enum<Days>, fourth)

int main() {

	TestTable table;

	// Build large table
	for (size_t i = 0; i < 250000; ++i) {
		// create random string
		const size_t n = rand() % 1000;// * 10 + rand();
		const string s = number_name(n);

		table.Add(n, s.c_str(), 100, Wed);
	}
	table.Add(0, "abcde", 100, Wed);

	printf("Memory usage: %zu bytes\n", GetMemUsage());

	UnitTest::Timer timer;

	// Search small integer column
	{
		timer.Start();

		// Do a search over entire column (value not found)
		for (size_t i = 0; i < 100; ++i) {
			const size_t res = table.fourth.Find(Tue);
			if (res != -1) {
				printf("error");
			}
		}

		const int search_time = timer.GetTimeInMs();
		printf("Search (small integer): %dms\n", search_time);
	}

	// Search byte-size integer column
	{
		timer.Start();

		// Do a search over entire column (value not found)
		for (size_t i = 0; i < 100; ++i) {
			const size_t res = table.third.Find(50);
			if (res != -1) {
				printf("error");
			}
		}

		const int search_time = timer.GetTimeInMs();
		printf("Search (byte-size integer): %dms\n", search_time);
	}

	// Search string column
	{
		timer.Start();

		// Do a search over entire column (value not found)
		for (size_t i = 0; i < 100; ++i) {
			const size_t res = table.second.Find("abcde");
			if (res != 250000) {
				printf("error");
			}
		}

		const int search_time = timer.GetTimeInMs();
		printf("Search (string): %dms\n", search_time);
	}

	// Add index
	{
		timer.Start();

		table.SetIndex(0);

		const int search_time = timer.GetTimeInMs();
		printf("Add index: %dms\n", search_time);
	}

	printf("Memory usage2: %zu bytes\n", GetMemUsage());

	// Search with index
	{
		timer.Start();

		for (size_t i = 0; i < 100000; ++i) {
			const size_t n = rand() % 1000;
			const size_t res = table.first.Find(n);
			if (res == 2500002) { // to avoid above find being optimized away
				printf("error");
			}
		}

		const int search_time = timer.GetTimeInMs();
		printf("Search index: %dms\n", search_time);
	}

	//getchar(); // wait for key
	//return 1;
}

#endif
<commit_msg>Changed %zu to %lld in test-* (%zu doesn't work in vc)<commit_after>#include <stdio.h>
#include <tightdb.h>
#include <UnitTest++.h>
#include <assert.h>
#include "../Support/mem.h"
#include "../Support/number_names.h"

#define OLD_TEST

#ifndef OLD_TEST

uint64_t rand2() {
	return (uint64_t)rand()*(uint64_t)rand()*(uint64_t)rand()*(uint64_t)rand()*rand();
}

TDB_TABLE_1(IntegerTable,
			Int,        first)

void main(void) {
	IntegerTable integers;
	UnitTest::Timer timer;
	volatile uint64_t write;

	uint64_t dummy = 0;
	int ITEMS = 10000;

	integers.Clear();
	integers.SetIndex(0);

	timer.Start();
	for (size_t i = 0; i < ITEMS; ++i) {
		dummy += rand2() + rand2() % (i + 1);
	}
	write = dummy;
	printf("Rand: %d ms\n", timer.GetTimeInMs());

	timer.Start();
	for (size_t i = 0; i < ITEMS; ++i) {
		size_t p = rand2() % (i + 1);
		integers.Add((int64_t)rand2());
	}
	printf("Add: %d ms\n", timer.GetTimeInMs());

	integers.Clear();
	timer.Start();
	for (size_t i = 0; i < ITEMS; ++i) {
		size_t p = rand2() % (i + 1);
		integers.InsertInt(0, p, (int64_t)rand2());
	}
	printf("Insert: %d ms\n", timer.GetTimeInMs());

	timer.Start();
	for (size_t i = 0; i < ITEMS; ++i) {
		size_t p = rand2() % ITEMS;
		dummy += p;
	}
	write = dummy;
	printf("Rand: %d ms\n", timer.GetTimeInMs());

	timer.Start();
	for (size_t i = 0; i < ITEMS; ++i) {
		size_t p = rand2() % ITEMS;
		dummy += integers.Get64(0, p);
	}
	write = dummy;
	printf("Get: %d ms\n", timer.GetTimeInMs());

	timer.Start();
	for (size_t i = 0; i < ITEMS; ++i) {
		size_t p = rand2() % ITEMS;
		integers.Set64(0, p, rand2());
	}
	write = dummy;
	printf("Set: %d ms\n", timer.GetTimeInMs());

	timer.Start();
	for (size_t i = 0; i < ITEMS; ++i) {
		integers.first.Find(rand2());
	}
	write = dummy;
	printf("Find: %d ms\n", timer.GetTimeInMs());

	timer.Start();
	for (size_t i = 0; i < ITEMS; ++i) {
		size_t p = rand2() % (ITEMS - i);
		integers.DeleteRow(p);
	}
	printf("Delete: %d ms\n", timer.GetTimeInMs());

	getchar();
	exit(-1);

}

#else

enum Days {
	Mon,
	Tue,
	Wed,
	Thu,
	Fri,
	Sat,
	Sun
};

TDB_TABLE_4(TestTable,
			Int,        first,
			String,     second,
			Int,        third,
			Enum<Days>, fourth)

int main() {

	TestTable table;

	// Build large table
	for (size_t i = 0; i < 250000; ++i) {
		// create random string
		const size_t n = rand() % 1000;// * 10 + rand();
		const string s = number_name(n);

		table.Add(n, s.c_str(), 100, Wed);
	}
	table.Add(0, "abcde", 100, Wed);

	printf("Memory usage: %lld bytes\n", (int64_t)GetMemUsage()); // %zu doesn't work in vc

	UnitTest::Timer timer;

	// Search small integer column
	{
		timer.Start();

		// Do a search over entire column (value not found)
		for (size_t i = 0; i < 100; ++i) {
			const size_t res = table.fourth.Find(Tue);
			if (res != -1) {
				printf("error");
			}
		}

		const int search_time = timer.GetTimeInMs();
		printf("Search (small integer): %dms\n", search_time);
	}

	// Search byte-size integer column
	{
		timer.Start();

		// Do a search over entire column (value not found)
		for (size_t i = 0; i < 100; ++i) {
			const size_t res = table.third.Find(50);
			if (res != -1) {
				printf("error");
			}
		}

		const int search_time = timer.GetTimeInMs();
		printf("Search (byte-size integer): %dms\n", search_time);
	}

	// Search string column
	{
		timer.Start();

		// Do a search over entire column (value not found)
		for (size_t i = 0; i < 100; ++i) {
			const size_t res = table.second.Find("abcde");
			if (res != 250000) {
				printf("error");
			}
		}

		const int search_time = timer.GetTimeInMs();
		printf("Search (string): %dms\n", search_time);
	}

	// Add index
	{
		timer.Start();

		table.SetIndex(0);

		const int search_time = timer.GetTimeInMs();
		printf("Add index: %dms\n", search_time);
	}

	printf("Memory usage2: %lld bytes\n", (int64_t)GetMemUsage()); // %zu doesn't work in vc

	// Search with index
	{
		timer.Start();

		for (size_t i = 0; i < 100000; ++i) {
			const size_t n = rand() % 1000;
			const size_t res = table.first.Find(n);
			if (res == 2500002) { // to avoid above find being optimized away
				printf("error");
			}
		}

		const int search_time = timer.GetTimeInMs();
		printf("Search index: %dms\n", search_time);
	}

	//getchar(); // wait for key
	//return 1;
}

#endif
<|endoftext|>


<commit_before><commit_msg>axial special case fix<commit_after><|endoftext|>