<commit_before>#include "Queue.hpp"

#include <mutex>

#if M_OS == M_OS_LINUX
#	include <sys/eventfd.h>
#	include <cstring>
#endif

//#define M_ENABLE_QUEUE_TRACE
#ifdef M_ENABLE_QUEUE_TRACE
#	define M_QUEUE_TRACE(x) TRACE(<< "[QUEUE] ") TRACE(x)
#else
#	define M_QUEUE_TRACE(x)
#endif

using namespace nitki;

Queue::Queue(){
	//can write will always be set because it is always possible to post a message to the queue
	this->setCanWriteFlag();

#if M_OS == M_OS_WINDOWS
	this->eventForWaitable = CreateEvent(
			NULL, //security attributes
			TRUE, //manual-reset
			FALSE, //not signalled initially
			NULL //no name
		);
	if(this->eventForWaitable == NULL){
		throw utki::Exc("Queue::Queue(): could not create event (Win32) for implementing Waitable");
	}
#elif M_OS == M_OS_MACOSX
	if(::pipe(&this->pipeEnds[0]) < 0){
		std::stringstream ss;
		ss << "Queue::Queue(): could not create pipe (*nix) for implementing Waitable,"
				<< " error code = " << errno << ": " << strerror(errno);
		TRACE(<< ss.str() << std::endl)
		throw utki::Exc(ss.str().c_str());
	}
#elif M_OS == M_OS_LINUX
	this->eventFD = eventfd(0, EFD_NONBLOCK);
	if(this->eventFD < 0){
		std::stringstream ss;
		ss << "Queue::Queue(): could not create eventfd (linux) for implementing Waitable,"
				<< " error code = " << errno << ": " << strerror(errno);
		throw utki::Exc(ss.str().c_str());
	}
#else
#	error "Unsupported OS"
#endif
}

Queue::~Queue()noexcept{
#if M_OS == M_OS_WINDOWS
	CloseHandle(this->eventForWaitable);
#elif M_OS == M_OS_MACOSX
	close(this->pipeEnds[0]);
	close(this->pipeEnds[1]);
#elif M_OS == M_OS_LINUX
	close(this->eventFD);
#else
#	error "Unsupported OS"
#endif
}

void Queue::pushMessage(std::function<void()>&& msg)noexcept{
	std::lock_guard<decltype(this->mut)> mutexGuard(this->mut);
	this->messages.push_back(std::move(msg));

	if(this->messages.size() == 1){//if it is a first message
		//Set CanRead flag.
		//NOTE: in linux implementation with epoll(), the CanRead
		//flag will also be set in WaitSet::Wait() method.
		//NOTE: set CanRead flag before event notification/pipe write, because
		//if do it after then some other thread which was waiting on the WaitSet
		//may read the CanRead flag while it was not set yet.
		ASSERT(!this->canRead())
		this->setCanReadFlag();

#if M_OS == M_OS_WINDOWS
		if(SetEvent(this->eventForWaitable) == 0){
			ASSERT(false)
		}
#elif M_OS == M_OS_MACOSX
		{
			std::uint8_t oneByteBuf[1];
			if(write(this->pipeEnds[1], oneByteBuf, 1) != 1){
				ASSERT(false)
			}
		}
#elif M_OS == M_OS_LINUX
		if(eventfd_write(this->eventFD, 1) < 0){
			ASSERT(false)
		}
#else
#	error "Unsupported OS"
#endif
	}

	ASSERT(this->canRead())
}

Queue::T_Message Queue::peekMsg(){
	std::lock_guard<decltype(this->mut)> mutexGuard(this->mut);
	if(this->messages.size() != 0){
		ASSERT(this->canRead())

		if(this->messages.size() == 1){//if we are taking away the last message from the queue
#if M_OS == M_OS_WINDOWS
			if(ResetEvent(this->eventForWaitable) == 0){
				ASSERT(false)
				throw utki::Exc("Queue::Wait(): ResetEvent() failed");
			}
#elif M_OS == M_OS_MACOSX
			{
				std::uint8_t oneByteBuf[1];
				if(read(this->pipeEnds[0], oneByteBuf, 1) != 1){
					throw utki::Exc("Queue::Wait(): read() failed");
				}
			}
#elif M_OS == M_OS_LINUX
			{
				eventfd_t value;
				if(eventfd_read(this->eventFD, &value) < 0){
					throw utki::Exc("Queue::Wait(): eventfd_read() failed");
				}
				ASSERT(value == 1)
			}
#else
#	error "Unsupported OS"
#endif
			this->clearCanReadFlag();
		}else{
			ASSERT(this->canRead())
		}

		T_Message ret = std::move(this->messages.front());

		this->messages.pop_front();

		return std::move(ret);
	}
	return nullptr;
}

#if M_OS == M_OS_WINDOWS
HANDLE Queue::getHandle(){
	//return event handle
	return this->eventForWaitable;
}

void Queue::setWaitingEvents(std::uint32_t flagsToWaitFor){
	//It is not allowed to wait on queue for write,
	//because it is always possible to push new message to queue.
	//Error condition is not possible for Queue.
	//Thus, only possible flag values are READ and 0 (NOT_READY)
	if(flagsToWaitFor != 0 && flagsToWaitFor != pogodi::Waitable::READ){
		ASSERT_INFO(false, "flagsToWaitFor = " << flagsToWaitFor)
		throw utki::Exc("Queue::SetWaitingEvents(): flagsToWaitFor should be pogodi::Waitable::READ or 0, other values are not allowed");
	}

	this->flagsMask = flagsToWaitFor;
}

//returns true if signaled
bool Queue::checkSignaled(){
	//error condition is not possible for queue
	ASSERT((this->readinessFlags & pogodi::Waitable::ERROR_CONDITION) == 0)

/*
#ifdef DEBUG
	{
		atomic::SpinLock::GuardYield mutexGuard(this->mut);
		if(this->first){
			ASSERT_ALWAYS(this->CanRead())

			//event should be in signalled state
			ASSERT_ALWAYS(WaitForSingleObject(this->eventForWaitable, 0) == WAIT_OBJECT_0)
		}

		if(this->CanRead()){
			ASSERT_ALWAYS(this->first)

			//event should be in signalled state
			ASSERT_ALWAYS(WaitForSingleObject(this->eventForWaitable, 0) == WAIT_OBJECT_0)
		}

		//if event is in signalled state
		if(WaitForSingleObject(this->eventForWaitable, 0) == WAIT_OBJECT_0){
			ASSERT_ALWAYS(this->CanRead())
			ASSERT_ALWAYS(this->first)
		}
	}
#endif
*/

	return (this->readinessFlags & this->flagsMask) != 0;
}

#elif M_OS == M_OS_MACOSX
//override
int Queue::getHandle(){
	//return read end of pipe
	return this->pipeEnds[0];
}

#elif M_OS == M_OS_LINUX
//override
int Queue::getHandle(){
	return this->eventFD;
}

#else
#	error "Unsupported OS"
#endif
<commit_msg>std::move<commit_after>#include "Queue.hpp"

#include <mutex>

#if M_OS == M_OS_LINUX
#	include <sys/eventfd.h>
#	include <cstring>
#endif

//#define M_ENABLE_QUEUE_TRACE
#ifdef M_ENABLE_QUEUE_TRACE
#	define M_QUEUE_TRACE(x) TRACE(<< "[QUEUE] ") TRACE(x)
#else
#	define M_QUEUE_TRACE(x)
#endif

using namespace nitki;

Queue::Queue(){
	//can write will always be set because it is always possible to post a message to the queue
	this->setCanWriteFlag();

#if M_OS == M_OS_WINDOWS
	this->eventForWaitable = CreateEvent(
			NULL, //security attributes
			TRUE, //manual-reset
			FALSE, //not signalled initially
			NULL //no name
		);
	if(this->eventForWaitable == NULL){
		throw utki::Exc("Queue::Queue(): could not create event (Win32) for implementing Waitable");
	}
#elif M_OS == M_OS_MACOSX
	if(::pipe(&this->pipeEnds[0]) < 0){
		std::stringstream ss;
		ss << "Queue::Queue(): could not create pipe (*nix) for implementing Waitable,"
				<< " error code = " << errno << ": " << strerror(errno);
		TRACE(<< ss.str() << std::endl)
		throw utki::Exc(ss.str().c_str());
	}
#elif M_OS == M_OS_LINUX
	this->eventFD = eventfd(0, EFD_NONBLOCK);
	if(this->eventFD < 0){
		std::stringstream ss;
		ss << "Queue::Queue(): could not create eventfd (linux) for implementing Waitable,"
				<< " error code = " << errno << ": " << strerror(errno);
		throw utki::Exc(ss.str().c_str());
	}
#else
#	error "Unsupported OS"
#endif
}

Queue::~Queue()noexcept{
#if M_OS == M_OS_WINDOWS
	CloseHandle(this->eventForWaitable);
#elif M_OS == M_OS_MACOSX
	close(this->pipeEnds[0]);
	close(this->pipeEnds[1]);
#elif M_OS == M_OS_LINUX
	close(this->eventFD);
#else
#	error "Unsupported OS"
#endif
}

void Queue::pushMessage(std::function<void()>&& msg)noexcept{
	std::lock_guard<decltype(this->mut)> mutexGuard(this->mut);
	this->messages.push_back(std::move(msg));

	if(this->messages.size() == 1){//if it is a first message
		//Set CanRead flag.
		//NOTE: in linux implementation with epoll(), the CanRead
		//flag will also be set in WaitSet::Wait() method.
		//NOTE: set CanRead flag before event notification/pipe write, because
		//if do it after then some other thread which was waiting on the WaitSet
		//may read the CanRead flag while it was not set yet.
		ASSERT(!this->canRead())
		this->setCanReadFlag();

#if M_OS == M_OS_WINDOWS
		if(SetEvent(this->eventForWaitable) == 0){
			ASSERT(false)
		}
#elif M_OS == M_OS_MACOSX
		{
			std::uint8_t oneByteBuf[1];
			if(write(this->pipeEnds[1], oneByteBuf, 1) != 1){
				ASSERT(false)
			}
		}
#elif M_OS == M_OS_LINUX
		if(eventfd_write(this->eventFD, 1) < 0){
			ASSERT(false)
		}
#else
#	error "Unsupported OS"
#endif
	}

	ASSERT(this->canRead())
}

Queue::T_Message Queue::peekMsg(){
	std::lock_guard<decltype(this->mut)> mutexGuard(this->mut);
	if(this->messages.size() != 0){
		ASSERT(this->canRead())

		if(this->messages.size() == 1){//if we are taking away the last message from the queue
#if M_OS == M_OS_WINDOWS
			if(ResetEvent(this->eventForWaitable) == 0){
				ASSERT(false)
				throw utki::Exc("Queue::Wait(): ResetEvent() failed");
			}
#elif M_OS == M_OS_MACOSX
			{
				std::uint8_t oneByteBuf[1];
				if(read(this->pipeEnds[0], oneByteBuf, 1) != 1){
					throw utki::Exc("Queue::Wait(): read() failed");
				}
			}
#elif M_OS == M_OS_LINUX
			{
				eventfd_t value;
				if(eventfd_read(this->eventFD, &value) < 0){
					throw utki::Exc("Queue::Wait(): eventfd_read() failed");
				}
				ASSERT(value == 1)
			}
#else
#	error "Unsupported OS"
#endif
			this->clearCanReadFlag();
		}else{
			ASSERT(this->canRead())
		}

		T_Message ret = std::move(this->messages.front());

		this->messages.pop_front();

		return ret;
	}
	return nullptr;
}

#if M_OS == M_OS_WINDOWS
HANDLE Queue::getHandle(){
	//return event handle
	return this->eventForWaitable;
}

void Queue::setWaitingEvents(std::uint32_t flagsToWaitFor){
	//It is not allowed to wait on queue for write,
	//because it is always possible to push new message to queue.
	//Error condition is not possible for Queue.
	//Thus, only possible flag values are READ and 0 (NOT_READY)
	if(flagsToWaitFor != 0 && flagsToWaitFor != pogodi::Waitable::READ){
		ASSERT_INFO(false, "flagsToWaitFor = " << flagsToWaitFor)
		throw utki::Exc("Queue::SetWaitingEvents(): flagsToWaitFor should be pogodi::Waitable::READ or 0, other values are not allowed");
	}

	this->flagsMask = flagsToWaitFor;
}

//returns true if signaled
bool Queue::checkSignaled(){
	//error condition is not possible for queue
	ASSERT((this->readinessFlags & pogodi::Waitable::ERROR_CONDITION) == 0)

/*
#ifdef DEBUG
	{
		atomic::SpinLock::GuardYield mutexGuard(this->mut);
		if(this->first){
			ASSERT_ALWAYS(this->CanRead())

			//event should be in signalled state
			ASSERT_ALWAYS(WaitForSingleObject(this->eventForWaitable, 0) == WAIT_OBJECT_0)
		}

		if(this->CanRead()){
			ASSERT_ALWAYS(this->first)

			//event should be in signalled state
			ASSERT_ALWAYS(WaitForSingleObject(this->eventForWaitable, 0) == WAIT_OBJECT_0)
		}

		//if event is in signalled state
		if(WaitForSingleObject(this->eventForWaitable, 0) == WAIT_OBJECT_0){
			ASSERT_ALWAYS(this->CanRead())
			ASSERT_ALWAYS(this->first)
		}
	}
#endif
*/

	return (this->readinessFlags & this->flagsMask) != 0;
}

#elif M_OS == M_OS_MACOSX
//override
int Queue::getHandle(){
	//return read end of pipe
	return this->pipeEnds[0];
}

#elif M_OS == M_OS_LINUX
//override
int Queue::getHandle(){
	return this->eventFD;
}

#else
#	error "Unsupported OS"
#endif
<|endoftext|>


<commit_before>#include <nls/ast/node.hh>

using namespace std;
namespace nls {
namespace ast {

Node::Node(void) : _left(NULL), _right(NULL), _variant(NULL), _name("anonymous") { }

Node::Node(Node *left) : _left(left), _right(NULL), _variant(NULL), _name("anonymous") { }

Node::Node(Node *left, Node *right) : _left(left), _right(right), _variant(NULL), _name("anonymous") { }

Node::~Node(void)
{
    if (_variant) {
        delete _variant;
    }
}

Node *Node::left(void)
{
    return _left;
}

Node *Node::right(void)
{
    return _right;
}

void Node::left(Node* node)
{
    _left = node;
}

void Node::right(Node* node)
{
    _right = node;
}

void Node::append(Node* node)
{

}

void Node::variant(Variant *var)
{
    _variant = var;
}

Variant *Node::variant(void)
{
    return _variant;
}

void Node::name(std::string& val)
{
    _name = val;
}
std::string& Node::name(void)
{
    return _name;
}

string Node::dot_shape(void) { return "box"; }
string Node::dot_label(void) { return "b0rk3d"; }
string Node::dot_color(void) { return "#e0e0e0"; }

}}
<commit_msg>Fixed node::append.<commit_after>#include <nls/ast/node.hh>

using namespace std;
namespace nls {
namespace ast {

Node::Node(void) : _left(NULL), _right(NULL), _variant(NULL), _name("anonymous") { }

Node::Node(Node *left) : _left(left), _right(NULL), _variant(NULL), _name("anonymous") { }

Node::Node(Node *left, Node *right) : _left(left), _right(right), _variant(NULL), _name("anonymous") { }

Node::~Node(void)
{
    if (_variant) {
        delete _variant;
    }
}

Node *Node::left(void)
{
    return _left;
}

Node *Node::right(void)
{
    return _right;
}

void Node::left(Node* node)
{
    _left = node;
}

void Node::right(Node* node)
{
    _right = node;
}

void Node::append(Node* node)
{
    Node* next = this;
    while(next->right()) {
        next = next->right();
    }
    next->right(node);
}

void Node::variant(Variant *var)
{
    _variant = var;
}

Variant *Node::variant(void)
{
    return _variant;
}

void Node::name(std::string& val)
{
    _name = val;
}
std::string& Node::name(void)
{
    return _name;
}

string Node::dot_shape(void) { return "box"; }
string Node::dot_label(void) { return "b0rk3d"; }
string Node::dot_color(void) { return "#e0e0e0"; }

}}
<|endoftext|>


<commit_before>#ifndef RBX_VM_OBJECT_UTILS_HPP
#define RBX_VM_OBJECT_UTILS_HPP

#include "builtin/object.hpp"
#include "exception.hpp"

/**
 *  @file   object_utils.hpp
 *
 *  Defines all the most common operations for dealing with
 *  objects, such as type checking and casting.
 */

// A stupid work around for g++ changing it's behavior on 4.3

#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 3
  #define SPECIALIZATION_STORAGE
#else
  #define SPECIALIZATION_STORAGE static inline
#endif

namespace rubinius {

  /**
   *  Ruby type system subtype check.
   *
   *  Given builtin-class +T+, return true if +obj+ is of class +T+
   */
  template <class T>
    static inline bool kind_of(const Object* obj) {
      if(obj->reference_p()) {
        return obj->type_id() == T::type;
      }
      return false;
    }

  /**
   * A specialized version for completeness.
   */
  template <>
    SPECIALIZATION_STORAGE bool kind_of<Object>(const Object* obj) {
      return true;
    }

  /**
   *  Ruby type system class check.
   *
   *  Another version of kind_of that shouldn't be specialized for subtype
   *  compatibility. I.e., only whether object's class is this specific
   *  one.
   */
  template <class T>
    static inline bool instance_of(const Object* obj) {
      if(obj->reference_p()) {
        return obj->type_id() == T::type;
      }
      return false;
    }

  /**
   * A specialized version for completeness.
   */
  template <>
    SPECIALIZATION_STORAGE bool instance_of<Object>(const Object* obj) {
      return obj->reference_p() && (obj->type_id() == ObjectType);
    }

  /*
   *  There is NO reason why as() or try_as() should be getting
   *  NULL arguments. That means something has not been properly
   *  initialised (to cNil if nothing else.)
   */

  /**
   *  Cast Object* into builtin T*.
   *
   *  Given builtin class +T+, return +obj+ cast as type +T*+. If
   *  +obj+ is not of type +T+, throw's a TypeError exception.
   *
   *  @see  builtin/object.cpp has specialised versions.
   */
  template <class T>
    static inline T* as(Object* obj) {
      if(!kind_of<T>(obj)) {
        TypeError::raise(T::type, obj);
      }

      return static_cast<T*>(obj);
    }

  /**
   *  Cast const Object* into builtin const T*.
   *
   *  Given builtin class +T+, return +obj+ cast as type +T*+. If
   *  +obj+ is not of type +T+, throw's a TypeError exception.
   *
   *  @see  builtin/object.cpp has specialised versions.
   */
  template <class T>
    static inline const T* as(const Object* obj) {
      if(!kind_of<T>(obj)) {
        TypeError::raise(T::type, obj);
      }

      return static_cast<const T*>(obj);
    }

  /**
   * A specialized version for completeness.
   */
  template <>
    SPECIALIZATION_STORAGE Object* as<Object>(Object* obj) {
      return obj;
    }

  /**
   * A specialized version for completeness.
   */
  template <>
    SPECIALIZATION_STORAGE const Object* as<Object>(const Object* obj) {
      return obj;
    }

  /**
   *  Cast Object* into builtin T*.
   *
   *  Given builtin class +T+, return +obj+ cast as type +T*+. If
   *  +obj+ is not exactly of type +T+, throw's a TypeError exception.
   *
   *  @see  builtin/object.cpp has specialised versions.
   */
  template <class T>
    static inline T* as_instance(Object* obj) {
      if(!instance_of<T>(obj)) {
        TypeError::raise(T::type, obj);
      }

      return static_cast<T*>(obj);
    }

  /**
   *  Cast const Object* into builtin const T*.
   *
   *  Given builtin class +T+, return +obj+ cast as type +T*+. If
   *  +obj+ is not exactly of type +T+, throw's a TypeError exception.
   *
   *  @see  builtin/object.cpp has specialised versions.
   */
  template <class T>
    static inline const T* as_instance(const Object* obj) {
      if(!instance_of<T>(obj)) {
        TypeError::raise(T::type, obj);
      }

      return static_cast<const T*>(obj);
    }

  /**
   *  Non-raising version of as().
   *
   *  Similar to as<>, but returns NULL if the type is invalid. ONLY
   *  use this when doing a conditional cast.
   *
   *  @see  builtin/object.cpp has specialised versions.
   */
  template <class T>
    static inline T* try_as(Object* obj) {
      if(!kind_of<T>(obj)) {
        return NULL;
      }

      return static_cast<T*>(obj);
    }

  /**
   *  Non-raising version of as(), for const objects.
   *
   *  Similar to as<>, but returns NULL if the type is invalid. ONLY
   *  use this when doing a conditional cast.
   *
   *  @see  builtin/object.cpp has specialised versions.
   */
  template <class T>
    static inline const T* try_as(const Object* obj) {
      if(!kind_of<T>(obj)) {
        return NULL;
      }

      return static_cast<const T*>(obj);
    }

  /**
   *  Non-raising version of as_instance().
   *
   *  Similar to as_instance<>, but returns NULL if the type is invalid. ONLY
   *  use this when doing a conditional cast.
   *
   *  @see  builtin/object.cpp has specialised versions.
   */
  template <class T>
    static inline T* try_as_instance(Object* obj) {
      if(!instance_of<T>(obj)) {
        return NULL;
      }

      return static_cast<T*>(obj);
    }

  /**
   *  Non-raising version of as(), for const objects.
   *
   *  Similar to as<>, but returns NULL if the type is invalid. ONLY
   *  use this when doing a conditional cast.
   *
   *  @see  builtin/object.cpp has specialised versions.
   */
  template <class T>
    static inline const T* try_as_instance(const Object* obj) {
      if(!instance_of<T>(obj)) {
        return NULL;
      }

      return static_cast<const T*>(obj);
    }

  /**
   *  Returns cNil cast to another type of rubinius::Object. Useful in
   *  cases where e.g. a String* would be returned but cNil is returned
   *  as an exceptional value.
   *
   */
  template <class T>
    static inline T* nil() { return static_cast<T*>(cNil); }

  /**
   *  Converts one type into another without a type check. This is
   *  like reinterprete_cast<>(), but we use it so we can easily
   *  find where we're doing explicit force casts.
   */
  template <class T>
    static inline T* force_as(ObjectHeader* obj) {
      return reinterpret_cast<T*>(obj);
    }

  template <class T>
    static inline const T* force_as(const ObjectHeader* obj) {
      return reinterpret_cast<const T*>(obj);
    }

  void type_assert(STATE, Object* obj, object_type type, const char* reason);

#include "gen/kind_of.hpp"

}

#endif
<commit_msg>Clang reports as being GCC 4.2 compatible, but has the 4.3 behavior<commit_after>#ifndef RBX_VM_OBJECT_UTILS_HPP
#define RBX_VM_OBJECT_UTILS_HPP

#include "builtin/object.hpp"
#include "exception.hpp"

/**
 *  @file   object_utils.hpp
 *
 *  Defines all the most common operations for dealing with
 *  objects, such as type checking and casting.
 */

// A stupid work around for g++ changing it's behavior on 4.3

#if __clang__ || (__GNUC__ >= 4 && __GNUC_MINOR__ >= 3)
  #define SPECIALIZATION_STORAGE
#else
  #define SPECIALIZATION_STORAGE static inline
#endif

namespace rubinius {

  /**
   *  Ruby type system subtype check.
   *
   *  Given builtin-class +T+, return true if +obj+ is of class +T+
   */
  template <class T>
    static inline bool kind_of(const Object* obj) {
      if(obj->reference_p()) {
        return obj->type_id() == T::type;
      }
      return false;
    }

  /**
   * A specialized version for completeness.
   */
  template <>
    SPECIALIZATION_STORAGE bool kind_of<Object>(const Object* obj) {
      return true;
    }

  /**
   *  Ruby type system class check.
   *
   *  Another version of kind_of that shouldn't be specialized for subtype
   *  compatibility. I.e., only whether object's class is this specific
   *  one.
   */
  template <class T>
    static inline bool instance_of(const Object* obj) {
      if(obj->reference_p()) {
        return obj->type_id() == T::type;
      }
      return false;
    }

  /**
   * A specialized version for completeness.
   */
  template <>
    SPECIALIZATION_STORAGE bool instance_of<Object>(const Object* obj) {
      return obj->reference_p() && (obj->type_id() == ObjectType);
    }

  /*
   *  There is NO reason why as() or try_as() should be getting
   *  NULL arguments. That means something has not been properly
   *  initialised (to cNil if nothing else.)
   */

  /**
   *  Cast Object* into builtin T*.
   *
   *  Given builtin class +T+, return +obj+ cast as type +T*+. If
   *  +obj+ is not of type +T+, throw's a TypeError exception.
   *
   *  @see  builtin/object.cpp has specialised versions.
   */
  template <class T>
    static inline T* as(Object* obj) {
      if(!kind_of<T>(obj)) {
        TypeError::raise(T::type, obj);
      }

      return static_cast<T*>(obj);
    }

  /**
   *  Cast const Object* into builtin const T*.
   *
   *  Given builtin class +T+, return +obj+ cast as type +T*+. If
   *  +obj+ is not of type +T+, throw's a TypeError exception.
   *
   *  @see  builtin/object.cpp has specialised versions.
   */
  template <class T>
    static inline const T* as(const Object* obj) {
      if(!kind_of<T>(obj)) {
        TypeError::raise(T::type, obj);
      }

      return static_cast<const T*>(obj);
    }

  /**
   * A specialized version for completeness.
   */
  template <>
    SPECIALIZATION_STORAGE Object* as<Object>(Object* obj) {
      return obj;
    }

  /**
   * A specialized version for completeness.
   */
  template <>
    SPECIALIZATION_STORAGE const Object* as<Object>(const Object* obj) {
      return obj;
    }

  /**
   *  Cast Object* into builtin T*.
   *
   *  Given builtin class +T+, return +obj+ cast as type +T*+. If
   *  +obj+ is not exactly of type +T+, throw's a TypeError exception.
   *
   *  @see  builtin/object.cpp has specialised versions.
   */
  template <class T>
    static inline T* as_instance(Object* obj) {
      if(!instance_of<T>(obj)) {
        TypeError::raise(T::type, obj);
      }

      return static_cast<T*>(obj);
    }

  /**
   *  Cast const Object* into builtin const T*.
   *
   *  Given builtin class +T+, return +obj+ cast as type +T*+. If
   *  +obj+ is not exactly of type +T+, throw's a TypeError exception.
   *
   *  @see  builtin/object.cpp has specialised versions.
   */
  template <class T>
    static inline const T* as_instance(const Object* obj) {
      if(!instance_of<T>(obj)) {
        TypeError::raise(T::type, obj);
      }

      return static_cast<const T*>(obj);
    }

  /**
   *  Non-raising version of as().
   *
   *  Similar to as<>, but returns NULL if the type is invalid. ONLY
   *  use this when doing a conditional cast.
   *
   *  @see  builtin/object.cpp has specialised versions.
   */
  template <class T>
    static inline T* try_as(Object* obj) {
      if(!kind_of<T>(obj)) {
        return NULL;
      }

      return static_cast<T*>(obj);
    }

  /**
   *  Non-raising version of as(), for const objects.
   *
   *  Similar to as<>, but returns NULL if the type is invalid. ONLY
   *  use this when doing a conditional cast.
   *
   *  @see  builtin/object.cpp has specialised versions.
   */
  template <class T>
    static inline const T* try_as(const Object* obj) {
      if(!kind_of<T>(obj)) {
        return NULL;
      }

      return static_cast<const T*>(obj);
    }

  /**
   *  Non-raising version of as_instance().
   *
   *  Similar to as_instance<>, but returns NULL if the type is invalid. ONLY
   *  use this when doing a conditional cast.
   *
   *  @see  builtin/object.cpp has specialised versions.
   */
  template <class T>
    static inline T* try_as_instance(Object* obj) {
      if(!instance_of<T>(obj)) {
        return NULL;
      }

      return static_cast<T*>(obj);
    }

  /**
   *  Non-raising version of as(), for const objects.
   *
   *  Similar to as<>, but returns NULL if the type is invalid. ONLY
   *  use this when doing a conditional cast.
   *
   *  @see  builtin/object.cpp has specialised versions.
   */
  template <class T>
    static inline const T* try_as_instance(const Object* obj) {
      if(!instance_of<T>(obj)) {
        return NULL;
      }

      return static_cast<const T*>(obj);
    }

  /**
   *  Returns cNil cast to another type of rubinius::Object. Useful in
   *  cases where e.g. a String* would be returned but cNil is returned
   *  as an exceptional value.
   *
   */
  template <class T>
    static inline T* nil() { return static_cast<T*>(cNil); }

  /**
   *  Converts one type into another without a type check. This is
   *  like reinterprete_cast<>(), but we use it so we can easily
   *  find where we're doing explicit force casts.
   */
  template <class T>
    static inline T* force_as(ObjectHeader* obj) {
      return reinterpret_cast<T*>(obj);
    }

  template <class T>
    static inline const T* force_as(const ObjectHeader* obj) {
      return reinterpret_cast<const T*>(obj);
    }

  void type_assert(STATE, Object* obj, object_type type, const char* reason);

#include "gen/kind_of.hpp"

}

#endif
<|endoftext|>


<commit_before>// v8
#include <v8.h>

// node
#include <node.h>
#include <node_version.h>

// node-mapnik
#include "mapnik_vector_tile.hpp"
#include "mapnik_map.hpp"
#include "mapnik_color.hpp"
#include "mapnik_geometry.hpp"
#include "mapnik_feature.hpp"
#include "mapnik_fonts.hpp"
#include "mapnik_plugins.hpp"
#include "mapnik_palette.hpp"
#include "mapnik_projection.hpp"
#include "mapnik_proj_transform.hpp"
#include "mapnik_layer.hpp"
#include "mapnik_datasource.hpp"
#include "mapnik_featureset.hpp"
//#include "mapnik_js_datasource.hpp"
#include "mapnik_memory_datasource.hpp"
#include "mapnik_image.hpp"
#include "mapnik_image_view.hpp"
#include "mapnik_grid.hpp"
#include "mapnik_cairo_surface.hpp"
#include "mapnik_grid_view.hpp"
#include "mapnik_expression.hpp"
#include "utils.hpp"

#ifdef MAPNIK_DEBUG
#include <libxml/parser.h>
#endif

// mapnik
#include <mapnik/config.hpp> // for MAPNIK_DECL
#include <mapnik/version.hpp>
#if MAPNIK_VERSION >= 200100
#include <mapnik/marker_cache.hpp>
#include <mapnik/mapped_memory_cache.hpp>
#include <mapnik/image_compositing.hpp>
#endif

// boost
#include <boost/version.hpp>

// cairo
#if defined(HAVE_CAIRO)
#include <cairo.h>
#endif

namespace node_mapnik {

using namespace node;
using namespace v8;

/**
 * Optional notification that the embedder is idle.
 * V8 uses the notification to reduce memory footprint.
 * This call can be used repeatedly if the embedder remains idle.
 * Returns true if the embedder should stop calling IdleNotification
 * until real work has been done.  This indicates that V8 has done
 * as much cleanup as it will be able to do.
 */
static Handle<Value> gc(const Arguments& args)
{
    HandleScope scope;
    return scope.Close(Boolean::New(V8::IdleNotification()));
}

static std::string format_version(int version)
{
    std::ostringstream s;
    s << version/100000 << "." << version/100 % 1000  << "." << version % 100;
    return s.str();
}

static Handle<Value> clearCache(const Arguments& args)
{
    HandleScope scope;
#if MAPNIK_VERSION >= 200200
    mapnik::marker_cache::instance().clear();
    mapnik::mapped_memory_cache::instance().clear();
#else
#if MAPNIK_VERSION >= 200100
    mapnik::marker_cache::instance()->clear();
    mapnik::mapped_memory_cache::instance()->clear();
#endif
#endif
    return Undefined();
}

static Handle<Value> shutdown(const Arguments& args)
{
    HandleScope scope;
    google::protobuf::ShutdownProtobufLibrary();
#ifdef MAPNIK_DEBUG
    // http://lists.fedoraproject.org/pipermail/devel/2010-January/129117.html
    xmlCleanupParser();
#endif
    return Undefined();
}

extern "C" {

    static void InitMapnik (Handle<Object> target)
    {
        GOOGLE_PROTOBUF_VERIFY_VERSION;

        // module level functions
        NODE_SET_METHOD(target, "register_datasources", node_mapnik::register_datasources);
        NODE_SET_METHOD(target, "datasources", node_mapnik::available_input_plugins);
        NODE_SET_METHOD(target, "register_fonts", node_mapnik::register_fonts);
        NODE_SET_METHOD(target, "fonts", node_mapnik::available_font_faces);
        NODE_SET_METHOD(target, "fontFiles", node_mapnik::available_font_files);
        NODE_SET_METHOD(target, "clearCache", clearCache);
        NODE_SET_METHOD(target, "gc", gc);
        NODE_SET_METHOD(target, "shutdown",shutdown);

        // Classes
        VectorTile::Initialize(target);
        Map::Initialize(target);
        Color::Initialize(target);
        Geometry::Initialize(target);
        Feature::Initialize(target);
        Image::Initialize(target);
        ImageView::Initialize(target);
        Palette::Initialize(target);
        Projection::Initialize(target);
        ProjTransform::Initialize(target);
        Layer::Initialize(target);
        Grid::Initialize(target);
        GridView::Initialize(target);
        Datasource::Initialize(target);
        Featureset::Initialize(target);
        // Not production safe, so disabling indefinitely
        //JSDatasource::Initialize(target);
        MemoryDatasource::Initialize(target);
        Expression::Initialize(target);
        CairoSurface::Initialize(target);

        // versions of deps
        Local<Object> versions = Object::New();
        versions->Set(String::NewSymbol("node"), String::New(NODE_VERSION+1));
        versions->Set(String::NewSymbol("v8"), String::New(V8::GetVersion()));
        versions->Set(String::NewSymbol("boost"), String::New(format_version(BOOST_VERSION).c_str()));
        versions->Set(String::NewSymbol("boost_number"), Integer::New(BOOST_VERSION));
        versions->Set(String::NewSymbol("mapnik"), String::New(format_version(MAPNIK_VERSION).c_str()));
        versions->Set(String::NewSymbol("mapnik_number"), Integer::New(MAPNIK_VERSION));
#if defined(HAVE_CAIRO)
        versions->Set(String::NewSymbol("cairo"), String::New(CAIRO_VERSION_STRING));
#endif
        target->Set(String::NewSymbol("versions"), versions);

        // built in support
        Local<Object> supports = Object::New();
        supports->Set(String::NewSymbol("grid"), True());

#if defined(HAVE_CAIRO)
        supports->Set(String::NewSymbol("cairo"), True());
#else
        supports->Set(String::NewSymbol("cairo"), False());
#endif

#if defined(HAVE_JPEG)
        supports->Set(String::NewSymbol("jpeg"), True());
#else
        supports->Set(String::NewSymbol("jpeg"), False());
#endif
        target->Set(String::NewSymbol("supports"), supports);

#if MAPNIK_VERSION >= 200100
        Local<Object> composite_ops = Object::New();
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "clear", mapnik::clear)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "src", mapnik::src)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "dst", mapnik::dst)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "src_over", mapnik::src_over)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "dst_over", mapnik::dst_over)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "src_in", mapnik::src_in)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "dst_in", mapnik::dst_in)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "src_out", mapnik::src_out)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "dst_out", mapnik::dst_out)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "src_atop", mapnik::src_atop)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "dst_atop", mapnik::dst_atop)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "xor", mapnik::_xor)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "plus", mapnik::plus)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "minus", mapnik::minus)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "multiply", mapnik::multiply)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "screen", mapnik::screen)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "overlay", mapnik::overlay)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "darken", mapnik::darken)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "lighten", mapnik::lighten)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "color_dodge", mapnik::color_dodge)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "color_burn", mapnik::color_burn)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "hard_light", mapnik::hard_light)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "soft_light", mapnik::soft_light)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "difference", mapnik::difference)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "exclusion", mapnik::exclusion)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "contrast", mapnik::contrast)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "invert", mapnik::invert)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "invert_rgb", mapnik::invert_rgb)

        target->Set(String::NewSymbol("compositeOp"), composite_ops);
#endif
    }

}

} // namespace node_mapnik

#if NODE_VERSION_AT_LEAST(0, 9, 0)

#define NODE_MAPNIK_MODULE(modname, regfunc)                          \
  extern "C" {                                                        \
    MAPNIK_EXP node::node_module_struct modname ## _module =         \
    {                                                                 \
      NODE_STANDARD_MODULE_STUFF,                                     \
      (node::addon_register_func)regfunc,                             \
      NODE_STRINGIFY(modname)                                         \
    };                                                                \
  }

#else

#define NODE_MAPNIK_MODULE(modname, regfunc)                          \
  extern "C" {                                                        \
    MAPNIK_EXP node::node_module_struct modname ## _module =         \
    {                                                                 \
      NODE_STANDARD_MODULE_STUFF,                                     \
      regfunc,                             \
      NODE_STRINGIFY(modname)                                         \
    };                                                                \
  }

#endif

NODE_MAPNIK_MODULE(_mapnik, node_mapnik::InitMapnik)
<commit_msg>add handlescope to InitMapnik which should do no harm (though may not be needed)<commit_after>// v8
#include <v8.h>

// node
#include <node.h>
#include <node_version.h>

// node-mapnik
#include "mapnik_vector_tile.hpp"
#include "mapnik_map.hpp"
#include "mapnik_color.hpp"
#include "mapnik_geometry.hpp"
#include "mapnik_feature.hpp"
#include "mapnik_fonts.hpp"
#include "mapnik_plugins.hpp"
#include "mapnik_palette.hpp"
#include "mapnik_projection.hpp"
#include "mapnik_proj_transform.hpp"
#include "mapnik_layer.hpp"
#include "mapnik_datasource.hpp"
#include "mapnik_featureset.hpp"
//#include "mapnik_js_datasource.hpp"
#include "mapnik_memory_datasource.hpp"
#include "mapnik_image.hpp"
#include "mapnik_image_view.hpp"
#include "mapnik_grid.hpp"
#include "mapnik_cairo_surface.hpp"
#include "mapnik_grid_view.hpp"
#include "mapnik_expression.hpp"
#include "utils.hpp"

#ifdef MAPNIK_DEBUG
#include <libxml/parser.h>
#endif

// mapnik
#include <mapnik/config.hpp> // for MAPNIK_DECL
#include <mapnik/version.hpp>
#if MAPNIK_VERSION >= 200100
#include <mapnik/marker_cache.hpp>
#include <mapnik/mapped_memory_cache.hpp>
#include <mapnik/image_compositing.hpp>
#endif

// boost
#include <boost/version.hpp>

// cairo
#if defined(HAVE_CAIRO)
#include <cairo.h>
#endif

namespace node_mapnik {

using namespace node;
using namespace v8;

/**
 * Optional notification that the embedder is idle.
 * V8 uses the notification to reduce memory footprint.
 * This call can be used repeatedly if the embedder remains idle.
 * Returns true if the embedder should stop calling IdleNotification
 * until real work has been done.  This indicates that V8 has done
 * as much cleanup as it will be able to do.
 */
static Handle<Value> gc(const Arguments& args)
{
    HandleScope scope;
    return scope.Close(Boolean::New(V8::IdleNotification()));
}

static std::string format_version(int version)
{
    std::ostringstream s;
    s << version/100000 << "." << version/100 % 1000  << "." << version % 100;
    return s.str();
}

static Handle<Value> clearCache(const Arguments& args)
{
    HandleScope scope;
#if MAPNIK_VERSION >= 200200
    mapnik::marker_cache::instance().clear();
    mapnik::mapped_memory_cache::instance().clear();
#else
#if MAPNIK_VERSION >= 200100
    mapnik::marker_cache::instance()->clear();
    mapnik::mapped_memory_cache::instance()->clear();
#endif
#endif
    return Undefined();
}

static Handle<Value> shutdown(const Arguments& args)
{
    HandleScope scope;
    google::protobuf::ShutdownProtobufLibrary();
#ifdef MAPNIK_DEBUG
    // http://lists.fedoraproject.org/pipermail/devel/2010-January/129117.html
    xmlCleanupParser();
#endif
    return Undefined();
}

extern "C" {

    static void InitMapnik (Handle<Object> target)
    {
        HandleScope scope;
        GOOGLE_PROTOBUF_VERIFY_VERSION;

        // module level functions
        NODE_SET_METHOD(target, "register_datasources", node_mapnik::register_datasources);
        NODE_SET_METHOD(target, "datasources", node_mapnik::available_input_plugins);
        NODE_SET_METHOD(target, "register_fonts", node_mapnik::register_fonts);
        NODE_SET_METHOD(target, "fonts", node_mapnik::available_font_faces);
        NODE_SET_METHOD(target, "fontFiles", node_mapnik::available_font_files);
        NODE_SET_METHOD(target, "clearCache", clearCache);
        NODE_SET_METHOD(target, "gc", gc);
        NODE_SET_METHOD(target, "shutdown",shutdown);

        // Classes
        VectorTile::Initialize(target);
        Map::Initialize(target);
        Color::Initialize(target);
        Geometry::Initialize(target);
        Feature::Initialize(target);
        Image::Initialize(target);
        ImageView::Initialize(target);
        Palette::Initialize(target);
        Projection::Initialize(target);
        ProjTransform::Initialize(target);
        Layer::Initialize(target);
        Grid::Initialize(target);
        GridView::Initialize(target);
        Datasource::Initialize(target);
        Featureset::Initialize(target);
        // Not production safe, so disabling indefinitely
        //JSDatasource::Initialize(target);
        MemoryDatasource::Initialize(target);
        Expression::Initialize(target);
        CairoSurface::Initialize(target);

        // versions of deps
        Local<Object> versions = Object::New();
        versions->Set(String::NewSymbol("node"), String::New(NODE_VERSION+1));
        versions->Set(String::NewSymbol("v8"), String::New(V8::GetVersion()));
        versions->Set(String::NewSymbol("boost"), String::New(format_version(BOOST_VERSION).c_str()));
        versions->Set(String::NewSymbol("boost_number"), Integer::New(BOOST_VERSION));
        versions->Set(String::NewSymbol("mapnik"), String::New(format_version(MAPNIK_VERSION).c_str()));
        versions->Set(String::NewSymbol("mapnik_number"), Integer::New(MAPNIK_VERSION));
#if defined(HAVE_CAIRO)
        versions->Set(String::NewSymbol("cairo"), String::New(CAIRO_VERSION_STRING));
#endif
        target->Set(String::NewSymbol("versions"), versions);

        // built in support
        Local<Object> supports = Object::New();
        supports->Set(String::NewSymbol("grid"), True());

#if defined(HAVE_CAIRO)
        supports->Set(String::NewSymbol("cairo"), True());
#else
        supports->Set(String::NewSymbol("cairo"), False());
#endif

#if defined(HAVE_JPEG)
        supports->Set(String::NewSymbol("jpeg"), True());
#else
        supports->Set(String::NewSymbol("jpeg"), False());
#endif
        target->Set(String::NewSymbol("supports"), supports);

#if MAPNIK_VERSION >= 200100
        Local<Object> composite_ops = Object::New();
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "clear", mapnik::clear)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "src", mapnik::src)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "dst", mapnik::dst)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "src_over", mapnik::src_over)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "dst_over", mapnik::dst_over)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "src_in", mapnik::src_in)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "dst_in", mapnik::dst_in)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "src_out", mapnik::src_out)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "dst_out", mapnik::dst_out)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "src_atop", mapnik::src_atop)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "dst_atop", mapnik::dst_atop)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "xor", mapnik::_xor)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "plus", mapnik::plus)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "minus", mapnik::minus)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "multiply", mapnik::multiply)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "screen", mapnik::screen)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "overlay", mapnik::overlay)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "darken", mapnik::darken)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "lighten", mapnik::lighten)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "color_dodge", mapnik::color_dodge)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "color_burn", mapnik::color_burn)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "hard_light", mapnik::hard_light)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "soft_light", mapnik::soft_light)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "difference", mapnik::difference)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "exclusion", mapnik::exclusion)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "contrast", mapnik::contrast)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "invert", mapnik::invert)
        NODE_MAPNIK_DEFINE_CONSTANT(composite_ops, "invert_rgb", mapnik::invert_rgb)

        target->Set(String::NewSymbol("compositeOp"), composite_ops);
#endif
    }

}

} // namespace node_mapnik

#if NODE_VERSION_AT_LEAST(0, 9, 0)

#define NODE_MAPNIK_MODULE(modname, regfunc)                          \
  extern "C" {                                                        \
    MAPNIK_EXP node::node_module_struct modname ## _module =         \
    {                                                                 \
      NODE_STANDARD_MODULE_STUFF,                                     \
      (node::addon_register_func)regfunc,                             \
      NODE_STRINGIFY(modname)                                         \
    };                                                                \
  }

#else

#define NODE_MAPNIK_MODULE(modname, regfunc)                          \
  extern "C" {                                                        \
    MAPNIK_EXP node::node_module_struct modname ## _module =         \
    {                                                                 \
      NODE_STANDARD_MODULE_STUFF,                                     \
      regfunc,                             \
      NODE_STRINGIFY(modname)                                         \
    };                                                                \
  }

#endif

NODE_MAPNIK_MODULE(_mapnik, node_mapnik::InitMapnik)
<|endoftext|>


<commit_before>#include <cstdio>
#include <string>
#include <memory.h>
#include <iostream>

#define BUF_SIZE 65536
char input_buf[BUF_SIZE];

struct FastReader {
	char* cur_pos;

	FastReader() {
		fread(input_buf, 1, sizeof(input_buf), stdin);
		cur_pos = input_buf;
	}

	void fill_buffer() {
		int size = input_buf + BUF_SIZE - cur_pos;
		if (size < (1 << 7)) {
			memcpy(input_buf, cur_pos, size);
			fread(input_buf + size, 1, BUF_SIZE - size, stdin);
			cur_pos = input_buf;
		}
	}

	int read_int() {
		fill_buffer();
		while (*cur_pos <= ' ')
			cur_pos++;
		bool sign = false;
		if (*cur_pos == '-') {
			sign = true;
			cur_pos++;
		}
		int res = 0;
		while (*cur_pos > ' ')
			res = (res << 3) + (res << 1) + (*(cur_pos++) & 15);
		return sign ? -res : res;
	}

	long int read_long() {
		fill_buffer();
		while (*cur_pos <= ' ')
			cur_pos++;
		bool sign = false;
		if (*cur_pos == '-') {
			sign = true;
			cur_pos++;
		}
		long long int res = 0LL;
		while (*cur_pos > ' ')
			res = (res << 3) + (res << 1) + (*(cur_pos++) & 15);
		return sign ? -res : res;
	}

	char read_char() {
		fill_buffer();
		while (*cur_pos <= ' ')
			cur_pos++;
		return *(cur_pos++);
	}

	std::string read_string() {
		fill_buffer();
		std::string str = "";
		while (*cur_pos <= ' ')
			cur_pos++;
		while (*cur_pos != ' ' && *cur_pos != '\n')
			str = str + *(cur_pos++);
		return str;
	}

	std::string read_line() {
		fill_buffer();
		std::string str = "";
		while (*cur_pos <= ' ')
			cur_pos++;
		while (*cur_pos != '\n')
			str = str + *(cur_pos++);
		return str;
	}
};

int main() {
	FastReader fr;

	int n1 = fr.read_int();
	long long int n2 = fr.read_long();
	char ch = fr.read_char();
	std::string str1 = fr.read_string();
	std::string str2 = fr.read_line();

	std::cout << n1 << "\n";
	std::cout << n2 << "\n";
	std::cout << ch << "\n";
	std::cout << str1 << "\n";
	std::cout << str2 << "\n";

	return 0;

}
<commit_msg>add comment for iostream usage<commit_after>#include <cstdio>
#include <string>
#include <memory.h>

// only for printing
#include <iostream>

#define BUF_SIZE 65536
char input_buf[BUF_SIZE];

struct FastReader {
	char* cur_pos;

	FastReader() {
		fread(input_buf, 1, sizeof(input_buf), stdin);
		cur_pos = input_buf;
	}

	void fill_buffer() {
		int size = input_buf + BUF_SIZE - cur_pos;
		if (size < (1 << 7)) {
			memcpy(input_buf, cur_pos, size);
			fread(input_buf + size, 1, BUF_SIZE - size, stdin);
			cur_pos = input_buf;
		}
	}

	int read_int() {
		fill_buffer();
		while (*cur_pos <= ' ')
			cur_pos++;
		bool sign = false;
		if (*cur_pos == '-') {
			sign = true;
			cur_pos++;
		}
		int res = 0;
		while (*cur_pos > ' ')
			res = (res << 3) + (res << 1) + (*(cur_pos++) & 15);
		return sign ? -res : res;
	}

	long int read_long() {
		fill_buffer();
		while (*cur_pos <= ' ')
			cur_pos++;
		bool sign = false;
		if (*cur_pos == '-') {
			sign = true;
			cur_pos++;
		}
		long long int res = 0LL;
		while (*cur_pos > ' ')
			res = (res << 3) + (res << 1) + (*(cur_pos++) & 15);
		return sign ? -res : res;
	}

	char read_char() {
		fill_buffer();
		while (*cur_pos <= ' ')
			cur_pos++;
		return *(cur_pos++);
	}

	std::string read_string() {
		fill_buffer();
		std::string str = "";
		while (*cur_pos <= ' ')
			cur_pos++;
		while (*cur_pos != ' ' && *cur_pos != '\n')
			str = str + *(cur_pos++);
		return str;
	}

	std::string read_line() {
		fill_buffer();
		std::string str = "";
		while (*cur_pos <= ' ')
			cur_pos++;
		while (*cur_pos != '\n')
			str = str + *(cur_pos++);
		return str;
	}
};

int main() {
	FastReader fr;

	int n1 = fr.read_int();
	long long int n2 = fr.read_long();
	char ch = fr.read_char();
	std::string str1 = fr.read_string();
	std::string str2 = fr.read_line();

	std::cout << n1 << "\n";
	std::cout << n2 << "\n";
	std::cout << ch << "\n";
	std::cout << str1 << "\n";
	std::cout << str2 << "\n";

	return 0;

}
<|endoftext|>


<commit_before>#include <string.h>

#include <float.h>
#include "reductions.h"
#include "rand48.h"

using namespace LEARNER;

namespace LRQ {

  struct LRQstate {
    vw* all;
    bool lrindices[256];
    size_t orig_size[256];
    std::vector<std::string> lrpairs;
    bool dropout;
    uint64_t seed;
    uint64_t initial_seed;
  };
}

namespace {
  bool
  valid_int (const char* s)
    {
      char* endptr;

      int v = strtoul (s, &endptr, 0);
      (void) v;

      return (*s != '\0' && *endptr == '\0');
    }

  inline bool
  cheesyrbit (uint64_t& seed)
    {
      return merand48 (seed) > 0.5;
    }

  inline float
  cheesyrand (uint32_t x)
    {
      uint64_t seed = x;

      return merand48 (seed);
    }

  inline bool
  example_is_test (example& ec)
  {
    return ec.l.simple.label == FLT_MAX;
  }

  void
  reset_seed (LRQ::LRQstate& lrq)
    {
      if (lrq.all->bfgs)
        lrq.seed = lrq.initial_seed;
    }
}

namespace LRQ {

  template <bool is_learn>
  void predict_or_learn(LRQstate& lrq, base_learner& base, example& ec)
  {
    vw& all = *lrq.all;

    // Remember original features

    for (unsigned char* i = ec.indices.begin; i != ec.indices.end; ++i)
      {
        if (lrq.lrindices[*i])
          lrq.orig_size[*i] = ec.atomics[*i].size ();
      }

    size_t which = ec.example_counter;
    float first_prediction;
    float first_loss;
    unsigned int maxiter = (is_learn && ! example_is_test (ec)) ? 2 : 1;

    bool do_dropout = lrq.dropout && is_learn && ! example_is_test (ec);
    float scale = (! lrq.dropout || do_dropout) ? 1.f : 0.5f;

    for (unsigned int iter = 0; iter < maxiter; ++iter, ++which)
      {
        // Add left LRQ features, holding right LRQ features fixed
        //     and vice versa
        // TODO: what happens with --lrq ab2 --lrq ac2
        //       i.e. namespace occurs multiple times (?)

        for (vector<string>::iterator i = lrq.lrpairs.begin ();
             i != lrq.lrpairs.end ();
             ++i)
          {
            unsigned char left = (*i)[which%2];
            unsigned char right = (*i)[(which+1)%2];
            unsigned int k = atoi (i->c_str () + 2);

            for (unsigned int lfn = 0; lfn < lrq.orig_size[left]; ++lfn)
              {
                feature* lf = ec.atomics[left].begin + lfn;
                float lfx = lf->x;
                size_t lindex = lf->weight_index + ec.ft_offset;

                for (unsigned int n = 1; n <= k; ++n)
                  {
                    if (! do_dropout || cheesyrbit (lrq.seed))
                      {
                        uint32_t lwindex = (uint32_t)(lindex + (n << all.reg.stride_shift));

                        float* lw = &all.reg.weight_vector[lwindex & all.reg.weight_mask];

                        // perturb away from saddle point at (0, 0)
                        if (is_learn && ! example_is_test (ec) && *lw == 0)
                          *lw = cheesyrand (lwindex);

                        for (unsigned int rfn = 0;
                             rfn < lrq.orig_size[right];
                             ++rfn)
                          {
                            feature* rf = ec.atomics[right].begin + rfn;
                            audit_data* ra = ec.audit_features[right].begin + rfn;

                            // NB: ec.ft_offset added by base learner
                            float rfx = rf->x;
                            size_t rindex = rf->weight_index;
                            uint32_t rwindex = (uint32_t)(rindex + (n << all.reg.stride_shift));

                            feature lrq;
                            lrq.x = scale * *lw * lfx * rfx;
                            lrq.weight_index = rwindex;

                            ec.atomics[right].push_back (lrq);

                            if (iter == 0 && (all.audit || all.hash_inv))
                              {
                                char* new_space = calloc_or_die<char>(4);
                                strcpy(new_space, "lrq");
                                size_t n_len = strlen(i->c_str () + 4);
                                size_t len = strlen(ra->feature) + n_len + 2;
                                char* new_feature = calloc_or_die<char>(len);
                                new_feature[0] = right;
                                new_feature[1] = '^';
                                strcat(new_feature, ra->feature);
                                strcat(new_feature, "^");
                                sprintf(new_feature+strlen(new_feature), "%d", n);
                                audit_data ad = { new_space, new_feature, lrq.weight_index, lrq.x, true };
                                ec.audit_features[right].push_back (ad);
                              }
                          }
                      }
                  }
              }
          }

	if (is_learn)
	  base.learn(ec);
	else
	  base.predict(ec);

        // Restore example
        if (iter == 0)
          {
            first_prediction = ec.pred.scalar;
            first_loss = ec.loss;
          }
        else
          {
            ec.pred.scalar = first_prediction;
            ec.loss = first_loss;
          }

        for (vector<string>::iterator i = lrq.lrpairs.begin ();
             i != lrq.lrpairs.end ();
             ++i)
          {
            unsigned char right = (*i)[(which+1)%2];

            ec.atomics[right].end =
              ec.atomics[right].begin + lrq.orig_size[right];

            if (all.audit)
              ec.audit_features[right].end =
                ec.audit_features[right].begin + lrq.orig_size[right];
          }
      }
  }

  base_learner* setup(vw& all)
  {//parse and set arguments
    new_options(all, "Lrq options")
      ("lrq", po::value<vector<string> > (), "use low rank quadratic features");
    if (missing_required(all)) return NULL;
    new_options(all)
      ("lrqdropout", "use dropout training for low rank quadratic features");
    add_options(all);

    if(!all.vm.count("lrq"))
      return NULL;

    LRQstate& lrq = calloc_or_die<LRQstate>();
    size_t maxk = 0;
    lrq.all = &all;

    size_t random_seed = 0;
    if (all.vm.count("random_seed")) random_seed = all.vm["random_seed"].as<size_t> ();

    lrq.initial_seed = lrq.seed = random_seed | 8675309;
    if (all.vm.count("lrqdropout"))
      lrq.dropout = true;
    else
      lrq.dropout = false;

    *all.file_options << " --lrqdropout ";

    lrq.lrpairs = all.vm["lrq"].as<vector<string> > ();

    for (vector<string>::iterator i = lrq.lrpairs.begin ();
	 i != lrq.lrpairs.end ();
	 ++i)
      *all.file_options << " --lrq " << *i;

    if (! all.quiet)
      {
        cerr << "creating low rank quadratic features for pairs: ";
        if (lrq.dropout)
          cerr << "(using dropout) ";
      }

    for (vector<string>::iterator i = lrq.lrpairs.begin ();
         i != lrq.lrpairs.end ();
         ++i)
      {
        if(!all.quiet){
          if (( i->length() < 3 ) || ! valid_int (i->c_str () + 2)) {
            cerr << endl << "error, low-rank quadratic features must involve two sets and a rank.\n";
            throw exception();
          }
          cerr << *i << " ";
        }
        // TODO: colon-syntax

        unsigned int k = atoi (i->c_str () + 2);

        lrq.lrindices[(int) (*i)[0]] = 1;
        lrq.lrindices[(int) (*i)[1]] = 1;

        maxk = max (maxk, k);
      }

    if(!all.quiet)
      cerr<<endl;

	all.wpp = all.wpp * (uint32_t)(1 + maxk);
    learner<LRQstate>& l = init_learner(&lrq, setup_base(all), predict_or_learn<true>,
					predict_or_learn<false>, 1 + maxk);
    l.set_end_pass(reset_seed);

    // TODO: leaks memory ?
    return make_base(l);
  }
}
<commit_msg>lrq arg bugfix<commit_after>#include <string.h>

#include <float.h>
#include "reductions.h"
#include "rand48.h"

using namespace LEARNER;

namespace LRQ {

  struct LRQstate {
    vw* all;
    bool lrindices[256];
    size_t orig_size[256];
    std::vector<std::string> lrpairs;
    bool dropout;
    uint64_t seed;
    uint64_t initial_seed;
  };
}

namespace {
  bool
  valid_int (const char* s)
    {
      char* endptr;

      int v = strtoul (s, &endptr, 0);
      (void) v;

      return (*s != '\0' && *endptr == '\0');
    }

  inline bool
  cheesyrbit (uint64_t& seed)
    {
      return merand48 (seed) > 0.5;
    }

  inline float
  cheesyrand (uint32_t x)
    {
      uint64_t seed = x;

      return merand48 (seed);
    }

  inline bool
  example_is_test (example& ec)
  {
    return ec.l.simple.label == FLT_MAX;
  }

  void
  reset_seed (LRQ::LRQstate& lrq)
    {
      if (lrq.all->bfgs)
        lrq.seed = lrq.initial_seed;
    }
}

namespace LRQ {

  template <bool is_learn>
  void predict_or_learn(LRQstate& lrq, base_learner& base, example& ec)
  {
    vw& all = *lrq.all;

    // Remember original features

    for (unsigned char* i = ec.indices.begin; i != ec.indices.end; ++i)
      {
        if (lrq.lrindices[*i])
          lrq.orig_size[*i] = ec.atomics[*i].size ();
      }

    size_t which = ec.example_counter;
    float first_prediction;
    float first_loss;
    unsigned int maxiter = (is_learn && ! example_is_test (ec)) ? 2 : 1;

    bool do_dropout = lrq.dropout && is_learn && ! example_is_test (ec);
    float scale = (! lrq.dropout || do_dropout) ? 1.f : 0.5f;

    for (unsigned int iter = 0; iter < maxiter; ++iter, ++which)
      {
        // Add left LRQ features, holding right LRQ features fixed
        //     and vice versa
        // TODO: what happens with --lrq ab2 --lrq ac2
        //       i.e. namespace occurs multiple times (?)

        for (vector<string>::iterator i = lrq.lrpairs.begin ();
             i != lrq.lrpairs.end ();
             ++i)
          {
            unsigned char left = (*i)[which%2];
            unsigned char right = (*i)[(which+1)%2];
            unsigned int k = atoi (i->c_str () + 2);

            for (unsigned int lfn = 0; lfn < lrq.orig_size[left]; ++lfn)
              {
                feature* lf = ec.atomics[left].begin + lfn;
                float lfx = lf->x;
                size_t lindex = lf->weight_index + ec.ft_offset;

                for (unsigned int n = 1; n <= k; ++n)
                  {
                    if (! do_dropout || cheesyrbit (lrq.seed))
                      {
                        uint32_t lwindex = (uint32_t)(lindex + (n << all.reg.stride_shift));

                        float* lw = &all.reg.weight_vector[lwindex & all.reg.weight_mask];

                        // perturb away from saddle point at (0, 0)
                        if (is_learn && ! example_is_test (ec) && *lw == 0)
                          *lw = cheesyrand (lwindex);

                        for (unsigned int rfn = 0;
                             rfn < lrq.orig_size[right];
                             ++rfn)
                          {
                            feature* rf = ec.atomics[right].begin + rfn;
                            audit_data* ra = ec.audit_features[right].begin + rfn;

                            // NB: ec.ft_offset added by base learner
                            float rfx = rf->x;
                            size_t rindex = rf->weight_index;
                            uint32_t rwindex = (uint32_t)(rindex + (n << all.reg.stride_shift));

                            feature lrq;
                            lrq.x = scale * *lw * lfx * rfx;
                            lrq.weight_index = rwindex;

                            ec.atomics[right].push_back (lrq);

                            if (iter == 0 && (all.audit || all.hash_inv))
                              {
                                char* new_space = calloc_or_die<char>(4);
                                strcpy(new_space, "lrq");
                                size_t n_len = strlen(i->c_str () + 4);
                                size_t len = strlen(ra->feature) + n_len + 2;
                                char* new_feature = calloc_or_die<char>(len);
                                new_feature[0] = right;
                                new_feature[1] = '^';
                                strcat(new_feature, ra->feature);
                                strcat(new_feature, "^");
                                sprintf(new_feature+strlen(new_feature), "%d", n);
                                audit_data ad = { new_space, new_feature, lrq.weight_index, lrq.x, true };
                                ec.audit_features[right].push_back (ad);
                              }
                          }
                      }
                  }
              }
          }

	if (is_learn)
	  base.learn(ec);
	else
	  base.predict(ec);

        // Restore example
        if (iter == 0)
          {
            first_prediction = ec.pred.scalar;
            first_loss = ec.loss;
          }
        else
          {
            ec.pred.scalar = first_prediction;
            ec.loss = first_loss;
          }

        for (vector<string>::iterator i = lrq.lrpairs.begin ();
             i != lrq.lrpairs.end ();
             ++i)
          {
            unsigned char right = (*i)[(which+1)%2];

            ec.atomics[right].end =
              ec.atomics[right].begin + lrq.orig_size[right];

            if (all.audit)
              ec.audit_features[right].end =
                ec.audit_features[right].begin + lrq.orig_size[right];
          }
      }
  }

  base_learner* setup(vw& all)
  {//parse and set arguments
    new_options(all, "Lrq options")
      ("lrq", po::value<vector<string> > (), "use low rank quadratic features");
    if (missing_required(all)) return NULL;
    new_options(all)
      ("lrqdropout", "use dropout training for low rank quadratic features");
    add_options(all);

    if(!all.vm.count("lrq"))
      return NULL;

    LRQstate& lrq = calloc_or_die<LRQstate>();
    size_t maxk = 0;
    lrq.all = &all;

    size_t random_seed = 0;
    if (all.vm.count("random_seed")) random_seed = all.vm["random_seed"].as<size_t> ();

    lrq.initial_seed = lrq.seed = random_seed | 8675309;
    if (all.vm.count("lrqdropout"))
      {
        lrq.dropout = true;
        *all.file_options << " --lrqdropout ";
      }
    else
      lrq.dropout = false;

    lrq.lrpairs = all.vm["lrq"].as<vector<string> > ();

    for (vector<string>::iterator i = lrq.lrpairs.begin ();
	 i != lrq.lrpairs.end ();
	 ++i)
      *all.file_options << " --lrq " << *i;

    if (! all.quiet)
      {
        cerr << "creating low rank quadratic features for pairs: ";
        if (lrq.dropout)
          cerr << "(using dropout) ";
      }

    for (vector<string>::iterator i = lrq.lrpairs.begin ();
         i != lrq.lrpairs.end ();
         ++i)
      {
        if(!all.quiet){
          if (( i->length() < 3 ) || ! valid_int (i->c_str () + 2)) {
            cerr << endl << "error, low-rank quadratic features must involve two sets and a rank.\n";
            throw exception();
          }
          cerr << *i << " ";
        }
        // TODO: colon-syntax

        unsigned int k = atoi (i->c_str () + 2);

        lrq.lrindices[(int) (*i)[0]] = 1;
        lrq.lrindices[(int) (*i)[1]] = 1;

        maxk = max (maxk, k);
      }

    if(!all.quiet)
      cerr<<endl;

	all.wpp = all.wpp * (uint32_t)(1 + maxk);
    learner<LRQstate>& l = init_learner(&lrq, setup_base(all), predict_or_learn<true>,
					predict_or_learn<false>, 1 + maxk);
    l.set_end_pass(reset_seed);

    // TODO: leaks memory ?
    return make_base(l);
  }
}
<|endoftext|>


<commit_before>/*
  Copyright (c) 2013, Dan VerWeire<dverweire@gmail.com>

  Permission to use, copy, modify, and/or distribute this software for any
  purpose with or without fee is hereby granted, provided that the above
  copyright notice and this permission notice appear in all copies.

  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include <string.h>
#include <v8.h>
#include <node.h>
#include <node_version.h>
#include <time.h>
#include <uv.h>

#include "odbc.h"
#include "odbc_connection.h"
#include "odbc_result.h"
#include "odbc_statement.h"

using namespace v8;
using namespace node;

Persistent<FunctionTemplate> ODBCResult::constructor_template;

void ODBCResult::Init(v8::Handle<Object> target) {
  DEBUG_PRINTF("ODBCResult::Init\n");
  HandleScope scope;

  Local<FunctionTemplate> t = FunctionTemplate::New(New);

  // Constructor Template
  constructor_template = Persistent<FunctionTemplate>::New(t);
  constructor_template->SetClassName(String::NewSymbol("ODBCResult"));

  // Reserve space for one Handle<Value>
  Local<ObjectTemplate> instance_template = constructor_template->InstanceTemplate();
  instance_template->SetInternalFieldCount(1);

  // Prototype Methods
  NODE_SET_PROTOTYPE_METHOD(constructor_template, "fetchAll", FetchAll);
  NODE_SET_PROTOTYPE_METHOD(constructor_template, "fetch", Fetch);

  NODE_SET_PROTOTYPE_METHOD(constructor_template, "moreResultsSync", MoreResultsSync);
  NODE_SET_PROTOTYPE_METHOD(constructor_template, "closeSync", CloseSync);
  NODE_SET_PROTOTYPE_METHOD(constructor_template, "fetchAllSync", FetchAllSync);

  // Attach the Database Constructor to the target object
  target->Set( v8::String::NewSymbol("ODBCResult"),
               constructor_template->GetFunction());

  scope.Close(Undefined());
}

ODBCResult::~ODBCResult() {
  this->Free();
}

void ODBCResult::Free() {
  DEBUG_PRINTF("ODBCResult::Free m_hSTMT=%X\n", m_hSTMT);

  if (m_hSTMT) {
    uv_mutex_lock(&ODBC::g_odbcMutex);

    //This doesn't actually deallocate the statement handle
    //that should not be done by the result object; that should
    //be done by the statement object
    //SQLFreeStmt(m_hSTMT, SQL_CLOSE);

    SQLFreeHandle( SQL_HANDLE_STMT, m_hSTMT);

    m_hSTMT = NULL;

    uv_mutex_unlock(&ODBC::g_odbcMutex);

    if (bufferLength > 0) {
      free(buffer);
    }
  }
}

Handle<Value> ODBCResult::New(const Arguments& args) {
  DEBUG_PRINTF("ODBCResult::New\n");

  HandleScope scope;

  REQ_EXT_ARG(0, js_henv);
  REQ_EXT_ARG(1, js_hdbc);
  REQ_EXT_ARG(2, js_hstmt);

  HENV hENV = static_cast<HENV>(js_henv->Value());
  HDBC hDBC = static_cast<HDBC>(js_hdbc->Value());
  HSTMT hSTMT = static_cast<HSTMT>(js_hstmt->Value());

  //create a new OBCResult object
  ODBCResult* objODBCResult = new ODBCResult(hENV, hDBC, hSTMT);

  DEBUG_PRINTF("ODBCResult::New m_hDBC=%X m_hDBC=%X m_hSTMT=%X\n",
    objODBCResult->m_hENV,
    objODBCResult->m_hDBC,
    objODBCResult->m_hSTMT
  );

  //specify the buffer length
  objODBCResult->bufferLength = MAX_VALUE_SIZE - 1;

  //initialze a buffer for this object
  objODBCResult->buffer = (uint16_t *) malloc(objODBCResult->bufferLength + 1);
  //TODO: make sure the malloc succeeded

  //set the initial colCount to 0
  objODBCResult->colCount = 0;

  objODBCResult->Wrap(args.Holder());

  return scope.Close(args.Holder());
}

/*
 * Fetch
 */

Handle<Value> ODBCResult::Fetch(const Arguments& args) {
  DEBUG_PRINTF("ODBCResult::Fetch\n");

  HandleScope scope;

  ODBCResult* objODBCResult = ObjectWrap::Unwrap<ODBCResult>(args.Holder());

  uv_work_t* work_req = (uv_work_t *) (calloc(1, sizeof(uv_work_t)));

  fetch_work_data* data = (fetch_work_data *) calloc(1, sizeof(fetch_work_data));

  Local<Function> cb;

  if (args.Length() == 0 || !args[0]->IsFunction()) {
    return ThrowException(Exception::TypeError(
              String::New("Argument 0 must be a callback function."))
    );
  }

  cb = Local<Function>::Cast(args[0]);

  data->cb = Persistent<Function>::New(cb);

  data->objResult = objODBCResult;
  work_req->data = data;

  uv_queue_work(
    uv_default_loop(),
    work_req,
    UV_Fetch,
    (uv_after_work_cb)UV_AfterFetch);

  objODBCResult->Ref();

  return scope.Close(Undefined());
}

void ODBCResult::UV_Fetch(uv_work_t* work_req) {
  DEBUG_PRINTF("ODBCResult::UV_Fetch\n");

  fetch_work_data* data = (fetch_work_data *)(work_req->data);

  data->result = SQLFetch(data->objResult->m_hSTMT);
}

void ODBCResult::UV_AfterFetch(uv_work_t* work_req, int status) {
  DEBUG_PRINTF("ODBCResult::UV_AfterFetch\n");

  HandleScope scope;

  fetch_work_data* data = (fetch_work_data *)(work_req->data);

  SQLRETURN ret = data->result;

  //check to see if there was an error
  if (ret == SQL_ERROR)  {
    ODBC::CallbackSQLError(
      data->objResult->m_hENV,
      data->objResult->m_hDBC,
      data->objResult->m_hSTMT,
      data->cb);

    free(data);
    free(work_req);

    data->objResult->Unref();

    return;
  }

  //check to see if we are at the end of the recordset
  if (ret == SQL_NO_DATA) {
    ODBC::FreeColumns(data->objResult->columns, &data->objResult->colCount);

    Handle<Value> args[2];
    args[0] = Null();
    args[1] = Null();

    data->cb->Call(Context::GetCurrent()->Global(), 2, args);
    data->cb.Dispose();

    free(data);
    free(work_req);

    data->objResult->Unref();

    return;
  }

  if (data->objResult->colCount == 0) {
    data->objResult->columns = ODBC::GetColumns(
      data->objResult->m_hSTMT,
      &data->objResult->colCount);
  }

  Handle<Value> args[2];

  args[0] = Null();
  args[1] = ODBC::GetRecordTuple(
    data->objResult->m_hSTMT,
    data->objResult->columns,
    &data->objResult->colCount,
    data->objResult->buffer,
    data->objResult->bufferLength);

  data->cb->Call(Context::GetCurrent()->Global(), 2, args);
  data->cb.Dispose();

  free(data);
  free(work_req);

  data->objResult->Unref();

  return;
}

/*
 * FetchAll
 */

Handle<Value> ODBCResult::FetchAll(const Arguments& args) {
  DEBUG_PRINTF("ODBCResult::FetchAll\n");

  HandleScope scope;

  ODBCResult* objODBCResult = ObjectWrap::Unwrap<ODBCResult>(args.Holder());

  uv_work_t* work_req = (uv_work_t *) (calloc(1, sizeof(uv_work_t)));

  fetch_work_data* data = (fetch_work_data *) calloc(1, sizeof(fetch_work_data));

  Local<Function> cb;

  if (args.Length() == 0 || !args[0]->IsFunction()) {
    return ThrowException(Exception::TypeError(
              String::New("Argument 0 must be a callback function."))
    );
  }

  cb = Local<Function>::Cast(args[0]);

  data->rows = Persistent<Array>::New(Array::New());
  data->errorCount = 0;
  data->count = 0;
  data->objError = Persistent<Object>::New(Object::New());

  data->cb = Persistent<Function>::New(cb);
  data->objResult = objODBCResult;

  work_req->data = data;

  uv_queue_work(uv_default_loop(),
    work_req,
    UV_FetchAll,
    (uv_after_work_cb)UV_AfterFetchAll);

  data->objResult->Ref();

  return scope.Close(Undefined());
}

void ODBCResult::UV_FetchAll(uv_work_t* work_req) {
  DEBUG_PRINTF("ODBCResult::UV_FetchAll\n");

  fetch_work_data* data = (fetch_work_data *)(work_req->data);

  data->result = SQLFetch(data->objResult->m_hSTMT);
 }

void ODBCResult::UV_AfterFetchAll(uv_work_t* work_req, int status) {
  DEBUG_PRINTF("ODBCResult::UV_AfterFetchAll\n");

  HandleScope scope;

  fetch_work_data* data = (fetch_work_data *)(work_req->data);

  ODBCResult* self = data->objResult->self();

  bool doMoreWork = true;

  if (self->colCount == 0) {
    self->columns = ODBC::GetColumns(self->m_hSTMT, &self->colCount);
  }

  //check to see if there was an error
  if (data->result == SQL_ERROR)  {
    data->errorCount++;

    data->objError = Persistent<Object>::New(ODBC::GetSQLError(
      self->m_hENV,
      self->m_hDBC,
      self->m_hSTMT,
      (char *) "[node-odbc] Error in ODBCResult::UV_AfterFetchAll"
    ));

    doMoreWork = false;
  }
  //check to see if we are at the end of the recordset
  else if (data->result == SQL_NO_DATA) {
    doMoreWork = false;
  }
  else {

    data->rows->Set(
      Integer::New(data->count),
      ODBC::GetRecordTuple(
        self->m_hSTMT,
        self->columns,
        &self->colCount,
        self->buffer,
        self->bufferLength)
    );

    data->count++;
  }

  if (doMoreWork) {
    //Go back to the thread pool and fetch more data!
    uv_queue_work(
      uv_default_loop(),
      work_req,
      UV_FetchAll,
      (uv_after_work_cb)UV_AfterFetchAll);
  }
  else {
    ODBC::FreeColumns(self->columns, &self->colCount);

    Handle<Value> args[2];
    //TODO: we need to return the error object if there was an error
    //however, on queries like "Drop...." the ret from SQLFetch is
    //SQL_ERROR, but there is not valid error message. I guess it's because
    //there is acually no result set...

    //if (self->errorCount > 0) {
    //  args[0] = objError;
    //}
    //else {
      args[0] = Null();
    //}
    args[1] = data->rows;

    data->cb->Call(Context::GetCurrent()->Global(), 2, args);
    data->cb.Dispose();

    //TODO: Do we need to free self->rows somehow?
    free(data);
    free(work_req);

    self->Unref();
  }

  scope.Close(Undefined());
}

/*
 * FetchAllSync
 */

Handle<Value> ODBCResult::FetchAllSync(const Arguments& args) {
  DEBUG_PRINTF("ODBCResult::FetchAllSync\n");

  HandleScope scope;

  ODBCResult* self = ObjectWrap::Unwrap<ODBCResult>(args.Holder());

  Local<Object> objError = Object::New();

  SQLRETURN ret;
  int count = 0;
  int errorCount = 0;

  if (self->colCount == 0) {
    self->columns = ODBC::GetColumns(self->m_hSTMT, &self->colCount);
  }

  Local<Array> rows = Array::New();

  //loop through all records
  while (true) {
    ret = SQLFetch(self->m_hSTMT);

    //check to see if there was an error
    if (ret == SQL_ERROR)  {
      errorCount++;

      objError = ODBC::GetSQLError(
        self->m_hENV,
        self->m_hDBC,
        self->m_hSTMT,
        (char *) "[node-odbc] Error in ODBCResult::UV_AfterFetchAll; probably"
          " your query did not have a result set."
      );

      break;
    }

    //check to see if we are at the end of the recordset
    if (ret == SQL_NO_DATA) {
      ODBC::FreeColumns(self->columns, &self->colCount);

      break;
    }

    rows->Set(
      Integer::New(count),
      ODBC::GetRecordTuple(
        self->m_hSTMT,
        self->columns,
        &self->colCount,
        self->buffer,
        self->bufferLength)
    );

    count++;
  }

  //TODO: we need to return the error object if there was an error
  //however, on queries like "Drop...." the ret from SQLFetch is
  //SQL_ERROR, but there is not valid error message. I guess it's because
  //there is acually no result set...
  //
  //we will need to throw if there is a valid error.
  if (errorCount > 0) {
    ThrowException(objError);
  }

  return scope.Close(rows);
}

Handle<Value> ODBCResult::CloseSync(const Arguments& args) {
  DEBUG_PRINTF("ODBCResult::Close\n");

  HandleScope scope;

  ODBCResult* result = ObjectWrap::Unwrap<ODBCResult>(args.Holder());

  result->Free();

  return scope.Close(Undefined());
}

Handle<Value> ODBCResult::MoreResultsSync(const Arguments& args) {
  DEBUG_PRINTF("ODBCResult::MoreResults\n");

  HandleScope scope;

  ODBCResult* result = ObjectWrap::Unwrap<ODBCResult>(args.Holder());
  //result->colCount = 0;

  SQLRETURN ret = SQLMoreResults(result->m_hSTMT);

  return scope.Close(SQL_SUCCEEDED(ret) ? True() : False());
}
<commit_msg>fix throwing of error in fetchAllSync when there are no columns; ie: during 'insert into...'<commit_after>/*
  Copyright (c) 2013, Dan VerWeire<dverweire@gmail.com>

  Permission to use, copy, modify, and/or distribute this software for any
  purpose with or without fee is hereby granted, provided that the above
  copyright notice and this permission notice appear in all copies.

  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include <string.h>
#include <v8.h>
#include <node.h>
#include <node_version.h>
#include <time.h>
#include <uv.h>

#include "odbc.h"
#include "odbc_connection.h"
#include "odbc_result.h"
#include "odbc_statement.h"

using namespace v8;
using namespace node;

Persistent<FunctionTemplate> ODBCResult::constructor_template;

void ODBCResult::Init(v8::Handle<Object> target) {
  DEBUG_PRINTF("ODBCResult::Init\n");
  HandleScope scope;

  Local<FunctionTemplate> t = FunctionTemplate::New(New);

  // Constructor Template
  constructor_template = Persistent<FunctionTemplate>::New(t);
  constructor_template->SetClassName(String::NewSymbol("ODBCResult"));

  // Reserve space for one Handle<Value>
  Local<ObjectTemplate> instance_template = constructor_template->InstanceTemplate();
  instance_template->SetInternalFieldCount(1);

  // Prototype Methods
  NODE_SET_PROTOTYPE_METHOD(constructor_template, "fetchAll", FetchAll);
  NODE_SET_PROTOTYPE_METHOD(constructor_template, "fetch", Fetch);

  NODE_SET_PROTOTYPE_METHOD(constructor_template, "moreResultsSync", MoreResultsSync);
  NODE_SET_PROTOTYPE_METHOD(constructor_template, "closeSync", CloseSync);
  NODE_SET_PROTOTYPE_METHOD(constructor_template, "fetchAllSync", FetchAllSync);

  // Attach the Database Constructor to the target object
  target->Set( v8::String::NewSymbol("ODBCResult"),
               constructor_template->GetFunction());

  scope.Close(Undefined());
}

ODBCResult::~ODBCResult() {
  this->Free();
}

void ODBCResult::Free() {
  DEBUG_PRINTF("ODBCResult::Free m_hSTMT=%X\n", m_hSTMT);

  if (m_hSTMT) {
    uv_mutex_lock(&ODBC::g_odbcMutex);

    //This doesn't actually deallocate the statement handle
    //that should not be done by the result object; that should
    //be done by the statement object
    //SQLFreeStmt(m_hSTMT, SQL_CLOSE);

    SQLFreeHandle( SQL_HANDLE_STMT, m_hSTMT);

    m_hSTMT = NULL;

    uv_mutex_unlock(&ODBC::g_odbcMutex);

    if (bufferLength > 0) {
      free(buffer);
    }
  }
}

Handle<Value> ODBCResult::New(const Arguments& args) {
  DEBUG_PRINTF("ODBCResult::New\n");

  HandleScope scope;

  REQ_EXT_ARG(0, js_henv);
  REQ_EXT_ARG(1, js_hdbc);
  REQ_EXT_ARG(2, js_hstmt);

  HENV hENV = static_cast<HENV>(js_henv->Value());
  HDBC hDBC = static_cast<HDBC>(js_hdbc->Value());
  HSTMT hSTMT = static_cast<HSTMT>(js_hstmt->Value());

  //create a new OBCResult object
  ODBCResult* objODBCResult = new ODBCResult(hENV, hDBC, hSTMT);

  DEBUG_PRINTF("ODBCResult::New m_hDBC=%X m_hDBC=%X m_hSTMT=%X\n",
    objODBCResult->m_hENV,
    objODBCResult->m_hDBC,
    objODBCResult->m_hSTMT
  );

  //specify the buffer length
  objODBCResult->bufferLength = MAX_VALUE_SIZE - 1;

  //initialze a buffer for this object
  objODBCResult->buffer = (uint16_t *) malloc(objODBCResult->bufferLength + 1);
  //TODO: make sure the malloc succeeded

  //set the initial colCount to 0
  objODBCResult->colCount = 0;

  objODBCResult->Wrap(args.Holder());

  return scope.Close(args.Holder());
}

/*
 * Fetch
 */

Handle<Value> ODBCResult::Fetch(const Arguments& args) {
  DEBUG_PRINTF("ODBCResult::Fetch\n");

  HandleScope scope;

  ODBCResult* objODBCResult = ObjectWrap::Unwrap<ODBCResult>(args.Holder());

  uv_work_t* work_req = (uv_work_t *) (calloc(1, sizeof(uv_work_t)));

  fetch_work_data* data = (fetch_work_data *) calloc(1, sizeof(fetch_work_data));

  Local<Function> cb;

  if (args.Length() == 0 || !args[0]->IsFunction()) {
    return ThrowException(Exception::TypeError(
              String::New("Argument 0 must be a callback function."))
    );
  }

  cb = Local<Function>::Cast(args[0]);

  data->cb = Persistent<Function>::New(cb);

  data->objResult = objODBCResult;
  work_req->data = data;

  uv_queue_work(
    uv_default_loop(),
    work_req,
    UV_Fetch,
    (uv_after_work_cb)UV_AfterFetch);

  objODBCResult->Ref();

  return scope.Close(Undefined());
}

void ODBCResult::UV_Fetch(uv_work_t* work_req) {
  DEBUG_PRINTF("ODBCResult::UV_Fetch\n");

  fetch_work_data* data = (fetch_work_data *)(work_req->data);

  data->result = SQLFetch(data->objResult->m_hSTMT);
}

void ODBCResult::UV_AfterFetch(uv_work_t* work_req, int status) {
  DEBUG_PRINTF("ODBCResult::UV_AfterFetch\n");

  HandleScope scope;

  fetch_work_data* data = (fetch_work_data *)(work_req->data);

  SQLRETURN ret = data->result;

  //check to see if there was an error
  if (ret == SQL_ERROR)  {
    ODBC::CallbackSQLError(
      data->objResult->m_hENV,
      data->objResult->m_hDBC,
      data->objResult->m_hSTMT,
      data->cb);

    free(data);
    free(work_req);

    data->objResult->Unref();

    return;
  }

  //check to see if we are at the end of the recordset
  if (ret == SQL_NO_DATA) {
    ODBC::FreeColumns(data->objResult->columns, &data->objResult->colCount);

    Handle<Value> args[2];
    args[0] = Null();
    args[1] = Null();

    data->cb->Call(Context::GetCurrent()->Global(), 2, args);
    data->cb.Dispose();

    free(data);
    free(work_req);

    data->objResult->Unref();

    return;
  }

  if (data->objResult->colCount == 0) {
    data->objResult->columns = ODBC::GetColumns(
      data->objResult->m_hSTMT,
      &data->objResult->colCount);
  }

  Handle<Value> args[2];

  args[0] = Null();
  args[1] = ODBC::GetRecordTuple(
    data->objResult->m_hSTMT,
    data->objResult->columns,
    &data->objResult->colCount,
    data->objResult->buffer,
    data->objResult->bufferLength);

  data->cb->Call(Context::GetCurrent()->Global(), 2, args);
  data->cb.Dispose();

  free(data);
  free(work_req);

  data->objResult->Unref();

  return;
}

/*
 * FetchAll
 */

Handle<Value> ODBCResult::FetchAll(const Arguments& args) {
  DEBUG_PRINTF("ODBCResult::FetchAll\n");

  HandleScope scope;

  ODBCResult* objODBCResult = ObjectWrap::Unwrap<ODBCResult>(args.Holder());

  uv_work_t* work_req = (uv_work_t *) (calloc(1, sizeof(uv_work_t)));

  fetch_work_data* data = (fetch_work_data *) calloc(1, sizeof(fetch_work_data));

  Local<Function> cb;

  if (args.Length() == 0 || !args[0]->IsFunction()) {
    return ThrowException(Exception::TypeError(
              String::New("Argument 0 must be a callback function."))
    );
  }

  cb = Local<Function>::Cast(args[0]);

  data->rows = Persistent<Array>::New(Array::New());
  data->errorCount = 0;
  data->count = 0;
  data->objError = Persistent<Object>::New(Object::New());

  data->cb = Persistent<Function>::New(cb);
  data->objResult = objODBCResult;

  work_req->data = data;

  uv_queue_work(uv_default_loop(),
    work_req,
    UV_FetchAll,
    (uv_after_work_cb)UV_AfterFetchAll);

  data->objResult->Ref();

  return scope.Close(Undefined());
}

void ODBCResult::UV_FetchAll(uv_work_t* work_req) {
  DEBUG_PRINTF("ODBCResult::UV_FetchAll\n");

  fetch_work_data* data = (fetch_work_data *)(work_req->data);

  data->result = SQLFetch(data->objResult->m_hSTMT);
 }

void ODBCResult::UV_AfterFetchAll(uv_work_t* work_req, int status) {
  DEBUG_PRINTF("ODBCResult::UV_AfterFetchAll\n");

  HandleScope scope;

  fetch_work_data* data = (fetch_work_data *)(work_req->data);

  ODBCResult* self = data->objResult->self();

  bool doMoreWork = true;

  if (self->colCount == 0) {
    self->columns = ODBC::GetColumns(self->m_hSTMT, &self->colCount);
  }

  //check to see if there was an error
  if (data->result == SQL_ERROR)  {
    data->errorCount++;

    data->objError = Persistent<Object>::New(ODBC::GetSQLError(
      self->m_hENV,
      self->m_hDBC,
      self->m_hSTMT,
      (char *) "[node-odbc] Error in ODBCResult::UV_AfterFetchAll"
    ));

    doMoreWork = false;
  }
  //check to see if we are at the end of the recordset
  else if (data->result == SQL_NO_DATA) {
    doMoreWork = false;
  }
  else {

    data->rows->Set(
      Integer::New(data->count),
      ODBC::GetRecordTuple(
        self->m_hSTMT,
        self->columns,
        &self->colCount,
        self->buffer,
        self->bufferLength)
    );

    data->count++;
  }

  if (doMoreWork) {
    //Go back to the thread pool and fetch more data!
    uv_queue_work(
      uv_default_loop(),
      work_req,
      UV_FetchAll,
      (uv_after_work_cb)UV_AfterFetchAll);
  }
  else {
    ODBC::FreeColumns(self->columns, &self->colCount);

    Handle<Value> args[2];
    //TODO: we need to return the error object if there was an error
    //however, on queries like "Drop...." the ret from SQLFetch is
    //SQL_ERROR, but there is not valid error message. I guess it's because
    //there is acually no result set...

    //if (self->errorCount > 0) {
    //  args[0] = objError;
    //}
    //else {
      args[0] = Null();
    //}
    args[1] = data->rows;

    data->cb->Call(Context::GetCurrent()->Global(), 2, args);
    data->cb.Dispose();

    //TODO: Do we need to free self->rows somehow?
    free(data);
    free(work_req);

    self->Unref();
  }

  scope.Close(Undefined());
}

/*
 * FetchAllSync
 */

Handle<Value> ODBCResult::FetchAllSync(const Arguments& args) {
  DEBUG_PRINTF("ODBCResult::FetchAllSync\n");

  HandleScope scope;

  ODBCResult* self = ObjectWrap::Unwrap<ODBCResult>(args.Holder());

  Local<Object> objError = Object::New();

  SQLRETURN ret;
  int count = 0;
  int errorCount = 0;

  if (self->colCount == 0) {
    self->columns = ODBC::GetColumns(self->m_hSTMT, &self->colCount);
  }

  Local<Array> rows = Array::New();

  //Only loop through the recordset if there are columns
  if (self->colCount > 0) {
    //loop through all records
    while (true) {
      ret = SQLFetch(self->m_hSTMT);

      //check to see if there was an error
      if (ret == SQL_ERROR)  {
        errorCount++;

        objError = ODBC::GetSQLError(
          self->m_hENV,
          self->m_hDBC,
          self->m_hSTMT,
          (char *) "[node-odbc] Error in ODBCResult::UV_AfterFetchAll; probably"
            " your query did not have a result set."
        );

        break;
      }

      //check to see if we are at the end of the recordset
      if (ret == SQL_NO_DATA) {
        ODBC::FreeColumns(self->columns, &self->colCount);

        break;
      }

      rows->Set(
        Integer::New(count),
        ODBC::GetRecordTuple(
          self->m_hSTMT,
          self->columns,
          &self->colCount,
          self->buffer,
          self->bufferLength)
      );

      count++;
    }
  }
  else {
    ODBC::FreeColumns(self->columns, &self->colCount);
  }

  //throw the error object if there were errors
  if (errorCount > 0) {
    ThrowException(objError);
  }

  return scope.Close(rows);
}

Handle<Value> ODBCResult::CloseSync(const Arguments& args) {
  DEBUG_PRINTF("ODBCResult::Close\n");

  HandleScope scope;

  ODBCResult* result = ObjectWrap::Unwrap<ODBCResult>(args.Holder());

  result->Free();

  return scope.Close(Undefined());
}

Handle<Value> ODBCResult::MoreResultsSync(const Arguments& args) {
  DEBUG_PRINTF("ODBCResult::MoreResults\n");

  HandleScope scope;

  ODBCResult* result = ObjectWrap::Unwrap<ODBCResult>(args.Holder());
  //result->colCount = 0;

  SQLRETURN ret = SQLMoreResults(result->m_hSTMT);

  return scope.Close(SQL_SUCCEEDED(ret) ? True() : False());
}
<|endoftext|>


<commit_before>#include "BoundaryMatrix.hh"
#include "Vector.hh"
#include "IO.hh"
#include "Standard.hh"
#include "Twist.hh"
#include "PersistencePairs.hh"

#include <iostream>

using namespace aleph;
using namespace representations;

using I  = unsigned;
using V  = Vector<I>;
using BM = BoundaryMatrix<V>;
using SR = StandardReduction;
using TR = TwistReduction;

int main()
{
  auto M = load<BM>( "Triangle.txt" );

  std::cout << "* Boundary matrix\n" << M << "\n"
            << "* Maximum dimension: " << M.getDimension() << "\n";

  computePersistencePairs<SR>( M );
  computePersistencePairs<TR>( M );
}
<commit_msg>Extended test application with simplicial complex class<commit_after>#include "BoundaryMatrix.hh"
#include "Vector.hh"
#include "IO.hh"
#include "Standard.hh"
#include "Twist.hh"
#include "PersistencePairs.hh"

#include "Conversions.hh"
#include "Simplex.hh"
#include "SimplicialComplex.hh"

#include <iostream>

using namespace aleph;
using namespace representations;

using I  = unsigned;
using V  = Vector<I>;
using BM = BoundaryMatrix<V>;
using SR = StandardReduction;
using TR = TwistReduction;

using S  = Simplex<float, unsigned>;
using SC = SimplicialComplex<S>;

int main()
{
  auto M = load<BM>( "Triangle.txt" );

  std::cout << "* Boundary matrix\n" << M << "\n"
            << "* Maximum dimension: " << M.getDimension() << "\n";

  computePersistencePairs<SR>( M );
  computePersistencePairs<TR>( M );

  {
    S simplex( {0,1,2} );
    SC K( { {0}, {1}, {2}, {0,1}, {0,2}, {1,2}, {0,1,2} } );

    std::cout << K;

    auto M = makeBoundaryMatrix<BM>( K );

    computePersistencePairs<SR>( M );
    computePersistencePairs<TR>( M );
  }
}
<|endoftext|>


<commit_before>#include "../mng/mng.h"
#include "sort.h"
#include "../containers/vector"

//! \example algo/sort.cpp
//! This is an example of how to use \c stxxl::sort() algorithm

using namespace stxxl;

#define RECORD_SIZE 512

struct my_type
{
	typedef unsigned key_type;

	key_type _key;
	char _data[RECORD_SIZE - sizeof(key_type)];
	key_type key() const {return _key; };

	my_type() {};
	my_type(key_type __key):_key(__key) {};

	static my_type min_value(){ return my_type(0); };
	static my_type max_value(){ return my_type(0xffffffff); };
};

std::ostream & operator << (std::ostream & o, const my_type & obj)
{
	o << obj._key;
	return o;
}

bool operator < (const my_type & a, const my_type & b)
{
	return a.key() < b.key();
}

bool operator != (const my_type & a, const my_type & b)
{
	return a.key() != b.key();
}

struct cmp: public std::less<my_type>
{
  	my_type min_value() const { return my_type(0); };
	my_type max_value() const { return my_type(0xffffffff); };
};

int main()
{
		unsigned memory_to_use = 512*1024*1024;
		typedef stxxl::vector<my_type> vector_type;
		const stxxl::int64 n_records =
			stxxl::int64(1*1024+512)*stxxl::int64(1024*1024)/sizeof(my_type);
		vector_type v(n_records);

    		random_number32 rnd;
		STXXL_MSG("Filling vector..., input size ="<<v.size())
		for(stxxl::int64 i=0; i < v.size(); i++)
			v[i]._key = 1 + (rnd()%0xfffffff);

		STXXL_MSG("Checking order...")
		STXXL_MSG( ((stxxl::is_sorted(v.begin(),v.end()))?"OK":"WRONG" ));

		STXXL_MSG("Sorting...")
		stxxl::sort(v.begin(),v.end(),cmp(),memory_to_use);

		STXXL_MSG("Checking order...")
		STXXL_MSG( ((stxxl::is_sorted(v.begin(),v.end()))?"OK":"WRONG" ));

		STXXL_MSG("Done, output size="<<v.size())

		return 0;
}
<commit_msg><commit_after>#include "../mng/mng.h"
#include "sort.h"
#include "../containers/vector"

//! \example algo/sort.cpp
//! This is an example of how to use \c stxxl::sort() algorithm

using namespace stxxl;

#define RECORD_SIZE 8

struct my_type
{
	typedef unsigned key_type;

	key_type _key;
	char _data[RECORD_SIZE - sizeof(key_type)];
	key_type key() const {return _key; };

	my_type() {};
	my_type(key_type __key):_key(__key) {};

	static my_type min_value(){ return my_type(0); };
	static my_type max_value(){ return my_type(0xffffffff); };
};

std::ostream & operator << (std::ostream & o, const my_type & obj)
{
	o << obj._key;
	return o;
}

bool operator < (const my_type & a, const my_type & b)
{
	return a.key() < b.key();
}

bool operator != (const my_type & a, const my_type & b)
{
	return a.key() != b.key();
}

struct cmp: public std::less<my_type>
{
  	my_type min_value() const { return my_type(0); };
	my_type max_value() const { return my_type(0xffffffff); };
};

int main()
{
		unsigned memory_to_use = 512*1024*1024;
		typedef stxxl::vector<my_type> vector_type;
		const stxxl::int64 n_records =
			stxxl::int64(1*1024+512)*stxxl::int64(1024*1024)/sizeof(my_type);
		vector_type v(n_records);

    		random_number32 rnd;
		STXXL_MSG("Filling vector..., input size ="<<v.size())
		for(stxxl::int64 i=0; i < v.size(); i++)
			v[i]._key = 1 + (rnd()%0xfffffff);

		STXXL_MSG("Checking order...")
		STXXL_MSG( ((stxxl::is_sorted(v.begin(),v.end()))?"OK":"WRONG" ));

		STXXL_MSG("Sorting...")
		stxxl::sort(v.begin(),v.end(),cmp(),memory_to_use);

		STXXL_MSG("Checking order...")
		STXXL_MSG( ((stxxl::is_sorted(v.begin(),v.end()))?"OK":"WRONG" ));

		STXXL_MSG("Done, output size="<<v.size())

		return 0;
}
<|endoftext|>


<commit_before>/******************************************************************************\
* File:          app.cpp
* Purpose:       Implementation of wxExApp class
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/config.h>
#include <wx/dir.h>
#ifdef wxExUSE_PORTABLE
#include <wx/fileconf.h>
#endif
#include <wx/stdpaths.h>
#include <wx/extension/app.h>
#include <wx/extension/frd.h>
#include <wx/extension/lexers.h>
#include <wx/extension/log.h>
#include <wx/extension/printing.h>
#include <wx/extension/tool.h>
#include <wx/extension/vcs.h>

int wxExApp::OnExit()
{
  delete wxExFindReplaceData::Set(NULL);
  delete wxExLexers::Set(NULL);
  delete wxExLog::Set(NULL);
  delete wxExPrinting::Set(NULL);
  delete wxExTool::Set(NULL);
  delete wxExVCS::Set(NULL);

  return wxApp::OnExit(); // this destroys the config
}

bool wxExApp::OnInit()
{
  if (!wxApp::OnInit())
  {
    return false;
  }

  // Init the localization, from now on things will be translated.
  if (m_Locale.Init())
  {
    // If there are catalogs in the catalog_dir, then add them to the m_Locale.
    // README: We use the canonical name, also for windows, not sure whether that is
    // the best.
    const wxString catalogDir = wxStandardPaths::Get().GetLocalizedResourcesDir(
      m_Locale.GetCanonicalName(),
      // This seems to be necessarty for wxGTK. For wxMSW it isn't used.
      wxStandardPaths::ResourceCat_Messages);

    if (wxFileName::DirExists(catalogDir))
    {
      wxArrayString files;
      wxDir::GetAllFiles(catalogDir, &files);

      for (
        wxArrayString::const_iterator it = files.begin();
        it != files.end();
        it++)
      {
        // Default the wxstd is already loaded by m_Locale.Init(),
        // so do not do it twice.
        const wxFileName fn(*it);

        if (!m_Locale.IsLoaded(fn.GetName()))
        {
          if (!m_Locale.AddCatalog(fn.GetName()))
          {
            wxLogError("Catalog could not be added: " + fn.GetName());
          }
        }
      }
    }
  }

  // Now construct the config, as most classes use it.
  wxConfigBase* config;
#ifdef wxExUSE_PORTABLE
  config = new wxFileConfig(
    wxEmptyString,
    wxEmptyString,
    wxFileName(
      wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath(),
      GetAppName() + wxString(".cfg")).GetFullPath(),
    wxEmptyString,
    wxCONFIG_USE_LOCAL_FILE);
#else
  // As wxStandardPaths::GetUserDataDir is used, subdir is necessary for config.
  // (ignored on non-Unix system)
  config = new wxConfig(
    wxEmptyString,
    wxEmptyString,
    wxEmptyString,
    wxEmptyString,
    wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_SUBDIR);
#endif
  wxConfigBase::Set(config);

  return true;
}
<commit_msg>set eol-style<commit_after>/******************************************************************************\
* File:          app.cpp
* Purpose:       Implementation of wxExApp class
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/config.h>
#include <wx/dir.h>
#ifdef wxExUSE_PORTABLE
#include <wx/fileconf.h>
#endif
#include <wx/stdpaths.h>
#include <wx/extension/app.h>
#include <wx/extension/frd.h>
#include <wx/extension/lexers.h>
#include <wx/extension/log.h>
#include <wx/extension/printing.h>
#include <wx/extension/tool.h>
#include <wx/extension/vcs.h>

int wxExApp::OnExit()
{
  delete wxExFindReplaceData::Set(NULL);
  delete wxExLexers::Set(NULL);
  delete wxExLog::Set(NULL);
  delete wxExPrinting::Set(NULL);
  delete wxExTool::Set(NULL);
  delete wxExVCS::Set(NULL);

  return wxApp::OnExit(); // this destroys the config
}

bool wxExApp::OnInit()
{
  if (!wxApp::OnInit())
  {
    return false;
  }

  // Init the localization, from now on things will be translated.
  if (m_Locale.Init())
  {
    // If there are catalogs in the catalog_dir, then add them to the m_Locale.
    // README: We use the canonical name, also for windows, not sure whether that is
    // the best.
    const wxString catalogDir = wxStandardPaths::Get().GetLocalizedResourcesDir(
      m_Locale.GetCanonicalName(),
      // This seems to be necessarty for wxGTK. For wxMSW it isn't used.
      wxStandardPaths::ResourceCat_Messages);

    if (wxFileName::DirExists(catalogDir))
    {
      wxArrayString files;
      wxDir::GetAllFiles(catalogDir, &files);

      for (
        wxArrayString::const_iterator it = files.begin();
        it != files.end();
        it++)
      {
        // Default the wxstd is already loaded by m_Locale.Init(),
        // so do not do it twice.
        const wxFileName fn(*it);

        if (!m_Locale.IsLoaded(fn.GetName()))
        {
          if (!m_Locale.AddCatalog(fn.GetName()))
          {
            wxLogError("Catalog could not be added: " + fn.GetName());
          }
        }
      }
    }
  }

  // Now construct the config, as most classes use it.
  wxConfigBase* config;
#ifdef wxExUSE_PORTABLE
  config = new wxFileConfig(
    wxEmptyString,
    wxEmptyString,
    wxFileName(
      wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath(),
      GetAppName() + wxString(".cfg")).GetFullPath(),
    wxEmptyString,
    wxCONFIG_USE_LOCAL_FILE);
#else
  // As wxStandardPaths::GetUserDataDir is used, subdir is necessary for config.
  // (ignored on non-Unix system)
  config = new wxConfig(
    wxEmptyString,
    wxEmptyString,
    wxEmptyString,
    wxEmptyString,
    wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_SUBDIR);
#endif
  wxConfigBase::Set(config);

  return true;
}
<|endoftext|>