<commit_before>/*********************************************************************
* Software License Agreement (BSD License)
*
*  Copyright (c) 2008, Willow Garage, Inc.
*  All rights reserved.
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*   * Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*   * Redistributions in binary form must reproduce the above
*     copyright notice, this list of conditions and the following
*     disclaimer in the documentation and/or other materials provided
*     with the distribution.
*   * Neither the name of the Willow Garage nor the names of its
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
*  POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/

/* Author: Wim Meeussen */

#include <boost/algorithm/string.hpp>
#include <ros/ros.h>
#include <vector>
#include "urdf/model.h"

namespace urdf{

Model::Model()
{
  this->clear();
}

void Model::clear()
{
  name_.clear();
  this->links_.clear();
  this->joints_.clear();
  this->materials_.clear();
  this->root_link_.reset();
}

bool Model::initFile(const std::string& filename)
{
  TiXmlDocument xml_doc;
  xml_doc.LoadFile(filename);

  return initXml(&xml_doc);
}

bool Model::initString(const std::string& xml_string)
{
  TiXmlDocument xml_doc;
  xml_doc.Parse(xml_string.c_str());

  return initXml(&xml_doc);
}

bool Model::initXml(TiXmlDocument *xml_doc)
{
  if (!xml_doc)
  {
    ROS_ERROR("Could not parse the xml");
    return false;
  }

  TiXmlElement *robot_xml = xml_doc->FirstChildElement("robot");
  if (!robot_xml)
  {
    ROS_ERROR("Could not find the 'robot' element in the xml file");
    return false;
  }
  return initXml(robot_xml);
}

bool Model::initXml(TiXmlElement *robot_xml)
{
  this->clear();

  ROS_DEBUG("Parsing robot xml");
  if (!robot_xml) return false;

  // Get robot name
  const char *name = robot_xml->Attribute("name");
  if (!name)
  {
    ROS_ERROR("No name given for the robot.");
    return false;
  }
  this->name_ = std::string(name);

  // Get all Material elements
  for (TiXmlElement* material_xml = robot_xml->FirstChildElement("material"); material_xml; material_xml = material_xml->NextSiblingElement("material"))
  {
    boost::shared_ptr<Material> material;
    material.reset(new Material);

    if (material->initXml(material_xml))
    {
      if (this->getMaterial(material->name))
      {
        ROS_ERROR("material '%s' is not unique.", material->name.c_str());
        material.reset();
        return false;
      }
      else
      {
        this->materials_.insert(make_pair(material->name,material));
        ROS_DEBUG("successfully added a new material '%s'", material->name.c_str());
      }
    }
    else
    {
      ROS_ERROR("material xml is not initialized correctly");
      material.reset();
    }
  }

  // Get all Link elements
  for (TiXmlElement* link_xml = robot_xml->FirstChildElement("link"); link_xml; link_xml = link_xml->NextSiblingElement("link"))
  {
    boost::shared_ptr<Link> link;
    link.reset(new Link);

    if (link->initXml(link_xml))
    {
      if (this->getLink(link->name))
      {
        ROS_ERROR("link '%s' is not unique.", link->name.c_str());
        link.reset();
        return false;
      }
      else
      {
        // set link visual material
        ROS_DEBUG("setting link '%s' material", link->name.c_str());
        if (link->visual)
        {
          if (!link->visual->material_name.empty())
          {
            if (this->getMaterial(link->visual->material_name))
            {
              ROS_DEBUG("setting link '%s' material to '%s'", link->name.c_str(),link->visual->material_name.c_str());
              link->visual->material = this->getMaterial( link->visual->material_name.c_str() );
            }
            else
            {
              if (link->visual->material)
              {
                ROS_DEBUG("link '%s' material '%s' defined in Visual.", link->name.c_str(),link->visual->material_name.c_str());
                this->materials_.insert(make_pair(link->visual->material->name,link->visual->material));
              }
              else
              {
                ROS_ERROR("link '%s' material '%s' undefined.", link->name.c_str(),link->visual->material_name.c_str());
                link.reset();
                return false;
              }
            }
          }
        }

        this->links_.insert(make_pair(link->name,link));
        ROS_DEBUG("successfully added a new link '%s'", link->name.c_str());
      }
    }
    else
    {
      ROS_ERROR("link xml is not initialized correctly");
      link.reset();
    }
  }
  // Get all Joint elements
  for (TiXmlElement* joint_xml = robot_xml->FirstChildElement("joint"); joint_xml; joint_xml = joint_xml->NextSiblingElement("joint"))
  {
    boost::shared_ptr<Joint> joint;
    joint.reset(new Joint);

    if (joint->initXml(joint_xml))
    {
      if (this->getJoint(joint->name))
      {
        ROS_ERROR("joint '%s' is not unique.", joint->name.c_str());
        joint.reset();
        return false;
      }
      else
      {
        this->joints_.insert(make_pair(joint->name,joint));
        ROS_DEBUG("successfully added a new joint '%s'", joint->name.c_str());
      }
    }
    else
    {
      ROS_ERROR("joint xml is not initialized correctly");
      joint.reset();
    }
  }

  // every link has children links and joints, but no parents, so we create a
  // local convenience data structure for keeping child->parent relations
  std::map<std::string, std::string> parent_link_tree;
  parent_link_tree.clear();

  // building tree: name mapping
  if (!this->initTree(parent_link_tree))
  {
    ROS_ERROR("failed to build tree");
    return false;
  }

  // find the root link
  if (!this->initRoot(parent_link_tree))
  {
    ROS_ERROR("failed to find root link");
    return false;
  }

  return true;
}

bool Model::initTree(std::map<std::string, std::string> &parent_link_tree)
{
  // loop through all joints, for every link, assign children links and children joints
  for (std::map<std::string,boost::shared_ptr<Joint> >::iterator joint = this->joints_.begin();joint != this->joints_.end(); joint++)
  {
    std::string parent_link_name = joint->second->parent_link_name;
    std::string child_link_name = joint->second->child_link_name;

    ROS_DEBUG("build tree: joint: '%s' has parent link '%s' and child  link '%s'", joint->first.c_str(), parent_link_name.c_str(),child_link_name.c_str());

    /// add an empty "world" link
    if (parent_link_name == "world")
    {
      if (this->getLink(parent_link_name))
      {
        ROS_DEBUG("    parent link '%s' already exists.", parent_link_name.c_str());
      }
      else
      {
        ROS_DEBUG("    parent link '%s' is a special case, adding fake link.", parent_link_name.c_str());
        boost::shared_ptr<Link> link;
        link.reset(new Link);
        link->name = "world";
        this->links_.insert(make_pair(link->name,link));
        ROS_DEBUG("        successfully added new link '%s'", link->name.c_str());
      }
    }

    if (parent_link_name.empty())
    {
      ROS_DEBUG("    Joint %s: does not have parent link name specified. Joint is an abstract joint.",(joint->second)->name.c_str());
    }
    else if (child_link_name.empty())
    {
      ROS_DEBUG("    Joint %s: does not have child link name specified. Joint is an abstract joint.",(joint->second)->name.c_str());
    }
    else
    {
      // find parent link
      boost::shared_ptr<Link> parent_link;
      this->getLink(parent_link_name, parent_link);

      if (!parent_link)
      {
        ROS_ERROR("    parent link '%s' is not found", parent_link_name.c_str());
        return false;
      }
      else
      {
        // find child link
        boost::shared_ptr<Link> child_link;
        this->getLink(child_link_name, child_link);

        if (!child_link)
        {
          ROS_ERROR("    for joint: %s child link '%s' is not found",joint->first.c_str(),child_link_name.c_str());
          return false;
        }
        else
        {
          //set parent link for child link
          child_link->setParent(parent_link);

          //set parent joint for child link
          child_link->setParentJoint(joint->second);

          //set child joint for parent link
          parent_link->addChildJoint(joint->second);

          //set child link for parent link
          parent_link->addChild(child_link);

          // fill in child/parent string map
          parent_link_tree[child_link->name] = parent_link_name;

          ROS_DEBUG("    now Link '%s' has %i children ", parent_link->name.c_str(), (int)parent_link->child_links.size());
        }
      }
    }
  }

  return true;
}

bool Model::initRoot(std::map<std::string, std::string> &parent_link_tree)
{

  this->root_link_.reset();

  for (std::map<std::string, std::string>::iterator p=parent_link_tree.begin(); p!=parent_link_tree.end(); p++)
  {
    if (parent_link_tree.find(p->second) == parent_link_tree.end())
    {
      if (this->root_link_)
      {
        ROS_DEBUG("child '%s', parent '%s', root '%s'", p->first.c_str(), p->second.c_str(), this->root_link_->name.c_str());
        if (this->root_link_->name != p->second)
        {
          ROS_ERROR("Two root links found: '%s' and '%s'", this->root_link_->name.c_str(), p->second.c_str());
          return false;
        }
      }
      else
         getLink(p->second,this->root_link_);
    }
  }
  if (!this->root_link_)
  {
    ROS_ERROR("No root link found. The robot xml is empty or not a tree.");
    return false;
  }
  ROS_DEBUG("Link '%s' is the root link", this->root_link_->name.c_str());

  return true;
}

boost::shared_ptr<Material> Model::getMaterial(const std::string& name) const
{
  boost::shared_ptr<Material> ptr;
  if (this->materials_.find(name) == this->materials_.end())
    ptr.reset();
  else
    ptr = this->materials_.find(name)->second;
  return ptr;
}

boost::shared_ptr<const Link> Model::getLink(const std::string& name) const
{
  boost::shared_ptr<const Link> ptr;
  if (this->links_.find(name) == this->links_.end())
    ptr.reset();
  else
    ptr = this->links_.find(name)->second;
  return ptr;
}

void Model::getLinks(std::vector<boost::shared_ptr<Link> >& links) const
{
  for (std::map<std::string,boost::shared_ptr<Link> >::const_iterator link = this->links_.begin();link != this->links_.end(); link++)
  {
    links.push_back(link->second);
  }
}

void Model::getLink(const std::string& name,boost::shared_ptr<Link> &link) const
{
  boost::shared_ptr<Link> ptr;
  if (this->links_.find(name) == this->links_.end())
    ptr.reset();
  else
    ptr = this->links_.find(name)->second;
  link = ptr;
}

boost::shared_ptr<const Joint> Model::getJoint(const std::string& name) const
{
  boost::shared_ptr<const Joint> ptr;
  if (this->joints_.find(name) == this->joints_.end())
    ptr.reset();
  else
    ptr = this->joints_.find(name)->second;
  return ptr;
}

}

<commit_msg>update error messages.<commit_after>/*********************************************************************
* Software License Agreement (BSD License)
*
*  Copyright (c) 2008, Willow Garage, Inc.
*  All rights reserved.
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*   * Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*   * Redistributions in binary form must reproduce the above
*     copyright notice, this list of conditions and the following
*     disclaimer in the documentation and/or other materials provided
*     with the distribution.
*   * Neither the name of the Willow Garage nor the names of its
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
*  POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/

/* Author: Wim Meeussen */

#include <boost/algorithm/string.hpp>
#include <ros/ros.h>
#include <vector>
#include "urdf/model.h"

namespace urdf{

Model::Model()
{
  this->clear();
}

void Model::clear()
{
  name_.clear();
  this->links_.clear();
  this->joints_.clear();
  this->materials_.clear();
  this->root_link_.reset();
}

bool Model::initFile(const std::string& filename)
{
  TiXmlDocument xml_doc;
  xml_doc.LoadFile(filename);

  return initXml(&xml_doc);
}

bool Model::initString(const std::string& xml_string)
{
  TiXmlDocument xml_doc;
  xml_doc.Parse(xml_string.c_str());

  return initXml(&xml_doc);
}

bool Model::initXml(TiXmlDocument *xml_doc)
{
  if (!xml_doc)
  {
    ROS_ERROR("Could not parse the xml");
    return false;
  }

  TiXmlElement *robot_xml = xml_doc->FirstChildElement("robot");
  if (!robot_xml)
  {
    ROS_ERROR("Could not find the 'robot' element in the xml file");
    return false;
  }
  return initXml(robot_xml);
}

bool Model::initXml(TiXmlElement *robot_xml)
{
  this->clear();

  ROS_DEBUG("Parsing robot xml");
  if (!robot_xml) return false;

  // Get robot name
  const char *name = robot_xml->Attribute("name");
  if (!name)
  {
    ROS_ERROR("No name given for the robot.");
    return false;
  }
  this->name_ = std::string(name);

  // Get all Material elements
  for (TiXmlElement* material_xml = robot_xml->FirstChildElement("material"); material_xml; material_xml = material_xml->NextSiblingElement("material"))
  {
    boost::shared_ptr<Material> material;
    material.reset(new Material);

    if (material->initXml(material_xml))
    {
      if (this->getMaterial(material->name))
      {
        ROS_ERROR("material '%s' is not unique.", material->name.c_str());
        material.reset();
        return false;
      }
      else
      {
        this->materials_.insert(make_pair(material->name,material));
        ROS_DEBUG("successfully added a new material '%s'", material->name.c_str());
      }
    }
    else
    {
      ROS_ERROR("material xml is not initialized correctly");
      material.reset();
    }
  }

  // Get all Link elements
  for (TiXmlElement* link_xml = robot_xml->FirstChildElement("link"); link_xml; link_xml = link_xml->NextSiblingElement("link"))
  {
    boost::shared_ptr<Link> link;
    link.reset(new Link);

    if (link->initXml(link_xml))
    {
      if (this->getLink(link->name))
      {
        ROS_ERROR("link '%s' is not unique.", link->name.c_str());
        link.reset();
        return false;
      }
      else
      {
        // set link visual material
        ROS_DEBUG("setting link '%s' material", link->name.c_str());
        if (link->visual)
        {
          if (!link->visual->material_name.empty())
          {
            if (this->getMaterial(link->visual->material_name))
            {
              ROS_DEBUG("setting link '%s' material to '%s'", link->name.c_str(),link->visual->material_name.c_str());
              link->visual->material = this->getMaterial( link->visual->material_name.c_str() );
            }
            else
            {
              if (link->visual->material)
              {
                ROS_DEBUG("link '%s' material '%s' defined in Visual.", link->name.c_str(),link->visual->material_name.c_str());
                this->materials_.insert(make_pair(link->visual->material->name,link->visual->material));
              }
              else
              {
                ROS_ERROR("link '%s' material '%s' undefined.", link->name.c_str(),link->visual->material_name.c_str());
                link.reset();
                return false;
              }
            }
          }
        }

        this->links_.insert(make_pair(link->name,link));
        ROS_DEBUG("successfully added a new link '%s'", link->name.c_str());
      }
    }
    else
    {
      ROS_ERROR("link xml is not initialized correctly");
      link.reset();
    }
  }
  // Get all Joint elements
  for (TiXmlElement* joint_xml = robot_xml->FirstChildElement("joint"); joint_xml; joint_xml = joint_xml->NextSiblingElement("joint"))
  {
    boost::shared_ptr<Joint> joint;
    joint.reset(new Joint);

    if (joint->initXml(joint_xml))
    {
      if (this->getJoint(joint->name))
      {
        ROS_ERROR("joint '%s' is not unique.", joint->name.c_str());
        joint.reset();
        return false;
      }
      else
      {
        this->joints_.insert(make_pair(joint->name,joint));
        ROS_DEBUG("successfully added a new joint '%s'", joint->name.c_str());
      }
    }
    else
    {
      ROS_ERROR("joint xml is not initialized correctly");
      joint.reset();
    }
  }

  // every link has children links and joints, but no parents, so we create a
  // local convenience data structure for keeping child->parent relations
  std::map<std::string, std::string> parent_link_tree;
  parent_link_tree.clear();

  // building tree: name mapping
  if (!this->initTree(parent_link_tree))
  {
    ROS_ERROR("failed to build tree");
    return false;
  }

  // find the root link
  if (!this->initRoot(parent_link_tree))
  {
    ROS_ERROR("failed to find root link");
    return false;
  }

  return true;
}

bool Model::initTree(std::map<std::string, std::string> &parent_link_tree)
{
  // loop through all joints, for every link, assign children links and children joints
  for (std::map<std::string,boost::shared_ptr<Joint> >::iterator joint = this->joints_.begin();joint != this->joints_.end(); joint++)
  {
    std::string parent_link_name = joint->second->parent_link_name;
    std::string child_link_name = joint->second->child_link_name;

    ROS_DEBUG("build tree: joint: '%s' has parent link '%s' and child  link '%s'", joint->first.c_str(), parent_link_name.c_str(),child_link_name.c_str());

    /// add an empty "world" link
    if (parent_link_name == "world")
    {
      if (this->getLink(parent_link_name))
      {
        ROS_DEBUG("    parent link '%s' already exists.", parent_link_name.c_str());
      }
      else
      {
        ROS_DEBUG("    parent link '%s' is a special case, adding fake link.", parent_link_name.c_str());
        boost::shared_ptr<Link> link;
        link.reset(new Link);
        link->name = "world";
        this->links_.insert(make_pair(link->name,link));
        ROS_DEBUG("        successfully added new link '%s'", link->name.c_str());
      }
    }

    if (parent_link_name.empty())
    {
      ROS_DEBUG("    Joint %s: does not have parent link name specified. Joint is an abstract joint.",(joint->second)->name.c_str());
    }
    else if (child_link_name.empty())
    {
      ROS_DEBUG("    Joint %s: does not have child link name specified. Joint is an abstract joint.",(joint->second)->name.c_str());
    }
    else
    {
      // find parent link
      boost::shared_ptr<Link> parent_link;
      this->getLink(parent_link_name, parent_link);

      if (!parent_link)
      {
        ROS_ERROR("    parent link '%s' of joint '%s' not found", parent_link_name.c_str(), joint->first.c_str() );
        return false;
      }
      else
      {
        // find child link
        boost::shared_ptr<Link> child_link;
        this->getLink(child_link_name, child_link);

        if (!child_link)
        {
          ROS_ERROR("    child link '%s' of joint: %s not found",child_link_name.c_str(),joint->first.c_str());
          return false;
        }
        else
        {
          //set parent link for child link
          child_link->setParent(parent_link);

          //set parent joint for child link
          child_link->setParentJoint(joint->second);

          //set child joint for parent link
          parent_link->addChildJoint(joint->second);

          //set child link for parent link
          parent_link->addChild(child_link);

          // fill in child/parent string map
          parent_link_tree[child_link->name] = parent_link_name;

          ROS_DEBUG("    now Link '%s' has %i children ", parent_link->name.c_str(), (int)parent_link->child_links.size());
        }
      }
    }
  }

  return true;
}

bool Model::initRoot(std::map<std::string, std::string> &parent_link_tree)
{

  this->root_link_.reset();

  for (std::map<std::string, std::string>::iterator p=parent_link_tree.begin(); p!=parent_link_tree.end(); p++)
  {
    if (parent_link_tree.find(p->second) == parent_link_tree.end())
    {
      if (this->root_link_)
      {
        ROS_DEBUG("child '%s', parent '%s', root '%s'", p->first.c_str(), p->second.c_str(), this->root_link_->name.c_str());
        if (this->root_link_->name != p->second)
        {
          ROS_ERROR("Two root links found: '%s' and '%s'", this->root_link_->name.c_str(), p->second.c_str());
          return false;
        }
      }
      else
         getLink(p->second,this->root_link_);
    }
  }
  if (!this->root_link_)
  {
    ROS_ERROR("No root link found. The robot xml is empty or not a tree.");
    return false;
  }
  ROS_DEBUG("Link '%s' is the root link", this->root_link_->name.c_str());

  return true;
}

boost::shared_ptr<Material> Model::getMaterial(const std::string& name) const
{
  boost::shared_ptr<Material> ptr;
  if (this->materials_.find(name) == this->materials_.end())
    ptr.reset();
  else
    ptr = this->materials_.find(name)->second;
  return ptr;
}

boost::shared_ptr<const Link> Model::getLink(const std::string& name) const
{
  boost::shared_ptr<const Link> ptr;
  if (this->links_.find(name) == this->links_.end())
    ptr.reset();
  else
    ptr = this->links_.find(name)->second;
  return ptr;
}

void Model::getLinks(std::vector<boost::shared_ptr<Link> >& links) const
{
  for (std::map<std::string,boost::shared_ptr<Link> >::const_iterator link = this->links_.begin();link != this->links_.end(); link++)
  {
    links.push_back(link->second);
  }
}

void Model::getLink(const std::string& name,boost::shared_ptr<Link> &link) const
{
  boost::shared_ptr<Link> ptr;
  if (this->links_.find(name) == this->links_.end())
    ptr.reset();
  else
    ptr = this->links_.find(name)->second;
  link = ptr;
}

boost::shared_ptr<const Joint> Model::getJoint(const std::string& name) const
{
  boost::shared_ptr<const Joint> ptr;
  if (this->joints_.find(name) == this->joints_.end())
    ptr.reset();
  else
    ptr = this->joints_.find(name)->second;
  return ptr;
}

}

<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2021.  All rights reserved
 */
#ifndef _Stroika_Foundation_Traversal_IterableFromIterator_inl_
#define _Stroika_Foundation_Traversal_IterableFromIterator_inl_

#include "../Debug/Assertions.h"
#include "DelegatedIterator.h"

namespace Stroika::Foundation::Traversal {

#if qDebug
    namespace Private_ {
        template <typename T>
        IteratorTracker<T>::~IteratorTracker ()
        {
            Assert (*fCountRunning == 0);
        }
        template <typename T>
        Iterator<T> IteratorTracker<T>::MakeDelegatedIterator (const Iterator<T>& sourceIterator)
        {
            return DelegatedIterator<T, shared_ptr<unsigned int>> (sourceIterator, fCountRunning);
        }
    }
#endif

    /*
     ********************************************************************************
     * IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep *
     ********************************************************************************
     */
    template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
    inline IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::_Rep (const CONTEXT_FOR_EACH_ITERATOR& contextForEachIterator)
        : _fContextForEachIterator (contextForEachIterator)
#if qDebug
        , fIteratorTracker_ ()
#endif
    {
    }
    template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
    Iterator<T> IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::MakeIterator () const
    {
#if qDebug
        return fIteratorTracker_.MakeDelegatedIterator (Iterator<T>{Iterator<T>::template MakeSmartPtr<NEW_ITERATOR_REP_TYPE> (_fContextForEachIterator)});
#else
        return Iterator<T>{Iterator<T>::template MakeSmartPtr<NEW_ITERATOR_REP_TYPE> (_fContextForEachIterator)};
#endif
    }
    template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
    size_t IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::GetLength () const
    {
        size_t n = 0;
        for (auto i = this->MakeIterator (); not i.Done (); ++i) {
            n++;
        }
        return n;
    }
    template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
    bool IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::IsEmpty () const
    {
        for (auto i = this->MakeIterator (); not i.Done (); ++i) {
            return false;
        }
        return true;
    }
    template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
    void IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::Apply (const function<void (ArgByValueType<value_type> item)>& doToElement) const
    {
        this->_Apply (doToElement);
    }
    template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
    Iterator<T> IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::FindFirstThat (const function<bool (ArgByValueType<value_type> item)>& doToElement) const
    {
        return this->_FindFirstThat (doToElement);
    }
#define qNotSureWhyWeNeedExtraTemplateDefsIsItMSFTBugOrMyMisunderstanding 1
#if qNotSureWhyWeNeedExtraTemplateDefsIsItMSFTBugOrMyMisunderstanding
    template <typename T>
    size_t IterableFromIterator<T, void, void>::_Rep::GetLength () const
    {
        size_t n = 0;
        for (auto i = this->MakeIterator (); not i.Done (); ++i) {
            n++;
        }
        return n;
    }
    template <typename T>
    bool IterableFromIterator<T, void, void>::_Rep::IsEmpty () const
    {
        for (auto i = this->MakeIterator (); not i.Done ();) {
            return false;
        }
        return true;
    }
    template <typename T>
    void IterableFromIterator<T, void, void>::_Rep::Apply (const function<void (ArgByValueType<value_type> item)>& doToElement) const
    {
        this->_Apply (doToElement);
    }
    template <typename T>
    Iterator<T> IterableFromIterator<T, void, void>::_Rep::FindFirstThat (const function<bool (ArgByValueType<value_type> item)>& doToElement) const
    {
        return this->_FindFirstThat (doToElement);
    }
#endif

    /*
     ********************************************************************************
     **************************** MakeIterableFromIterator **************************
     ********************************************************************************
     */
    template <typename T>
    Iterable<T> MakeIterableFromIterator (const Iterator<T>& iterator)
    {
        struct MyIterable_ : public Iterable<T> {
            struct Rep : public IterableFromIterator<T>::_Rep, public Memory::UseBlockAllocationIfAppropriate<Rep> {
                using _IterableRepSharedPtr = typename Iterable<T>::_IterableRepSharedPtr;
                Iterator<T> fOriginalIterator;
#if qDebug
                mutable Private_::IteratorTracker<T> fIteratorTracker_{};
#endif
                Rep (const Iterator<T>& originalIterator)
                    : fOriginalIterator{originalIterator}
                {
                }
                virtual Iterator<T> MakeIterator () const override
                {
#if qDebug
                    return fIteratorTracker_.MakeDelegatedIterator (fOriginalIterator);
#else
                    return fOriginalIterator;
#endif
                }
                virtual _IterableRepSharedPtr Clone () const override
                {
                    return Iterable<T>::template MakeSmartPtr<Rep> (*this);
                }
            };
            MyIterable_ (const Iterator<T>& originalIterator)
                : Iterable<T>{Iterable<T>::template MakeSmartPtr<Rep> (originalIterator)}
            {
            }
        };
        return MyIterable_{iterator};
    }

}

#endif /* _Stroika_Foundation_Traversal_IterableFromIterator_inl_ */
<commit_msg>cosmetic<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2021.  All rights reserved
 */
#ifndef _Stroika_Foundation_Traversal_IterableFromIterator_inl_
#define _Stroika_Foundation_Traversal_IterableFromIterator_inl_

#include "../Debug/Assertions.h"
#include "DelegatedIterator.h"

namespace Stroika::Foundation::Traversal {

#if qDebug
    namespace Private_ {
        template <typename T>
        IteratorTracker<T>::~IteratorTracker ()
        {
            Assert (*fCountRunning == 0);
        }
        template <typename T>
        Iterator<T> IteratorTracker<T>::MakeDelegatedIterator (const Iterator<T>& sourceIterator)
        {
            return DelegatedIterator<T, shared_ptr<unsigned int>> (sourceIterator, fCountRunning);
        }
    }
#endif

    /*
     ********************************************************************************
     * IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep *
     ********************************************************************************
     */
    template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
    inline IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::_Rep (const CONTEXT_FOR_EACH_ITERATOR& contextForEachIterator)
        : _fContextForEachIterator {contextForEachIterator}
    {
    }
    template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
    Iterator<T> IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::MakeIterator () const
    {
#if qDebug
        return fIteratorTracker_.MakeDelegatedIterator (Iterator<T>{Iterator<T>::template MakeSmartPtr<NEW_ITERATOR_REP_TYPE> (_fContextForEachIterator)});
#else
        return Iterator<T>{Iterator<T>::template MakeSmartPtr<NEW_ITERATOR_REP_TYPE> (_fContextForEachIterator)};
#endif
    }
    template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
    size_t IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::GetLength () const
    {
        size_t n = 0;
        for (auto i = this->MakeIterator (); not i.Done (); ++i) {
            n++;
        }
        return n;
    }
    template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
    bool IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::IsEmpty () const
    {
        for (auto i = this->MakeIterator (); not i.Done (); ++i) {
            return false;
        }
        return true;
    }
    template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
    void IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::Apply (const function<void (ArgByValueType<value_type> item)>& doToElement) const
    {
        this->_Apply (doToElement);
    }
    template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
    Iterator<T> IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::FindFirstThat (const function<bool (ArgByValueType<value_type> item)>& doToElement) const
    {
        return this->_FindFirstThat (doToElement);
    }
#define qNotSureWhyWeNeedExtraTemplateDefsIsItMSFTBugOrMyMisunderstanding 1
#if qNotSureWhyWeNeedExtraTemplateDefsIsItMSFTBugOrMyMisunderstanding
    template <typename T>
    size_t IterableFromIterator<T, void, void>::_Rep::GetLength () const
    {
        size_t n = 0;
        for (auto i = this->MakeIterator (); not i.Done (); ++i) {
            n++;
        }
        return n;
    }
    template <typename T>
    bool IterableFromIterator<T, void, void>::_Rep::IsEmpty () const
    {
        for (auto i = this->MakeIterator (); not i.Done ();) {
            return false;
        }
        return true;
    }
    template <typename T>
    void IterableFromIterator<T, void, void>::_Rep::Apply (const function<void (ArgByValueType<value_type> item)>& doToElement) const
    {
        this->_Apply (doToElement);
    }
    template <typename T>
    Iterator<T> IterableFromIterator<T, void, void>::_Rep::FindFirstThat (const function<bool (ArgByValueType<value_type> item)>& doToElement) const
    {
        return this->_FindFirstThat (doToElement);
    }
#endif

    /*
     ********************************************************************************
     **************************** MakeIterableFromIterator **************************
     ********************************************************************************
     */
    template <typename T>
    Iterable<T> MakeIterableFromIterator (const Iterator<T>& iterator)
    {
        struct MyIterable_ : public Iterable<T> {
            struct Rep : public IterableFromIterator<T>::_Rep, public Memory::UseBlockAllocationIfAppropriate<Rep> {
                using _IterableRepSharedPtr = typename Iterable<T>::_IterableRepSharedPtr;
                Iterator<T> fOriginalIterator;
#if qDebug
                mutable Private_::IteratorTracker<T> fIteratorTracker_{};
#endif
                Rep (const Iterator<T>& originalIterator)
                    : fOriginalIterator{originalIterator}
                {
                }
                virtual Iterator<T> MakeIterator () const override
                {
#if qDebug
                    return fIteratorTracker_.MakeDelegatedIterator (fOriginalIterator);
#else
                    return fOriginalIterator;
#endif
                }
                virtual _IterableRepSharedPtr Clone () const override
                {
                    return Iterable<T>::template MakeSmartPtr<Rep> (*this);
                }
            };
            MyIterable_ (const Iterator<T>& originalIterator)
                : Iterable<T>{Iterable<T>::template MakeSmartPtr<Rep> (originalIterator)}
            {
            }
        };
        return MyIterable_{iterator};
    }

}

#endif /* _Stroika_Foundation_Traversal_IterableFromIterator_inl_ */
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2018.  All rights reserved
 */
#ifndef _Stroika_Foundation_Traversal_IterableFromIterator_inl_
#define _Stroika_Foundation_Traversal_IterableFromIterator_inl_

#include "../Debug/Assertions.h"
#include "DelegatedIterator.h"

namespace Stroika {
    namespace Foundation {
        namespace Traversal {

#if qDebug
            namespace Private_ {
                template <typename T>
                IteratorTracker<T>::~IteratorTracker ()
                {
                    Assert (*fCountRunning == 0);
                }
                template <typename T>
                Iterator<T> IteratorTracker<T>::MakeDelegatedIterator (const Iterator<T>& sourceIterator)
                {
                    return DelegatedIterator<T, shared_ptr<unsigned int>> (sourceIterator, fCountRunning);
                }
            }
#endif

            /*
             ********************************************************************************
             * IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep *
             ********************************************************************************
             */
            template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
            inline IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::_Rep (const CONTEXT_FOR_EACH_ITERATOR& contextForEachIterator)
                : _fContextForEachIterator (contextForEachIterator)
#if qDebug
                , fIteratorTracker_ ()
#endif
            {
            }
            template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
            Iterator<T> IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::MakeIterator ([[maybe_unused]]IteratorOwnerID suggestedOwner) const
            {
#if qDebug
                return fIteratorTracker_.MakeDelegatedIterator (Iterator<T>{Iterator<T>::template MakeSharedPtr<NEW_ITERATOR_REP_TYPE> (_fContextForEachIterator)});
#else
                return Iterator<T>{Iterator<T>::template MakeSharedPtr<NEW_ITERATOR_REP_TYPE> (_fContextForEachIterator)};
#endif
            }
            template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
            size_t IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::GetLength () const
            {
                size_t n = 0;
                for (auto i = this->MakeIterator (this); not i.Done (); ++i) {
                    n++;
                }
                return n;
            }
            template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
            bool IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::IsEmpty () const
            {
                for (auto i = this->MakeIterator (this); not i.Done (); ++i) {
                    return false;
                }
                return true;
            }
            template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
            void IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::Apply (_APPLY_ARGTYPE doToElement) const
            {
                this->_Apply (doToElement);
            }
            template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
            Iterator<T> IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::FindFirstThat (_APPLYUNTIL_ARGTYPE doToElement, IteratorOwnerID suggestedOwner) const
            {
                return this->_FindFirstThat (doToElement, suggestedOwner);
            }
#define qNotSureWhyWeNeedExtraTemplateDefsIsItMSFTBugOrMyMisunderstanding 1
#if qNotSureWhyWeNeedExtraTemplateDefsIsItMSFTBugOrMyMisunderstanding
            template <typename T>
            size_t IterableFromIterator<T, void, void>::_Rep::GetLength () const
            {
                size_t n = 0;
                for (auto i = this->MakeIterator (this); not i.Done (); ++i) {
                    n++;
                }
                return n;
            }
            template <typename T>
            bool IterableFromIterator<T, void, void>::_Rep::IsEmpty () const
            {
                for (auto i = this->MakeIterator (this); not i.Done ();) {
                    return false;
                }
                return true;
            }
            template <typename T>
            void IterableFromIterator<T, void, void>::_Rep::Apply (_APPLY_ARGTYPE doToElement) const
            {
                this->_Apply (doToElement);
            }
            template <typename T>
            Iterator<T> IterableFromIterator<T, void, void>::_Rep::FindFirstThat (_APPLYUNTIL_ARGTYPE doToElement, IteratorOwnerID suggestedOwner) const
            {
                return this->_FindFirstThat (doToElement, suggestedOwner);
            }
#endif

            /*
             ********************************************************************************
             **************************** MakeIterableFromIterator **************************
             ********************************************************************************
             */
            template <typename T>
            Iterable<T> MakeIterableFromIterator (const Iterator<T>& iterator)
            {
                struct MyIterable_ : public Iterable<T> {
                    struct Rep : public IterableFromIterator<T>::_Rep {
                        using _IterableRepSharedPtr = typename Iterable<T>::_IterableRepSharedPtr;
                        DECLARE_USE_BLOCK_ALLOCATION (Rep);
                        Iterator<T> fOriginalIterator;
#if qDebug
                        mutable Private_::IteratorTracker<T> fIteratorTracker_{};
#endif
                        Rep (const Iterator<T>& originalIterator)
                            : fOriginalIterator (originalIterator)
                        {
                        }
                        virtual Iterator<T> MakeIterator ([[maybe_unused]] IteratorOwnerID suggestedOwner) const override
                        {
#if qDebug
                            return fIteratorTracker_.MakeDelegatedIterator (fOriginalIterator);
#else
                            return fOriginalIterator;
#endif
                        }
                        virtual _IterableRepSharedPtr Clone (IteratorOwnerID forIterableEnvelope) const override
                        {
                            return Iterable<T>::template MakeSharedPtr<Rep> (*this);
                        }
                    };
                    MyIterable_ (const Iterator<T>& originalIterator)
                        : Iterable<T> (Iterable<T>::template MakeSharedPtr<Rep> (originalIterator))
                    {
                    }
                };
                return MyIterable_ (iterator);
            }
        }
    }
}
#endif /* _Stroika_Foundation_Traversal_IterableFromIterator_inl_ */
<commit_msg>Lots of compiler (msvc level 4) warning cleanups: [[maybe_unused]] use<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2018.  All rights reserved
 */
#ifndef _Stroika_Foundation_Traversal_IterableFromIterator_inl_
#define _Stroika_Foundation_Traversal_IterableFromIterator_inl_

#include "../Debug/Assertions.h"
#include "DelegatedIterator.h"

namespace Stroika {
    namespace Foundation {
        namespace Traversal {

#if qDebug
            namespace Private_ {
                template <typename T>
                IteratorTracker<T>::~IteratorTracker ()
                {
                    Assert (*fCountRunning == 0);
                }
                template <typename T>
                Iterator<T> IteratorTracker<T>::MakeDelegatedIterator (const Iterator<T>& sourceIterator)
                {
                    return DelegatedIterator<T, shared_ptr<unsigned int>> (sourceIterator, fCountRunning);
                }
            }
#endif

            /*
             ********************************************************************************
             * IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep *
             ********************************************************************************
             */
            template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
            inline IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::_Rep (const CONTEXT_FOR_EACH_ITERATOR& contextForEachIterator)
                : _fContextForEachIterator (contextForEachIterator)
#if qDebug
                , fIteratorTracker_ ()
#endif
            {
            }
            template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
            Iterator<T> IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::MakeIterator ([[maybe_unused]] IteratorOwnerID suggestedOwner) const
            {
#if qDebug
                return fIteratorTracker_.MakeDelegatedIterator (Iterator<T>{Iterator<T>::template MakeSharedPtr<NEW_ITERATOR_REP_TYPE> (_fContextForEachIterator)});
#else
                return Iterator<T>{Iterator<T>::template MakeSharedPtr<NEW_ITERATOR_REP_TYPE> (_fContextForEachIterator)};
#endif
            }
            template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
            size_t IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::GetLength () const
            {
                size_t n = 0;
                for (auto i = this->MakeIterator (this); not i.Done (); ++i) {
                    n++;
                }
                return n;
            }
            template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
            bool IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::IsEmpty () const
            {
                for (auto i = this->MakeIterator (this); not i.Done (); ++i) {
                    return false;
                }
                return true;
            }
            template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
            void IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::Apply (_APPLY_ARGTYPE doToElement) const
            {
                this->_Apply (doToElement);
            }
            template <typename T, typename NEW_ITERATOR_REP_TYPE, typename CONTEXT_FOR_EACH_ITERATOR>
            Iterator<T> IterableFromIterator<T, NEW_ITERATOR_REP_TYPE, CONTEXT_FOR_EACH_ITERATOR>::_Rep::FindFirstThat (_APPLYUNTIL_ARGTYPE doToElement, IteratorOwnerID suggestedOwner) const
            {
                return this->_FindFirstThat (doToElement, suggestedOwner);
            }
#define qNotSureWhyWeNeedExtraTemplateDefsIsItMSFTBugOrMyMisunderstanding 1
#if qNotSureWhyWeNeedExtraTemplateDefsIsItMSFTBugOrMyMisunderstanding
            template <typename T>
            size_t IterableFromIterator<T, void, void>::_Rep::GetLength () const
            {
                size_t n = 0;
                for (auto i = this->MakeIterator (this); not i.Done (); ++i) {
                    n++;
                }
                return n;
            }
            template <typename T>
            bool IterableFromIterator<T, void, void>::_Rep::IsEmpty () const
            {
                for (auto i = this->MakeIterator (this); not i.Done ();) {
                    return false;
                }
                return true;
            }
            template <typename T>
            void IterableFromIterator<T, void, void>::_Rep::Apply (_APPLY_ARGTYPE doToElement) const
            {
                this->_Apply (doToElement);
            }
            template <typename T>
            Iterator<T> IterableFromIterator<T, void, void>::_Rep::FindFirstThat (_APPLYUNTIL_ARGTYPE doToElement, IteratorOwnerID suggestedOwner) const
            {
                return this->_FindFirstThat (doToElement, suggestedOwner);
            }
#endif

            /*
             ********************************************************************************
             **************************** MakeIterableFromIterator **************************
             ********************************************************************************
             */
            template <typename T>
            Iterable<T> MakeIterableFromIterator (const Iterator<T>& iterator)
            {
                struct MyIterable_ : public Iterable<T> {
                    struct Rep : public IterableFromIterator<T>::_Rep {
                        using _IterableRepSharedPtr = typename Iterable<T>::_IterableRepSharedPtr;
                        DECLARE_USE_BLOCK_ALLOCATION (Rep);
                        Iterator<T> fOriginalIterator;
#if qDebug
                        mutable Private_::IteratorTracker<T> fIteratorTracker_{};
#endif
                        Rep (const Iterator<T>& originalIterator)
                            : fOriginalIterator (originalIterator)
                        {
                        }
                        virtual Iterator<T> MakeIterator ([[maybe_unused]] IteratorOwnerID suggestedOwner) const override
                        {
#if qDebug
                            return fIteratorTracker_.MakeDelegatedIterator (fOriginalIterator);
#else
                            return fOriginalIterator;
#endif
                        }
                        virtual _IterableRepSharedPtr Clone (IteratorOwnerID forIterableEnvelope) const override
                        {
                            return Iterable<T>::template MakeSharedPtr<Rep> (*this);
                        }
                    };
                    MyIterable_ (const Iterator<T>& originalIterator)
                        : Iterable<T> (Iterable<T>::template MakeSharedPtr<Rep> (originalIterator))
                    {
                    }
                };
                return MyIterable_ (iterator);
            }
        }
    }
}
#endif /* _Stroika_Foundation_Traversal_IterableFromIterator_inl_ */
<|endoftext|>


<commit_before><commit_msg>Updated SimpleMaterial::isReadyForSubMesh function to pass material context<commit_after><|endoftext|>


<commit_before>/******************************************************************************
 *  Copyright (c) 2014 Jamis Hoo
 *  Distributed under the MIT license
 *  (See accompanying file LICENSE or copy at http://opensource.org/licenses/MIT)
 *
 *  Project:
 *  Filename: test.cc
 *  Version: 1.0
 *  Author: Jamis Hoo
 *  E-mail: hjm211324@gmail.com
 *  Date: Dec. 29, 2014
 *  Time: 11:10:09
 *  Description:
 *****************************************************************************/
#include <iostream>

int main() {
    std::cout << "Hello world!" << std::endl;

}

<commit_msg>--allow-empty_message<commit_after>/******************************************************************************
 *  Copyright (c) 2014 Jamis Hoo
 *  Distributed under the MIT license
 *  (See accompanying file LICENSE or copy at http://opensource.org/licenses/MIT)
 *
 *  Project:
 *  Filename: test.cc
 *  Version: 1.0
 *  Author: Jamis Hoo
 *  E-mail: hjm211324@gmail.com
 *  Date: Dec. 29, 2014
 *  Time: 11:10:09
 *  Description:
 *****************************************************************************/
#include <iostream>

int main() {
    std::cout << "Hello world!" << std::endl;

}

<|endoftext|>


<commit_before>#include "php.h"
#include "php_gdal.h"
#include <ogr_core.h>
#include <cpl_conv.h>
#include <cpl_string.h>
#include "ogrexception.h"
#include "ogrspatialreference.h"
#include "ogrgeometry.h"

zend_class_entry *gdal_ogrgeometry_ce;
zend_object_handlers ogrgeometry_object_handlers;

void ogrgeometry_free_storage(void *object TSRMLS_DC)
{
  php_ogrgeometry_object *obj = (php_ogrgeometry_object *)object;
  //delete obj->geometry; // TODO
  zend_hash_destroy(obj->std.properties);
  FREE_HASHTABLE(obj->std.properties);
  efree(obj);
}

zend_object_value ogrgeometry_create_handler(zend_class_entry *type TSRMLS_DC)
{
  zval *tmp;
  zend_object_value retval;

  php_ogrgeometry_object *obj =
    (php_ogrgeometry_object *)emalloc(sizeof(php_ogrgeometry_object));
  memset(obj, 0, sizeof(php_ogrgeometry_object));
  obj->std.ce = type;

  ALLOC_HASHTABLE(obj->std.properties);
  zend_hash_init(obj->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
#if PHP_VERSION_ID < 50399
  zend_hash_copy(obj->std.properties, &type->default_properties,
                 (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));
#else
  object_properties_init(&obj->std, type);
#endif

  retval.handle = zend_objects_store_put(obj, NULL,
                                         ogrgeometry_free_storage, NULL TSRMLS_CC);
  retval.handlers = &ogrgeometry_object_handlers;

  return retval;
}

PHP_METHOD(OGRGeometry, IsValid)
{
  OGRGeometry *geometry;
  php_ogrgeometry_object *obj;

  if (ZEND_NUM_ARGS() != 0) {
    return;
  }

  obj = (php_ogrgeometry_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
  geometry = obj->geometry;
  RETURN_BOOL(geometry->IsValid());
}

PHP_METHOD(OGRGeometry, ExportToWkt)
{
  OGRGeometry *geometry;
  php_ogrgeometry_object *obj;
  char *ppszDstText;
  char *ret;

  if (ZEND_NUM_ARGS() != 0) {
    return;
  }

  obj = (php_ogrgeometry_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
  geometry = obj->geometry;

  if (geometry->exportToWkt(&ppszDstText) != OGRERR_NONE) {
    php_gdal_ogr_throw("Failed to convert geometry to WKT");
    RETURN_EMPTY_STRING();
  }

  ret = estrdup(ppszDstText);
  OGRFree(ppszDstText);
  RETURN_STRING(ret, 0);
}

PHP_METHOD(OGRGeometry, ExportToWkb)
{
  OGRGeometry *geometry;
  php_ogrgeometry_object *obj;
  int wkbSize;
  char * buffer;
  int wkbByteOrder = wkbNDR; // use as default when no byteOrder is specified

  if (ZEND_NUM_ARGS() != 0) {
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, (char*)"l",
          &wkbByteOrder) == FAILURE) {
      php_gdal_ogr_throw("Illegal value for byteOrder");
      RETURN_EMPTY_STRING();
    }
  }

  if ((wkbByteOrder) != wkbNDR && (wkbByteOrder != wkbXDR)) {
      php_gdal_ogr_throw("Illegal value for byteOrder. Has to be either wkbNDR or wkbXDR");
      RETURN_EMPTY_STRING();
  }

  obj = (php_ogrgeometry_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
  geometry = obj->geometry;

  wkbSize = geometry->WkbSize();
  buffer = (char*)ecalloc(sizeof(char), wkbSize+1);

  if (geometry->exportToWkb(wkbNDR, (unsigned char*)buffer) != OGRERR_NONE) {
    php_gdal_ogr_throw("Failed to convert geometry to WKB");
    RETURN_EMPTY_STRING();
  }

  RETURN_STRINGL(buffer, wkbSize+1, 0);
}

PHP_METHOD(OGRGeometry, ExportToJson)
{
  OGRGeometry *geometry;
  php_ogrgeometry_object *obj;
  char *jsonText;
  char *ret;

  if (ZEND_NUM_ARGS() != 0) {
    return;
  }

  obj = (php_ogrgeometry_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
  geometry = obj->geometry;

  jsonText = geometry->exportToJson();
  if (jsonText == NULL) {
    php_gdal_ogr_throw("Failed to convert geometry to JSON");
    RETURN_EMPTY_STRING();
  }

  ret = estrdup(jsonText);
  CPLFree(jsonText);
  RETURN_STRING(ret, 0);
}

PHP_METHOD(OGRGeometry, ExportToKML)
{
  OGRGeometry *geometry;
  php_ogrgeometry_object *obj;
  char *kmlText;
  char *ret;

  if (ZEND_NUM_ARGS() != 0) {
    return;
  }

  obj = (php_ogrgeometry_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
  geometry = obj->geometry;

  kmlText = geometry->exportToKML();
  if (kmlText == NULL) {
    php_gdal_ogr_throw("Failed to convert geometry to KML");
    RETURN_EMPTY_STRING();
  }

  ret = estrdup(kmlText);
  CPLFree(kmlText);
  RETURN_STRING(ret, 0);
}

PHP_METHOD(OGRGeometry, ExportToGML)
{
  OGRGeometry *geometry;
  php_ogrgeometry_object *obj;
  char *gmlText;
  char *ret;
  char *gmlOptions = NULL;
  int gmlOptionsLen;
  char **papszOptions = NULL;

  if (ZEND_NUM_ARGS() != 0) {
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, (char*)"s", &gmlOptions, &gmlOptionsLen) == FAILURE) {
      php_gdal_ogr_throw("Illegal value for GML format options");
      RETURN_EMPTY_STRING();
    }
  }

  obj = (php_ogrgeometry_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
  geometry = obj->geometry;

#if ! ((GDAL_VERSION_MAJOR <= 1) && (GDAL_VERSION_MINOR < 8))
  if (gmlOptionsLen != 0) {
    papszOptions = CSLAddString(papszOptions, gmlOptions);
  }

  gmlText = geometry->exportToGML(papszOptions);
#else
  gmlText = geometry->exportToGML();
#endif

#if ! ((GDAL_VERSION_MAJOR <= 1) && (GDAL_VERSION_MINOR < 8))
  if (papszOptions) {
    CSLDestroy(papszOptions);
  }
#endif

  if (gmlText == NULL) {
    php_gdal_ogr_throw("Failed to convert geometry to GML");
    RETURN_EMPTY_STRING();
  }

  ret = estrdup(gmlText);
  CPLFree(gmlText);
  RETURN_STRING(ret, 0);
}

PHP_METHOD(OGRGeometry, GetGeometryName)
{
  OGRGeometry *geometry;
  php_ogrgeometry_object *obj;
  char *ret;
  const char *geomName;

  if (ZEND_NUM_ARGS() != 0) {
    return;
  }

  obj = (php_ogrgeometry_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
  geometry = obj->geometry;

  geomName = geometry->getGeometryName();
  ret = estrdup(geomName);
  RETURN_STRING(ret, 0);
}

PHP_METHOD(OGRGeometry, GetGeometryType)
{
  OGRGeometry *geometry;
  php_ogrgeometry_object *obj;

  if (ZEND_NUM_ARGS() != 0) {
    return;
  }

  obj = (php_ogrgeometry_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
  geometry = obj->geometry;
  RETURN_LONG(geometry->getGeometryType());
}

PHP_METHOD(OGRGeometry, IsEmpty)
{
  OGRGeometry *geometry;
  php_ogrgeometry_object *obj;

  if (ZEND_NUM_ARGS() != 0) {
    return;
  }

  obj = (php_ogrgeometry_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
  geometry = obj->geometry;
  RETURN_BOOL(geometry->IsEmpty());
}

PHP_METHOD(OGRGeometry, GetSpatialReference)
{
  OGRGeometry *geometry;
  php_ogrgeometry_object *obj;
  OGRSpatialReference *spatialreference;
  php_ogrspatialreference_object *spatialreference_obj;

  if (ZEND_NUM_ARGS() != 0) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrgeometry_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
  geometry = obj->geometry;

  spatialreference = geometry->getSpatialReference();
  if (!spatialreference) {
    RETURN_NULL();
  }
  if (object_init_ex(return_value, gdal_ogrspatialreference_ce) != SUCCESS) {
    RETURN_NULL();
  }
  spatialreference_obj = (php_ogrspatialreference_object*) zend_objects_get_address(return_value TSRMLS_CC);
  spatialreference_obj->spatialreference = spatialreference;
}

zend_function_entry ogrgeometry_methods[] = {
  PHP_ME(OGRGeometry, IsValid, NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRGeometry, ExportToWkt, NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRGeometry, ExportToWkb, NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRGeometry, ExportToJson, NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRGeometry, ExportToKML, NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRGeometry, ExportToGML, NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRGeometry, GetGeometryName, NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRGeometry, GetGeometryType, NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRGeometry, IsEmpty, NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRGeometry, GetSpatialReference, NULL, ZEND_ACC_PUBLIC)
  {NULL, NULL, NULL}
};

void php_gdal_ogrgeometry_startup(INIT_FUNC_ARGS)
{
  zend_class_entry ce;
  INIT_CLASS_ENTRY(ce, "OGRGeometry", ogrgeometry_methods);
  gdal_ogrgeometry_ce = zend_register_internal_class(&ce TSRMLS_CC);
  gdal_ogrgeometry_ce->create_object = ogrgeometry_create_handler;
  memcpy(&ogrgeometry_object_handlers,
         zend_get_std_object_handlers(), sizeof(zend_object_handlers));
  ogrgeometry_object_handlers.clone_obj = NULL;
}

/* VIM settings */
/* ex: set tabstop=2 expandtab shiftwidth=2 smartindent */
<commit_msg>comment on pointer ownership for geometry pointer<commit_after>#include "php.h"
#include "php_gdal.h"
#include <ogr_core.h>
#include <cpl_conv.h>
#include <cpl_string.h>
#include "ogrexception.h"
#include "ogrspatialreference.h"
#include "ogrgeometry.h"

zend_class_entry *gdal_ogrgeometry_ce;
zend_object_handlers ogrgeometry_object_handlers;

void ogrgeometry_free_storage(void *object TSRMLS_DC)
{
  php_ogrgeometry_object *obj = (php_ogrgeometry_object *)object;
  delete obj->geometry; // currently all pointers here are only references which
                        // should not be modified
  zend_hash_destroy(obj->std.properties);
  FREE_HASHTABLE(obj->std.properties);
  efree(obj);
}

zend_object_value ogrgeometry_create_handler(zend_class_entry *type TSRMLS_DC)
{
  zval *tmp;
  zend_object_value retval;

  php_ogrgeometry_object *obj =
    (php_ogrgeometry_object *)emalloc(sizeof(php_ogrgeometry_object));
  memset(obj, 0, sizeof(php_ogrgeometry_object));
  obj->std.ce = type;

  ALLOC_HASHTABLE(obj->std.properties);
  zend_hash_init(obj->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
#if PHP_VERSION_ID < 50399
  zend_hash_copy(obj->std.properties, &type->default_properties,
                 (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));
#else
  object_properties_init(&obj->std, type);
#endif

  retval.handle = zend_objects_store_put(obj, NULL,
                                         ogrgeometry_free_storage, NULL TSRMLS_CC);
  retval.handlers = &ogrgeometry_object_handlers;

  return retval;
}

PHP_METHOD(OGRGeometry, IsValid)
{
  OGRGeometry *geometry;
  php_ogrgeometry_object *obj;

  if (ZEND_NUM_ARGS() != 0) {
    return;
  }

  obj = (php_ogrgeometry_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
  geometry = obj->geometry;
  RETURN_BOOL(geometry->IsValid());
}

PHP_METHOD(OGRGeometry, ExportToWkt)
{
  OGRGeometry *geometry;
  php_ogrgeometry_object *obj;
  char *ppszDstText;
  char *ret;

  if (ZEND_NUM_ARGS() != 0) {
    return;
  }

  obj = (php_ogrgeometry_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
  geometry = obj->geometry;

  if (geometry->exportToWkt(&ppszDstText) != OGRERR_NONE) {
    php_gdal_ogr_throw("Failed to convert geometry to WKT");
    RETURN_EMPTY_STRING();
  }

  ret = estrdup(ppszDstText);
  OGRFree(ppszDstText);
  RETURN_STRING(ret, 0);
}

PHP_METHOD(OGRGeometry, ExportToWkb)
{
  OGRGeometry *geometry;
  php_ogrgeometry_object *obj;
  int wkbSize;
  char * buffer;
  int wkbByteOrder = wkbNDR; // use as default when no byteOrder is specified

  if (ZEND_NUM_ARGS() != 0) {
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, (char*)"l",
          &wkbByteOrder) == FAILURE) {
      php_gdal_ogr_throw("Illegal value for byteOrder");
      RETURN_EMPTY_STRING();
    }
  }

  if ((wkbByteOrder) != wkbNDR && (wkbByteOrder != wkbXDR)) {
      php_gdal_ogr_throw("Illegal value for byteOrder. Has to be either wkbNDR or wkbXDR");
      RETURN_EMPTY_STRING();
  }

  obj = (php_ogrgeometry_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
  geometry = obj->geometry;

  wkbSize = geometry->WkbSize();
  buffer = (char*)ecalloc(sizeof(char), wkbSize+1);

  if (geometry->exportToWkb(wkbNDR, (unsigned char*)buffer) != OGRERR_NONE) {
    php_gdal_ogr_throw("Failed to convert geometry to WKB");
    RETURN_EMPTY_STRING();
  }

  RETURN_STRINGL(buffer, wkbSize+1, 0);
}

PHP_METHOD(OGRGeometry, ExportToJson)
{
  OGRGeometry *geometry;
  php_ogrgeometry_object *obj;
  char *jsonText;
  char *ret;

  if (ZEND_NUM_ARGS() != 0) {
    return;
  }

  obj = (php_ogrgeometry_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
  geometry = obj->geometry;

  jsonText = geometry->exportToJson();
  if (jsonText == NULL) {
    php_gdal_ogr_throw("Failed to convert geometry to JSON");
    RETURN_EMPTY_STRING();
  }

  ret = estrdup(jsonText);
  CPLFree(jsonText);
  RETURN_STRING(ret, 0);
}

PHP_METHOD(OGRGeometry, ExportToKML)
{
  OGRGeometry *geometry;
  php_ogrgeometry_object *obj;
  char *kmlText;
  char *ret;

  if (ZEND_NUM_ARGS() != 0) {
    return;
  }

  obj = (php_ogrgeometry_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
  geometry = obj->geometry;

  kmlText = geometry->exportToKML();
  if (kmlText == NULL) {
    php_gdal_ogr_throw("Failed to convert geometry to KML");
    RETURN_EMPTY_STRING();
  }

  ret = estrdup(kmlText);
  CPLFree(kmlText);
  RETURN_STRING(ret, 0);
}

PHP_METHOD(OGRGeometry, ExportToGML)
{
  OGRGeometry *geometry;
  php_ogrgeometry_object *obj;
  char *gmlText;
  char *ret;
  char *gmlOptions = NULL;
  int gmlOptionsLen;
  char **papszOptions = NULL;

  if (ZEND_NUM_ARGS() != 0) {
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, (char*)"s", &gmlOptions, &gmlOptionsLen) == FAILURE) {
      php_gdal_ogr_throw("Illegal value for GML format options");
      RETURN_EMPTY_STRING();
    }
  }

  obj = (php_ogrgeometry_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
  geometry = obj->geometry;

#if ! ((GDAL_VERSION_MAJOR <= 1) && (GDAL_VERSION_MINOR < 8))
  if (gmlOptionsLen != 0) {
    papszOptions = CSLAddString(papszOptions, gmlOptions);
  }

  gmlText = geometry->exportToGML(papszOptions);
#else
  gmlText = geometry->exportToGML();
#endif

#if ! ((GDAL_VERSION_MAJOR <= 1) && (GDAL_VERSION_MINOR < 8))
  if (papszOptions) {
    CSLDestroy(papszOptions);
  }
#endif

  if (gmlText == NULL) {
    php_gdal_ogr_throw("Failed to convert geometry to GML");
    RETURN_EMPTY_STRING();
  }

  ret = estrdup(gmlText);
  CPLFree(gmlText);
  RETURN_STRING(ret, 0);
}

PHP_METHOD(OGRGeometry, GetGeometryName)
{
  OGRGeometry *geometry;
  php_ogrgeometry_object *obj;
  char *ret;
  const char *geomName;

  if (ZEND_NUM_ARGS() != 0) {
    return;
  }

  obj = (php_ogrgeometry_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
  geometry = obj->geometry;

  geomName = geometry->getGeometryName();
  ret = estrdup(geomName);
  RETURN_STRING(ret, 0);
}

PHP_METHOD(OGRGeometry, GetGeometryType)
{
  OGRGeometry *geometry;
  php_ogrgeometry_object *obj;

  if (ZEND_NUM_ARGS() != 0) {
    return;
  }

  obj = (php_ogrgeometry_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
  geometry = obj->geometry;
  RETURN_LONG(geometry->getGeometryType());
}

PHP_METHOD(OGRGeometry, IsEmpty)
{
  OGRGeometry *geometry;
  php_ogrgeometry_object *obj;

  if (ZEND_NUM_ARGS() != 0) {
    return;
  }

  obj = (php_ogrgeometry_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
  geometry = obj->geometry;
  RETURN_BOOL(geometry->IsEmpty());
}

PHP_METHOD(OGRGeometry, GetSpatialReference)
{
  OGRGeometry *geometry;
  php_ogrgeometry_object *obj;
  OGRSpatialReference *spatialreference;
  php_ogrspatialreference_object *spatialreference_obj;

  if (ZEND_NUM_ARGS() != 0) {
    WRONG_PARAM_COUNT;
  }

  obj = (php_ogrgeometry_object *) zend_object_store_get_object(getThis() TSRMLS_CC);
  geometry = obj->geometry;

  spatialreference = geometry->getSpatialReference();
  if (!spatialreference) {
    RETURN_NULL();
  }
  if (object_init_ex(return_value, gdal_ogrspatialreference_ce) != SUCCESS) {
    RETURN_NULL();
  }
  spatialreference_obj = (php_ogrspatialreference_object*) zend_objects_get_address(return_value TSRMLS_CC);
  spatialreference_obj->spatialreference = spatialreference;
}

zend_function_entry ogrgeometry_methods[] = {
  PHP_ME(OGRGeometry, IsValid, NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRGeometry, ExportToWkt, NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRGeometry, ExportToWkb, NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRGeometry, ExportToJson, NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRGeometry, ExportToKML, NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRGeometry, ExportToGML, NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRGeometry, GetGeometryName, NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRGeometry, GetGeometryType, NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRGeometry, IsEmpty, NULL, ZEND_ACC_PUBLIC)
  PHP_ME(OGRGeometry, GetSpatialReference, NULL, ZEND_ACC_PUBLIC)
  {NULL, NULL, NULL}
};

void php_gdal_ogrgeometry_startup(INIT_FUNC_ARGS)
{
  zend_class_entry ce;
  INIT_CLASS_ENTRY(ce, "OGRGeometry", ogrgeometry_methods);
  gdal_ogrgeometry_ce = zend_register_internal_class(&ce TSRMLS_CC);
  gdal_ogrgeometry_ce->create_object = ogrgeometry_create_handler;
  memcpy(&ogrgeometry_object_handlers,
         zend_get_std_object_handlers(), sizeof(zend_object_handlers));
  ogrgeometry_object_handlers.clone_obj = NULL;
}

/* VIM settings */
/* ex: set tabstop=2 expandtab shiftwidth=2 smartindent */
<|endoftext|>


<commit_before>/**
 * Clever programming language
 * Copyright (c) Clever Team
 *
 * This file is distributed under the MIT license. See LICENSE for details.
 */
#include "types/type.h"
#include "modules/std/unicode/string.h"
#include "unicode/unistr.h"
#include "core/value.h"

namespace clever { namespace packages { namespace std {

#define CLEVER_USTR_TYPE icu::UnicodeString*
#define CLEVER_USTR_THIS() (CLEVER_USTR_TYPE) CLEVER_THIS()->getObj()

void* UnicodeString::allocData(CLEVER_TYPE_CTOR_ARGS) const {
	if (args->size()) {
		Value* from = args->at(0);
		if (from) {
			const CString* str = from->getStr();
			if (str) {
				return new icu::UnicodeString(
					str->c_str(), str->size(), US_INV
				);
			}
		}
	}
	return NULL;
}

void UnicodeString::deallocData(void *data) {
	delete (icu::UnicodeString*) data;
}

CLEVER_METHOD(UnicodeString::dbg) {
	if (CLEVER_THIS()) {
		CLEVER_USTR_TYPE intern = CLEVER_USTR_THIS();
		if (intern) {
			printf("Fetched UnicodeString from Object\n");
		}
	}
}

CLEVER_TYPE_OPERATOR(UnicodeString::add) {}
CLEVER_TYPE_OPERATOR(UnicodeString::sub) {}
CLEVER_TYPE_OPERATOR(UnicodeString::mul) {}
CLEVER_TYPE_OPERATOR(UnicodeString::div) {}
CLEVER_TYPE_OPERATOR(UnicodeString::mod) {}
CLEVER_TYPE_OPERATOR(UnicodeString::greater) {}
CLEVER_TYPE_OPERATOR(UnicodeString::greater_equal) {}
CLEVER_TYPE_OPERATOR(UnicodeString::less) {}
CLEVER_TYPE_OPERATOR(UnicodeString::less_equal) {}
CLEVER_TYPE_OPERATOR(UnicodeString::equal) {}
CLEVER_TYPE_OPERATOR(UnicodeString::not_equal) {}

CLEVER_TYPE_INIT(UnicodeString::init)
{
	addMethod(CSTRING("dbg"),		(MethodPtr) &UnicodeString::dbg);
}

}}} // clever::packages::std
<commit_msg>macros everywhere<commit_after>/**
 * Clever programming language
 * Copyright (c) Clever Team
 *
 * This file is distributed under the MIT license. See LICENSE for details.
 */
#include "types/type.h"
#include "modules/std/unicode/string.h"
#include "unicode/unistr.h"
#include "core/value.h"

namespace clever { namespace packages { namespace std {

#define CLEVER_USTR_TYPE icu::UnicodeString*
#define CLEVER_USTR_CAST (CLEVER_USTR_TYPE)
#define CLEVER_USTR_THIS() CLEVER_USTR_CAST CLEVER_THIS()->getObj()

void* UnicodeString::allocData(CLEVER_TYPE_CTOR_ARGS) const {
	if (args->size()) {
		Value* from = args->at(0);
		if (from) {
			const CString* str = from->getStr();
			if (str) {
				return new icu::UnicodeString(
					str->c_str(), str->size(), US_INV
				);
			}
		}
	}
	return NULL;
}

void UnicodeString::deallocData(void *data) {
	delete CLEVER_USTR_CAST data;
}

CLEVER_METHOD(UnicodeString::dbg) {
	if (CLEVER_THIS()) {
		CLEVER_USTR_TYPE intern = CLEVER_USTR_THIS();
		if (intern) {
			printf("Fetched UnicodeString from Object\n");
		}
	}
}

CLEVER_TYPE_OPERATOR(UnicodeString::add) {}
CLEVER_TYPE_OPERATOR(UnicodeString::sub) {}
CLEVER_TYPE_OPERATOR(UnicodeString::mul) {}
CLEVER_TYPE_OPERATOR(UnicodeString::div) {}
CLEVER_TYPE_OPERATOR(UnicodeString::mod) {}
CLEVER_TYPE_OPERATOR(UnicodeString::greater) {}
CLEVER_TYPE_OPERATOR(UnicodeString::greater_equal) {}
CLEVER_TYPE_OPERATOR(UnicodeString::less) {}
CLEVER_TYPE_OPERATOR(UnicodeString::less_equal) {}
CLEVER_TYPE_OPERATOR(UnicodeString::equal) {}
CLEVER_TYPE_OPERATOR(UnicodeString::not_equal) {}

CLEVER_TYPE_INIT(UnicodeString::init)
{
	addMethod(CSTRING("dbg"),		(MethodPtr) &UnicodeString::dbg);
}

}}} // clever::packages::std
<|endoftext|>


<commit_before>#include <foot_contact_alt/FootContactAlt.h>

using namespace TwoLegs;
using namespace std;

FootContactAlt::FootContactAlt(bool _log_data_files,const float atlasWeight){
  cout << "A new FootContactAlt object was created" << endl;

  // was 1400*0.65 for a long time, but this didn't work with toe lift off stepping
  schmitt_level_ = 0.65;
  transition_timeout_ = 4000;
  ////////////////////////////////////////////

  standing_foot = F_UNKNOWN;

  lcmutime = 0;
  deltautime = 0;

  expectedweight = atlasWeight;

  foottransitionintermediateflag = true;

  l_foot_force_z = 0.f;
  r_foot_force_z = 0.f;

  transition_timespan = 0;

  // actual noticable toe push off occurs with about 50:50 ratio: 760:760 or even later
  // To reduce tic-tocing you can reduce the first number
  // originally 275/375 was ok, but some upward drift (3/4 of a block height) and backward drift (1/3 of a block length)
  // later 475/525 was better, upward drift (1/2 of block) and backward drift (about the same)
  left_contact_state_strong_  = new SchmittTrigger(525.0, 575.0, 7000, 7000);
  right_contact_state_strong_ = new SchmittTrigger(525.0, 575.0, 7000, 7000);

  left_contact_state_strong_->forceHigh();
  right_contact_state_strong_->forceHigh();

  verbose_ =1; // 3 lots, 2 some, 1 v.important
}

contact_status_id FootContactAlt::DetectFootTransition(int64_t utime, float leftz, float rightz) {
  bool lf_state_last = (bool) left_contact_state_strong_->getState();
  bool rf_state_last = (bool) right_contact_state_strong_->getState();

  left_contact_state_strong_->UpdateState(utime, leftz);
  right_contact_state_strong_->UpdateState(utime, rightz);

  bool lf_state = (bool) left_contact_state_strong_->getState();
  bool rf_state = (bool) right_contact_state_strong_->getState();

  std::stringstream ss;
  ss << (int)standing_foot << " | " << lf_state << " " << rf_state << " ";

  if (!lf_state_last && lf_state){
    if (verbose_ >= 1) std::cout << ss.str() << "Left has gone high\n";
    standing_foot = F_LEFT;
    return F_LEFT_NEW;
  }else if(!rf_state_last && rf_state){
    if (verbose_ >= 1) std::cout << ss.str() << "Right has gone high\n";
    standing_foot = F_RIGHT;
    return F_RIGHT_NEW;
  }else if(lf_state_last && !lf_state){
    if (verbose_ >= 3) std::cout << ss.str() << "Left has gone low\n";
    if (standing_foot==F_LEFT){
      if (verbose_ >= 1) std::cout << ss.str() << "Left has gone low when used as standing, force switch to right "<< leftz << " | "<<  rightz <<"\n";
      standing_foot = F_RIGHT;
      return F_RIGHT_NEW;
    }else{
      if (verbose_ >= 3) std::cout << ss.str() << "Left has gone low when used not used as standing. Continue with right\n";
      return F_RIGHT_FIXED;
    }
  }else if(rf_state_last && !rf_state){
    if (verbose_ >= 3) std::cout << ss.str() << "Right has gone low\n";
    if (standing_foot==F_RIGHT){
      if (verbose_ >= 1) std::cout << ss.str() << "Right has gone low when used as standing, force switch to left "<< leftz << " | "<<  rightz <<"\n";
      standing_foot = F_LEFT;
      return F_LEFT_NEW;
    }else{
      if (verbose_ >= 3) std::cout << ss.str() << "Right has gone low when used not used as standing. Continue with left\n";
      return F_LEFT_FIXED;
    }
  }else{
    if (standing_foot==F_LEFT){
      if (verbose_ >= 3) std::cout << ss.str() << "Left No change\n";
      return F_LEFT_FIXED;
    }else if (standing_foot==F_RIGHT){
      if (verbose_ >= 3) std::cout << ss.str() << "Right No change\n";
      return F_RIGHT_FIXED;
    }
  }

  std::cout << ss.str() << "Situation unknown. Error\n";
  exit(-1);
  return F_STATUS_UNKNOWN;
}

void FootContactAlt::setStandingFoot(footid_alt foot) {
  standing_foot = foot;
}

footid_alt FootContactAlt::getStandingFoot() {
  return standing_foot;
}

footid_alt FootContactAlt::getSecondaryFoot() {
  if (standing_foot == F_LEFT)
    return F_RIGHT;
  if (standing_foot == F_RIGHT)
    return F_LEFT;
  std::cout << "FootContactAlt::secondary_foot(): THIS SHOULD NOT HAPPEN THE FOOT NUMBERS ARE INCONSISTENT\n";
  return F_UNKNOWN;
}

float FootContactAlt::getPrimaryFootZforce() {
  if (standing_foot == F_LEFT)
    return l_foot_force_z;
  return r_foot_force_z;
}

float FootContactAlt::getSecondaryFootZforce() {
  if (standing_foot == F_LEFT)
    return r_foot_force_z;
  return l_foot_force_z;
}

<commit_msg>fix for bdi toe off<commit_after>#include <foot_contact_alt/FootContactAlt.h>

using namespace TwoLegs;
using namespace std;

FootContactAlt::FootContactAlt(bool _log_data_files,const float atlasWeight){
  cout << "A new FootContactAlt object was created" << endl;

  // was 1400*0.65 for a long time, but this didn't work with toe lift off stepping
  schmitt_level_ = 0.65;
  transition_timeout_ = 4000;
  ////////////////////////////////////////////

  standing_foot = F_UNKNOWN;

  lcmutime = 0;
  deltautime = 0;

  expectedweight = atlasWeight;

  foottransitionintermediateflag = true;

  l_foot_force_z = 0.f;
  r_foot_force_z = 0.f;

  transition_timespan = 0;

  // actual noticable toe push off occurs with about 50:50 ratio: 760:760 or even later
  // To reduce tic-tocing you can reduce the first number
  // originally 275/375 was ok, but some upward drift (3/4 of a block height) and backward drift (1/3 of a block length)
  // later 475/525 was better, upward drift (1/2 of block) and backward drift (about the same)
  // From April 2014 to Sept 2014 I used 525.0, 575.0, 7000, 7000
  //left_contact_state_strong_  = new SchmittTrigger(525.0, 575.0, 7000, 7000);
  //right_contact_state_strong_ = new SchmittTrigger(525.0, 575.0, 7000, 7000);

  left_contact_state_strong_  = new SchmittTrigger(475.0, 525.0, 7000, 7000);
  right_contact_state_strong_ = new SchmittTrigger(475.0, 525.0, 7000, 7000);

  left_contact_state_strong_->forceHigh();
  right_contact_state_strong_->forceHigh();

  verbose_ =1; // 3 lots, 2 some, 1 v.important
}

contact_status_id FootContactAlt::DetectFootTransition(int64_t utime, float leftz, float rightz) {
  bool lf_state_last = (bool) left_contact_state_strong_->getState();
  bool rf_state_last = (bool) right_contact_state_strong_->getState();

  left_contact_state_strong_->UpdateState(utime, leftz);
  right_contact_state_strong_->UpdateState(utime, rightz);

  bool lf_state = (bool) left_contact_state_strong_->getState();
  bool rf_state = (bool) right_contact_state_strong_->getState();

  std::stringstream ss;
  ss << (int)standing_foot << " | " << lf_state << " " << rf_state << " ";

  if (!lf_state_last && lf_state){
    if (verbose_ >= 1) std::cout << ss.str() << "Left has gone high\n";
    standing_foot = F_LEFT;
    return F_LEFT_NEW;
  }else if(!rf_state_last && rf_state){
    if (verbose_ >= 1) std::cout << ss.str() << "Right has gone high\n";
    standing_foot = F_RIGHT;
    return F_RIGHT_NEW;
  }else if(lf_state_last && !lf_state){
    if (verbose_ >= 3) std::cout << ss.str() << "Left has gone low\n";
    if (standing_foot==F_LEFT){
      if (verbose_ >= 1) std::cout << ss.str() << "Left has gone low when used as standing, force switch to right "<< leftz << " | "<<  rightz <<"\n";
      standing_foot = F_RIGHT;
      return F_RIGHT_NEW;
    }else{
      if (verbose_ >= 3) std::cout << ss.str() << "Left has gone low when used not used as standing. Continue with right\n";
      return F_RIGHT_FIXED;
    }
  }else if(rf_state_last && !rf_state){
    if (verbose_ >= 3) std::cout << ss.str() << "Right has gone low\n";
    if (standing_foot==F_RIGHT){
      if (verbose_ >= 1) std::cout << ss.str() << "Right has gone low when used as standing, force switch to left "<< leftz << " | "<<  rightz <<"\n";
      standing_foot = F_LEFT;
      return F_LEFT_NEW;
    }else{
      if (verbose_ >= 3) std::cout << ss.str() << "Right has gone low when used not used as standing. Continue with left\n";
      return F_LEFT_FIXED;
    }
  }else{
    if (standing_foot==F_LEFT){
      if (verbose_ >= 3) std::cout << ss.str() << "Left No change\n";
      return F_LEFT_FIXED;
    }else if (standing_foot==F_RIGHT){
      if (verbose_ >= 3) std::cout << ss.str() << "Right No change\n";
      return F_RIGHT_FIXED;
    }
  }

  std::cout << ss.str() << "Situation unknown. Error\n";
  exit(-1);
  return F_STATUS_UNKNOWN;
}

void FootContactAlt::setStandingFoot(footid_alt foot) {
  standing_foot = foot;
}

footid_alt FootContactAlt::getStandingFoot() {
  return standing_foot;
}

footid_alt FootContactAlt::getSecondaryFoot() {
  if (standing_foot == F_LEFT)
    return F_RIGHT;
  if (standing_foot == F_RIGHT)
    return F_LEFT;
  std::cout << "FootContactAlt::secondary_foot(): THIS SHOULD NOT HAPPEN THE FOOT NUMBERS ARE INCONSISTENT\n";
  return F_UNKNOWN;
}

float FootContactAlt::getPrimaryFootZforce() {
  if (standing_foot == F_LEFT)
    return l_foot_force_z;
  return r_foot_force_z;
}

float FootContactAlt::getSecondaryFootZforce() {
  if (standing_foot == F_LEFT)
    return r_foot_force_z;
  return l_foot_force_z;
}

<|endoftext|>


<commit_before>#include "../../SDP_Solver_Terminate_Reason.hxx"
#include "../../../SDP_Solver_Parameters.hxx"

void compute_feasible_and_termination(
  const SDP_Solver_Parameters &parameters, const El::BigFloat &primal_error,
  const El::BigFloat &dual_error, const El::BigFloat &duality_gap,
  const El::BigFloat &primal_step_length, const El::BigFloat &dual_step_length,
  const int &iteration,
  const std::chrono::time_point<std::chrono::high_resolution_clock>
    &solver_start_time,
  bool &is_primal_and_dual_feasible,
  SDP_Solver_Terminate_Reason &terminate_reason, bool &terminate_now)
{
  const bool is_dual_feasible(dual_error < parameters.dual_error_threshold),
    is_primal_feasible(primal_error < parameters.primal_error_threshold);
  is_primal_and_dual_feasible = (is_primal_feasible && is_dual_feasible);

  const bool is_optimal(duality_gap < parameters.duality_gap_threshold);

  terminate_now = true;
  if(is_primal_feasible && parameters.find_primal_feasible)
    {
      terminate_reason = SDP_Solver_Terminate_Reason::PrimalFeasible;
    }
  else if(is_dual_feasible && parameters.find_dual_feasible)
    {
      terminate_reason = SDP_Solver_Terminate_Reason::DualFeasible;
    }
  else if(primal_step_length == El::BigFloat(1)
          && parameters.detect_primal_feasible_jump)
    {
      terminate_reason
        = SDP_Solver_Terminate_Reason::PrimalFeasibleJumpDetected;
    }
  else if(dual_step_length == El::BigFloat(1)
          && parameters.detect_dual_feasible_jump)
    {
      terminate_reason = SDP_Solver_Terminate_Reason::DualFeasibleJumpDetected;
    }
  else if(is_primal_and_dual_feasible && is_optimal)
    {
      terminate_reason = SDP_Solver_Terminate_Reason::PrimalDualOptimal;
    }
  else if(iteration > parameters.max_iterations)
    {
      terminate_reason = SDP_Solver_Terminate_Reason::MaxIterationsExceeded;
    }
  else if(std::chrono::duration_cast<std::chrono::seconds>(
            std::chrono::high_resolution_clock::now() - solver_start_time)
            .count()
          >= parameters.max_runtime)
    {
      terminate_reason = SDP_Solver_Terminate_Reason::MaxRuntimeExceeded;
    }
  else
    {
      terminate_now = false;
    }
  El::byte terminate_byte(terminate_now);
  // Time varies between cores, so follow the decision of the root.
  El::mpi::Broadcast(terminate_byte, 0, El::mpi::COMM_WORLD);
  terminate_now = static_cast<bool>(terminate_byte);
}
<commit_msg>Rearrange some termination conditions<commit_after>#include "../../SDP_Solver_Terminate_Reason.hxx"
#include "../../../SDP_Solver_Parameters.hxx"

void compute_feasible_and_termination(
  const SDP_Solver_Parameters &parameters, const El::BigFloat &primal_error,
  const El::BigFloat &dual_error, const El::BigFloat &duality_gap,
  const El::BigFloat &primal_step_length, const El::BigFloat &dual_step_length,
  const int &iteration,
  const std::chrono::time_point<std::chrono::high_resolution_clock>
    &solver_start_time,
  bool &is_primal_and_dual_feasible,
  SDP_Solver_Terminate_Reason &terminate_reason, bool &terminate_now)
{
  const bool is_dual_feasible(dual_error < parameters.dual_error_threshold),
    is_primal_feasible(primal_error < parameters.primal_error_threshold);
  is_primal_and_dual_feasible = (is_primal_feasible && is_dual_feasible);

  const bool is_optimal(duality_gap < parameters.duality_gap_threshold);

  terminate_now = true;
  if(is_primal_and_dual_feasible && is_optimal)
    {
      terminate_reason = SDP_Solver_Terminate_Reason::PrimalDualOptimal;
    }
  else if(is_dual_feasible && parameters.find_dual_feasible)
    {
      terminate_reason = SDP_Solver_Terminate_Reason::DualFeasible;
    }
  else if(is_primal_feasible && parameters.find_primal_feasible)
    {
      terminate_reason = SDP_Solver_Terminate_Reason::PrimalFeasible;
    }
  else if(dual_step_length == El::BigFloat(1)
          && parameters.detect_dual_feasible_jump)
    {
      terminate_reason = SDP_Solver_Terminate_Reason::DualFeasibleJumpDetected;
    }
  else if(primal_step_length == El::BigFloat(1)
          && parameters.detect_primal_feasible_jump)
    {
      terminate_reason
        = SDP_Solver_Terminate_Reason::PrimalFeasibleJumpDetected;
    }
  else if(iteration > parameters.max_iterations)
    {
      terminate_reason = SDP_Solver_Terminate_Reason::MaxIterationsExceeded;
    }
  else if(std::chrono::duration_cast<std::chrono::seconds>(
            std::chrono::high_resolution_clock::now() - solver_start_time)
            .count()
          >= parameters.max_runtime)
    {
      terminate_reason = SDP_Solver_Terminate_Reason::MaxRuntimeExceeded;
    }
  else
    {
      terminate_now = false;
    }
  El::byte terminate_byte(terminate_now);
  // Time varies between cores, so follow the decision of the root.
  El::mpi::Broadcast(terminate_byte, 0, El::mpi::COMM_WORLD);
  terminate_now = static_cast<bool>(terminate_byte);
}
<|endoftext|>


<commit_before>/*******************************
Copyright (C) 2013-2015 gregoire ANGERAND

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
**********************************/

#include "ShaderInstance.h"
#include "GLContext.h"

namespace n {
namespace graphics {

ShaderInstance *ShaderInstance::current = 0;

ShaderInstance::ShaderInstance(Shader<FragmentShader> *frag, Shader<VertexShader> *vert, Shader<GeometryShader> *geom) : handle(0), samplerCount(0), bases{frag, vert, geom} {
	compile();
}

ShaderInstance::ShaderInstance(Shader<FragmentShader> *frag, ShaderProgram::StandardVertexShader vert, Shader<GeometryShader> *geom) : ShaderInstance(frag, ShaderProgram::getStandardVertexShader(vert), geom) {

}

ShaderInstance::~ShaderInstance() {
	if(handle) {
		gl::GLuint h = handle;
		GLContext::getContext()->addGLTask([=]() { gl::glDeleteProgram(h); });
	}
}

const ShaderInstance *ShaderInstance::getCurrent() {
	return current;
}

void ShaderInstance::bind() {
	GLContext::getContext()->program = 0;
	if(current != this) {
		rebind();
	}
}

void ShaderInstance::rebind() {
	GLContext::getContext()->program = 0;
	gl::glUseProgram(handle);
	for(uint i = 0; i != samplerCount; i++) {
		bindings[i].bind(i);
	}
	current = this;
	//bindStandards();
}

void ShaderInstance::unbind() {
	current = 0;
	internal::rebindProgram();
}

void ShaderInstance::compile() {
	handle = gl::glCreateProgram();
	bool val = true;
	for(uint i = 0; i != 3; i++) {
		if(bases[i]) {
			gl::glAttachShader(handle, bases[i]->handle);
			val &= bases[i]->isValid();
		}
	}
	gl::glLinkProgram(handle);
	int res = 0;
	gl::glGetProgramiv(handle, GL_LINK_STATUS, &res);
	if(!res || !val) {
		int size = 0;
		gl::glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &size);
		char *msg = new char[size + 1];
		gl::glGetProgramInfoLog(handle, size, &res, msg);
		gl::glDeleteProgram(handle);
		handle = 0;
		msg[size] = '\0';
		core::String logs = msg;
		delete[] msg;
		throw ShaderLinkingException(logs);
	} else {
		getUniforms();
	}
}

void ShaderInstance::getUniforms() {
	const uint max = 512;
	char name[max];
	int uniforms = 0;
	gl::glGetProgramiv(handle, GL_ACTIVE_UNIFORMS, &uniforms);
	for(uint i = 0; i != SVMax; i++) {
		standards[i] = UniformAddr(GL_INVALID_INDEX);
	}
	for(uint i = 0; i != (uint)uniforms; i++) {
		gl::GLsizei size = 0;
		gl::GLenum type = GL_NONE;
		gl::glGetActiveUniform(handle, i, max - 1, 0, &size, &type, name);
		core::String uniform = name;
		if(uniform.endsWith("[0]")) {
			uniform = uniform.subString(0, uniform.size() - 3);
		}
		UniformInfo info({gl::glGetUniformLocation(handle, name), (uint)size});
		if(isSampler(type)) {
			uint slot = samplerCount++;
			setValue(info.addr, int(slot));
			info.addr = slot;
		}
		uniformsInfo[uniform] = info;
		int std = computeStandardIndex(uniform);
		if(std != UniformAddr(GL_INVALID_INDEX)) {
			standards[std] = info.addr;
		}
	}
	bindings = new internal::TextureBinding[samplerCount];
}

ShaderInstance::UniformAddr ShaderInstance::computeStandardIndex(const core::String &name) {
	for(uint i = 0; i != SVMax; i++) {
		if(name == ShaderValueName[i]) {
			return i;
		}
	}
	return UniformAddr(GL_INVALID_INDEX);
}

void ShaderInstance::bindStandards() const {
	setValue("n_ProjectionMatrix", GLContext::getContext()->getProjectionMatrix());
	setValue("n_ViewMatrix", GLContext::getContext()->getViewMatrix());
	setValue("n_ViewportSize", math::Vec2(GLContext::getContext()->getViewport()));
	setValue("n_ModelMatrix", GLContext::getContext()->getModelMatrix());
	setValue("n_ViewProjectionMatrix", GLContext::getContext()->getProjectionMatrix() * GLContext::getContext()->getViewMatrix());
}

void ShaderInstance::setValue(UniformAddr addr, int a) const {
	gl::glProgramUniform1i(handle, addr, a);
}

void ShaderInstance::setValue(UniformAddr addr, uint a) const {
	gl::glProgramUniform1ui(handle, addr, a);
}

void ShaderInstance::setValue(UniformAddr addr, float f) const {
	gl::glProgramUniform1f(handle, addr, f);
}

void ShaderInstance::setValue(UniformAddr addr, double f) const {
	gl::glProgramUniform1f(handle, addr, f);
}

void ShaderInstance::setValue(UniformAddr addr, const math::Vec2i &v) const {
	gl::glProgramUniform2iv(handle, addr, 1, v.begin());
}

void ShaderInstance::setValue(UniformAddr addr, const math::Vec3i &v) const {
	gl::glProgramUniform3iv(handle, addr, 1, v.begin());
}

void ShaderInstance::setValue(UniformAddr addr, const math::Vec2 &v) const {
	gl::glProgramUniform2fv(handle, addr, 1, v.begin());
}

void ShaderInstance::setValue(UniformAddr addr, const math::Vec3 &v) const {
	gl::glProgramUniform3fv(handle, addr, 1, v.begin());
}

void ShaderInstance::setValue(UniformAddr addr, const math::Vec4 &v) const {
	gl::glProgramUniform4fv(handle, addr, 1, v.begin());
}

void ShaderInstance::setValue(UniformAddr addr, const math::Matrix2<float> &m) const {
	gl::glProgramUniformMatrix2fv(handle, addr, 1, GL_TRUE, m.begin());
}

void ShaderInstance::setValue(UniformAddr addr, const math::Matrix3<float> &m) const {
	gl::glProgramUniformMatrix3fv(handle, addr, 1, GL_TRUE, m.begin());
}

void ShaderInstance::setValue(UniformAddr addr, const math::Matrix4<float> &m) const {
	gl::glProgramUniformMatrix4fv(handle, addr, 1, GL_TRUE, m.begin());
}

void ShaderInstance::setValue(UniformAddr slot, const Texture &t, TextureSampler sampler) const {
	if(slot != UniformAddr(GL_INVALID_INDEX)) {
		bindings[slot] = t;
		bindings[slot] = sampler;
		if(current == this) {
			bindings[slot].bind(slot);
		} else {
			t.prepare();
		}
	}
}

ShaderInstance::UniformAddr ShaderInstance::getAddr(const core::String &name) const {
	return getInfo(name).addr;
}

ShaderInstance::UniformInfo ShaderInstance::getInfo(const core::String &name) const {	return uniformsInfo.get(name, UniformInfo{UniformAddr(GL_INVALID_INDEX), 0});
}

}
}
<commit_msg>Fixed mem leaks.<commit_after>/*******************************
Copyright (C) 2013-2015 gregoire ANGERAND

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
**********************************/

#include "ShaderInstance.h"
#include "GLContext.h"

namespace n {
namespace graphics {

ShaderInstance *ShaderInstance::current = 0;

ShaderInstance::ShaderInstance(Shader<FragmentShader> *frag, Shader<VertexShader> *vert, Shader<GeometryShader> *geom) : handle(0), samplerCount(0), bases{frag, vert, geom} {
	compile();
}

ShaderInstance::ShaderInstance(Shader<FragmentShader> *frag, ShaderProgram::StandardVertexShader vert, Shader<GeometryShader> *geom) : ShaderInstance(frag, ShaderProgram::getStandardVertexShader(vert), geom) {

}

ShaderInstance::~ShaderInstance() {
	if(handle) {
		gl::GLuint h = handle;
		GLContext::getContext()->addGLTask([=]() { gl::glDeleteProgram(h); });
	}
	delete[] bindings;
}

const ShaderInstance *ShaderInstance::getCurrent() {
	return current;
}

void ShaderInstance::bind() {
	GLContext::getContext()->program = 0;
	if(current != this) {
		rebind();
	}
}

void ShaderInstance::rebind() {
	GLContext::getContext()->program = 0;
	gl::glUseProgram(handle);
	for(uint i = 0; i != samplerCount; i++) {
		bindings[i].bind(i);
	}
	current = this;
	//bindStandards();
}

void ShaderInstance::unbind() {
	current = 0;
	internal::rebindProgram();
}

void ShaderInstance::compile() {
	handle = gl::glCreateProgram();
	bool val = true;
	for(uint i = 0; i != 3; i++) {
		if(bases[i]) {
			gl::glAttachShader(handle, bases[i]->handle);
			val &= bases[i]->isValid();
		}
	}
	gl::glLinkProgram(handle);
	int res = 0;
	gl::glGetProgramiv(handle, GL_LINK_STATUS, &res);
	if(!res || !val) {
		int size = 0;
		gl::glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &size);
		char *msg = new char[size + 1];
		gl::glGetProgramInfoLog(handle, size, &res, msg);
		gl::glDeleteProgram(handle);
		handle = 0;
		msg[size] = '\0';
		core::String logs = msg;
		delete[] msg;
		throw ShaderLinkingException(logs);
	} else {
		getUniforms();
	}
}

void ShaderInstance::getUniforms() {
	const uint max = 512;
	char name[max];
	int uniforms = 0;
	gl::glGetProgramiv(handle, GL_ACTIVE_UNIFORMS, &uniforms);
	for(uint i = 0; i != SVMax; i++) {
		standards[i] = UniformAddr(GL_INVALID_INDEX);
	}
	for(uint i = 0; i != (uint)uniforms; i++) {
		gl::GLsizei size = 0;
		gl::GLenum type = GL_NONE;
		gl::glGetActiveUniform(handle, i, max - 1, 0, &size, &type, name);
		core::String uniform = name;
		if(uniform.endsWith("[0]")) {
			uniform = uniform.subString(0, uniform.size() - 3);
		}
		UniformInfo info({gl::glGetUniformLocation(handle, name), (uint)size});
		if(isSampler(type)) {
			uint slot = samplerCount++;
			setValue(info.addr, int(slot));
			info.addr = slot;
		}
		uniformsInfo[uniform] = info;
		int std = computeStandardIndex(uniform);
		if(std != UniformAddr(GL_INVALID_INDEX)) {
			standards[std] = info.addr;
		}
	}
	bindings = new internal::TextureBinding[samplerCount];
}

ShaderInstance::UniformAddr ShaderInstance::computeStandardIndex(const core::String &name) {
	for(uint i = 0; i != SVMax; i++) {
		if(name == ShaderValueName[i]) {
			return i;
		}
	}
	return UniformAddr(GL_INVALID_INDEX);
}

void ShaderInstance::bindStandards() const {
	setValue("n_ProjectionMatrix", GLContext::getContext()->getProjectionMatrix());
	setValue("n_ViewMatrix", GLContext::getContext()->getViewMatrix());
	setValue("n_ViewportSize", math::Vec2(GLContext::getContext()->getViewport()));
	setValue("n_ModelMatrix", GLContext::getContext()->getModelMatrix());
	setValue("n_ViewProjectionMatrix", GLContext::getContext()->getProjectionMatrix() * GLContext::getContext()->getViewMatrix());
}

void ShaderInstance::setValue(UniformAddr addr, int a) const {
	gl::glProgramUniform1i(handle, addr, a);
}

void ShaderInstance::setValue(UniformAddr addr, uint a) const {
	gl::glProgramUniform1ui(handle, addr, a);
}

void ShaderInstance::setValue(UniformAddr addr, float f) const {
	gl::glProgramUniform1f(handle, addr, f);
}

void ShaderInstance::setValue(UniformAddr addr, double f) const {
	gl::glProgramUniform1f(handle, addr, f);
}

void ShaderInstance::setValue(UniformAddr addr, const math::Vec2i &v) const {
	gl::glProgramUniform2iv(handle, addr, 1, v.begin());
}

void ShaderInstance::setValue(UniformAddr addr, const math::Vec3i &v) const {
	gl::glProgramUniform3iv(handle, addr, 1, v.begin());
}

void ShaderInstance::setValue(UniformAddr addr, const math::Vec2 &v) const {
	gl::glProgramUniform2fv(handle, addr, 1, v.begin());
}

void ShaderInstance::setValue(UniformAddr addr, const math::Vec3 &v) const {
	gl::glProgramUniform3fv(handle, addr, 1, v.begin());
}

void ShaderInstance::setValue(UniformAddr addr, const math::Vec4 &v) const {
	gl::glProgramUniform4fv(handle, addr, 1, v.begin());
}

void ShaderInstance::setValue(UniformAddr addr, const math::Matrix2<float> &m) const {
	gl::glProgramUniformMatrix2fv(handle, addr, 1, GL_TRUE, m.begin());
}

void ShaderInstance::setValue(UniformAddr addr, const math::Matrix3<float> &m) const {
	gl::glProgramUniformMatrix3fv(handle, addr, 1, GL_TRUE, m.begin());
}

void ShaderInstance::setValue(UniformAddr addr, const math::Matrix4<float> &m) const {
	gl::glProgramUniformMatrix4fv(handle, addr, 1, GL_TRUE, m.begin());
}

void ShaderInstance::setValue(UniformAddr slot, const Texture &t, TextureSampler sampler) const {
	if(slot != UniformAddr(GL_INVALID_INDEX)) {
		bindings[slot] = t;
		bindings[slot] = sampler;
		if(current == this) {
			bindings[slot].bind(slot);
		} else {
			t.prepare();
		}
	}
}

ShaderInstance::UniformAddr ShaderInstance::getAddr(const core::String &name) const {
	return getInfo(name).addr;
}

ShaderInstance::UniformInfo ShaderInstance::getInfo(const core::String &name) const {	return uniformsInfo.get(name, UniformInfo{UniformAddr(GL_INVALID_INDEX), 0});
}

}
}
<|endoftext|>