<commit_before>/*
* Mlock Allocator
* (C) 2012 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/

#include <botan/locking_allocator.h>
#include <botan/internal/assert.h>
#include <algorithm>
#include <cstring>
#include <sys/mman.h>
#include <sys/resource.h>

namespace Botan {

namespace {

size_t mlock_limit()
   {
   struct rlimit limits;
   ::getrlimit(RLIMIT_MEMLOCK, &limits);

   if(limits.rlim_cur < limits.rlim_max)
      {
      limits.rlim_cur = limits.rlim_max;
      ::setrlimit(RLIMIT_MEMLOCK, &limits);
      ::getrlimit(RLIMIT_MEMLOCK, &limits);
      }

   /*
   * Linux defaults to only 64 KiB of mlockable memory per process
   * (too small) but BSDs offer a small fraction of total RAM (more
   * than we need). Bound the total mlock size to 256 KiB which is
   * enough to run the entire test suite without spilling to non-mlock
   * memory, but small enough that we should not cause problems if
   * multiple processes are mlocking on the same machine.
   */
   return std::min<size_t>(limits.rlim_cur, 256*1024);
   }

bool ptr_in_pool(const void* pool_ptr, size_t poolsize,
                 const void* buf_ptr, size_t bufsize)
   {
   const size_t pool = reinterpret_cast<size_t>(pool_ptr);
   const size_t buf = reinterpret_cast<size_t>(buf_ptr);

   if(buf < pool || buf >= pool + poolsize)
      return false;

   BOTAN_ASSERT(buf + bufsize <= pool + poolsize,
                "Invalid pointer/length halfway into mem pool");

   return true;
   }

}

void* mlock_allocator::allocate(size_t n, size_t alignment)
   {
   if(!m_pool || n >= m_poolsize)
      return nullptr; // bigger than the whole pool!

   std::lock_guard<std::mutex> lock(m_mutex);

   auto best_fit = m_freelist.end();

   for(auto i = m_freelist.begin(); i != m_freelist.end(); ++i)
      {
      // If we have a perfect fit, use it immediately
      if(i->second == n && (i->first % alignment) == 0)
         {
         const size_t offset = i->first;
         m_freelist.erase(i);
         ::memset(m_pool + offset, 0, n);
         return m_pool + offset;
         }

      if((i->second > (i->first % alignment) + n) &&
         ((best_fit == m_freelist.end()) || (best_fit->second > i->second)))
         {
         best_fit = i;
         }
      }

   if(best_fit != m_freelist.end())
      {
      const size_t offset = best_fit->first;

      size_t alignment_padding = offset % alignment;

      best_fit->first += n + alignment_padding;
      best_fit->second -= n + alignment_padding;

      // Need to realign, split the block
      if(alignment_padding)
         m_freelist.insert(best_fit, std::make_pair(offset, alignment_padding));

      ::memset(m_pool + offset + alignment_padding, 0, n);

      return m_pool + offset + alignment_padding;
      }

   return nullptr;
   }

bool mlock_allocator::deallocate(void* p, size_t n)
   {
   if(!m_pool || !ptr_in_pool(m_pool, m_poolsize, p, n))
      return false;

   std::lock_guard<std::mutex> lock(m_mutex);

   const size_t start = static_cast<byte*>(p) - m_pool;

   auto comp = [](std::pair<size_t, size_t> x, std::pair<size_t, size_t> y){ return x.first < y.first; };

   auto i = std::lower_bound(m_freelist.begin(), m_freelist.end(),
                             std::make_pair(start, 0), comp);

   // try to merge with later block
   if(start + n == i->first)
      {
      i->first = start;
      i->second += n;
      n = 0;
      }

   // try to merge with previous block
   if(i != m_freelist.begin())
      {
      auto prev = std::prev(i);

      if(prev->first + prev->second == start)
         {
         if(n)
            {
            prev->second += n;
            n = 0;
            }
         else
            {
            // merge adjoining
            prev->second += i->second;
            m_freelist.erase(i);
            }
         }
      }

   if(n != 0) // no merge possible?
      m_freelist.insert(i, std::make_pair(start, n));

   return true;
   }

mlock_allocator::mlock_allocator() :
   m_poolsize(mlock_limit()),
   m_pool(nullptr)
   {
#if !defined(MAP_NOCORE)
   #define MAP_NOCORE 0
#endif

   if(m_poolsize)
      {
      m_pool = static_cast<byte*>(
         ::mmap(
            nullptr, m_poolsize,
            PROT_READ | PROT_WRITE,
            MAP_ANONYMOUS | MAP_SHARED | MAP_NOCORE,
            -1, 0));

      if(m_pool == static_cast<byte*>(MAP_FAILED))
         throw std::runtime_error("Failed to mmap pool");

      std::memset(m_pool, 0x00, m_poolsize);

      if(::mlock(m_pool, m_poolsize) != 0)
         {
         ::munmap(m_pool, m_poolsize);
         m_pool = nullptr;
         throw std::runtime_error("Failed to lock pool");
         }

      m_freelist.push_back(std::make_pair(0, m_poolsize));
      }
   }

mlock_allocator::~mlock_allocator()
   {
   if(m_pool)
      {
      std::memset(m_pool, 0, m_poolsize);
      ::munlock(m_pool, m_poolsize);
      ::munmap(m_pool, m_poolsize);
      m_pool = nullptr;
      }
   }

mlock_allocator& mlock_allocator::instance()
   {
   static mlock_allocator mlock;
   return mlock;
   }

}
<commit_msg>Fix alignment again and add assert checks so we don't mess up again.<commit_after>/*
* Mlock Allocator
* (C) 2012 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/

#include <botan/locking_allocator.h>
#include <botan/internal/assert.h>
#include <algorithm>
#include <cstring>
#include <sys/mman.h>
#include <sys/resource.h>

namespace Botan {

namespace {

size_t mlock_limit()
   {
   struct rlimit limits;
   ::getrlimit(RLIMIT_MEMLOCK, &limits);

   if(limits.rlim_cur < limits.rlim_max)
      {
      limits.rlim_cur = limits.rlim_max;
      ::setrlimit(RLIMIT_MEMLOCK, &limits);
      ::getrlimit(RLIMIT_MEMLOCK, &limits);
      }

   /*
   * Linux defaults to only 64 KiB of mlockable memory per process
   * (too small) but BSDs offer a small fraction of total RAM (more
   * than we need). Bound the total mlock size to 256 KiB which is
   * enough to run the entire test suite without spilling to non-mlock
   * memory, but small enough that we should not cause problems if
   * multiple processes are mlocking on the same machine.
   */
   return std::min<size_t>(limits.rlim_cur, 256*1024);
   }

bool ptr_in_pool(const void* pool_ptr, size_t poolsize,
                 const void* buf_ptr, size_t bufsize)
   {
   const size_t pool = reinterpret_cast<size_t>(pool_ptr);
   const size_t buf = reinterpret_cast<size_t>(buf_ptr);

   if(buf < pool || buf >= pool + poolsize)
      return false;

   BOTAN_ASSERT(buf + bufsize <= pool + poolsize,
                "Invalid pointer/length halfway into mem pool");

   return true;
   }

size_t padding_for_alignment(size_t offset, size_t desired_alignment)
   {
   size_t mod = offset % desired_alignment;
   if(mod == 0)
      return 0; // already right on
   return desired_alignment - mod;
   }

}

void* mlock_allocator::allocate(size_t n, size_t alignment)
   {
   if(!m_pool || n >= m_poolsize)
      return nullptr; // bigger than the whole pool!

   std::lock_guard<std::mutex> lock(m_mutex);

   auto best_fit = m_freelist.end();

   for(auto i = m_freelist.begin(); i != m_freelist.end(); ++i)
      {
      // If we have a perfect fit, use it immediately
      if(i->second == n && (i->first % alignment) == 0)
         {
         const size_t offset = i->first;
         m_freelist.erase(i);
         ::memset(m_pool + offset, 0, n);

         BOTAN_ASSERT((reinterpret_cast<size_t>(m_pool) + offset) % alignment == 0,
                      "Returning correctly aligned pointer");

         return m_pool + offset;
         }

      if((i->second >= (n + padding_for_alignment(i->first, alignment)) &&
          ((best_fit == m_freelist.end()) || (best_fit->second > i->second))))
         {
         best_fit = i;
         }
      }

   if(best_fit != m_freelist.end())
      {
      const size_t offset = best_fit->first;

      const size_t alignment_padding = padding_for_alignment(offset, alignment);

      best_fit->first += n + alignment_padding;
      best_fit->second -= n + alignment_padding;

      // Need to realign, split the block
      if(alignment_padding)
         {
         if(best_fit->second == 0)
            {
            /*
            We used the entire block except for small piece used for
            alignment at the beginning, so just update this entry.
            */
            best_fit->second = alignment_padding;
            }
         else
            m_freelist.insert(best_fit, std::make_pair(offset, alignment_padding));
         }

      ::memset(m_pool + offset + alignment_padding, 0, n);

      BOTAN_ASSERT((reinterpret_cast<size_t>(m_pool) + offset + alignment_padding) % alignment == 0,
                   "Returning correctly aligned pointer");

      return m_pool + offset + alignment_padding;
      }

   return nullptr;
   }

bool mlock_allocator::deallocate(void* p, size_t n)
   {
   if(!m_pool || !ptr_in_pool(m_pool, m_poolsize, p, n))
      return false;

   std::lock_guard<std::mutex> lock(m_mutex);

   const size_t start = static_cast<byte*>(p) - m_pool;

   auto comp = [](std::pair<size_t, size_t> x, std::pair<size_t, size_t> y){ return x.first < y.first; };

   auto i = std::lower_bound(m_freelist.begin(), m_freelist.end(),
                             std::make_pair(start, 0), comp);

   // try to merge with later block
   if(start + n == i->first)
      {
      i->first = start;
      i->second += n;
      n = 0;
      }

   // try to merge with previous block
   if(i != m_freelist.begin())
      {
      auto prev = std::prev(i);

      if(prev->first + prev->second == start)
         {
         if(n)
            {
            prev->second += n;
            n = 0;
            }
         else
            {
            // merge adjoining
            prev->second += i->second;
            m_freelist.erase(i);
            }
         }
      }

   if(n != 0) // no merge possible?
      m_freelist.insert(i, std::make_pair(start, n));

   return true;
   }

mlock_allocator::mlock_allocator() :
   m_poolsize(mlock_limit()),
   m_pool(nullptr)
   {
#if !defined(MAP_NOCORE)
   #define MAP_NOCORE 0
#endif

   if(m_poolsize)
      {
      m_pool = static_cast<byte*>(
         ::mmap(
            nullptr, m_poolsize,
            PROT_READ | PROT_WRITE,
            MAP_ANONYMOUS | MAP_SHARED | MAP_NOCORE,
            -1, 0));

      if(m_pool == static_cast<byte*>(MAP_FAILED))
         throw std::runtime_error("Failed to mmap pool");

      std::memset(m_pool, 0x00, m_poolsize);

      if(::mlock(m_pool, m_poolsize) != 0)
         {
         ::munmap(m_pool, m_poolsize);
         m_pool = nullptr;
         throw std::runtime_error("Failed to lock pool");
         }

      m_freelist.push_back(std::make_pair(0, m_poolsize));
      }
   }

mlock_allocator::~mlock_allocator()
   {
   if(m_pool)
      {
      std::memset(m_pool, 0, m_poolsize);
      ::munlock(m_pool, m_poolsize);
      ::munmap(m_pool, m_poolsize);
      m_pool = nullptr;
      }
   }

mlock_allocator& mlock_allocator::instance()
   {
   static mlock_allocator mlock;
   return mlock;
   }

}
<|endoftext|>


<commit_before>#include "SysConfig.h"
#if(HAS_PCA9539)

#include <CI2C.h>
#include "CPCA9539.h"
#include "CTimer.h"
#include "NDataManager.h"

namespace
{
    CTimer pca9539_sample_timer;
}

CPCA9539::CPCA9539( CI2C *i2cInterfaceIn )
    : m_pca( i2cInterfaceIn )
{

}

void CPCA9539::Initialize()
{
    Serial.println( "CPCA9539.Status:INIT;" );

    pca9539_sample_timer.Reset();

    Serial.println( "CPCA9539.Status:POST_INIT;");
}

void CPCA9539::Update( CCommand &commandIn )
{
    if( pca9539_sample_timer.HasElapsed( 1000 ) )
    {
        Serial.println( "PCA9539.Status:LOOP;" );
    }
}

#endif<commit_msg>Init in module class<commit_after>#include "SysConfig.h"
#if(HAS_PCA9539)

#include <CI2C.h>
#include "CPCA9539.h"
#include "CTimer.h"
#include "NDataManager.h"

namespace
{
    CTimer pca9539_sample_timer;
}

CPCA9539::CPCA9539( CI2C *i2cInterfaceIn )
    : m_pca( i2cInterfaceIn )
{

}

void CPCA9539::Initialize()
{
    Serial.println( "CPCA9539.Status:INIT;" );

    pca9539_sample_timer.Reset();

    Serial.println( "CPCA9539.Status:POST_INIT;");
}

void CPCA9539::Update( CCommand &commandIn )
{
    if( pca9539_sample_timer.HasElapsed( 1000 ) )
    {
        Serial.println( "PCA9539.Status:LOOP;" );
        m_pca.Initialize();
    }
}

#endif<|endoftext|>


<commit_before>/******************************************************************************\
* EventHandler.hpp                                                             *
* An event handler providing GUI-like events                                   *
*                                                                              *
*                                                                              *
* Copyright (C) 2006 by Leandro Motta Barros.                                  *
*                                                                              *
* This program is distributed under the OpenSceneGraph Public License. You     *
* should have received a copy of it with the source distribution, in a file    *
* named 'COPYING.txt'.                                                         *
\******************************************************************************/

#ifndef _GUISH_EVENT_HANDLER_HPP_
#define _GUISH_EVENT_HANDLER_HPP_

#include <boost/signal.hpp>
#include <osgProducer/Viewer>
#include <OSGUIsh/FocusPolicy.hpp>
#include <OSGUIsh/ManualFocusPolicy.hpp>

namespace OSGUIsh
{
   /** A \c struct grouping parameters passed to event handlers. Future versions
    *  of OSGUish may add more members here if necessary without breaking
    *  existing user code.
    *  @note Be aware that, in the general case,
    *        <tt>hit.getNodePath().back() != node.get()</tt>. \c hit contains
    *        the actual, "low level" hit, while \c node contains the node
    *        registered with OSGUish. For instance, suppose  you register a
    *        car node, that has a car body node and four wheel nodes as
    *        subnodes. \c node will always be the whole car, while \c hit will
    *        be the "car body" or one of the "wheels".
    */
   struct HandlerParams
   {
      public:
         /// Convenience constructor.
         HandlerParams (NodePtr nodeParam,
                        const osgGA::GUIEventAdapter& eventParam,
                        const osgUtil::Hit& hitParam)
            : node(nodeParam), event(eventParam), hit(hitParam)
         { }

         /// The node generating the event.
         NodePtr node;

         /** The event data, as passed by OSG. Here you can find many useful
          *  information, like "which mouse button was pressed".
          */
         const osgGA::GUIEventAdapter& event;

         /** The \c osgUtil::Hit for the node that was under the mouse pointer
          *  when the event was generated.
          *  @note Notice that, in some cases, the \c osgUtil::Hit for the node
          *        under the mouse pointer doesn't really have something to do
          *        with the event being handled. For example, if the event is a
          *        <tt>KeyUp</tt> and the focus policy is not the "node under
          *        mouse has focus" policy, than the hit will not be related to
          *        the node generating the event.
          *
Also, in cases like the above, the hit may even be
          *        invalid, since, perhaps, there will not be any registered
          *        node under the mouse pointer.
          */
         const osgUtil::Hit& hit;
   };

   /** An event handler providing GUI-like events for nodes. The \c EventHandler
    *  has an internal list of nodes being "observed". Every observed node has a
    *  collection of signals associated to it. These signals represent the
    *  events that can be generated for the node.
    */
   class EventHandler: public osgGA::GUIEventHandler
   {
      public:
         /** Constructs an \c EventHandler.
          *  @param viewer The viewer used to view the scene graph. This used
          *         for calling its \c computeIntersections() method.
          *  @param kbdPolicyFactory The factory that will be used to create the
          *         \c FocusPolicy used to automatically set the focus for
          *         keyboard events.
          *  @param wheelPolicyFactory The factory that will be used to create
          *         the \c FocusPolicy used to automatically set the focus for
          *         mouse wheel events.
          */
         EventHandler (osgProducer::Viewer& viewer,
                       const FocusPolicyFactory& kbdPolicyFactory =
                       FocusPolicyFactoryMason<ManualFocusPolicy>(),
                       const FocusPolicyFactory& wheelPolicyFactory =
                       FocusPolicyFactoryMason<ManualFocusPolicy>());

         /** Handles upcoming events (overloads virtual method).
          *  @return See \c handleReturnValues_ please.
          */
         bool handle (const osgGA::GUIEventAdapter& ea,
                      osgGA::GUIActionAdapter&);

         /** Sets the list of root nodes used when picking.
          *
This deserves some words: when using multiple
          *  <tt>osg::CameraNode</tt>s (in particular when using HUDs), picking
          *  in OSG can be problematic. The details of this problem are not
          *  important here (basically, we don't have control on the relative
          *  "z-order" of objects in different <tt>CameraNode</tt>s). But it is
          *  important to know that, if we want to pick objects in different
          *  camera nodes, we may have some unpredictable results.
          *
So, what's the solution? Actually, there is no solution. At
          *  least, not an easy one. So, OSGUIsh uses a list of root nodes when
          *  picking, as a way to offer some control to its users.
          *
Suppose, for instance, that you want to pick both in a group of
          *  objects and in a HUD. By default, OSGUIsh will pick from the root
          *  of the whole scene (objects and HUD), which (as described above)
          *  will not work. So, you call \c setPickingRoots() passing two nodes:
          *  first the HUD, second the group of objects.
          *
Once you do this, OSGUIsh will start picking in two stages.
          *  First, it will try picking the HUD. If it hits something in the
          *  HUD, that hit will be used. If not, OSGUIsh will try picking the
          *  group of objects.
          */
         void setPickingRoots (std::vector<NodePtr> newRoot);

         /** Sets the root used by OSGUIsh when picking.
          *  @see setPickingRoots for a longer discussion on how OSGUIsh
          *       performs picking (you can set more than one root, for
          *       example).
          */
         void setPickingRoot (NodePtr newRoot);

         /** A type representing a signal used in OSGUIsh. This signal returns
          *  nothing and takes a \c HandlerParams, which packs all relevant data
          *  for an event handler function.
          */
         typedef boost::signal<void (HandlerParams&)> Signal_t;

         /// A (smart) pointer to a \c Signal_t;
         typedef boost::shared_ptr<Signal_t> SignalPtr;

         /** Adds a given node to the list of nodes being "observed" by this
          *  \c EventHandler. In other words, signals for this node will be
          *  triggered from this call on.
          *  @param node The node that will be added to this \c EventHandler.
          */
         void addNode (const NodePtr node);

         /** Returns a signal associated with a given node. This is typically
          *  used to call \c connect() on the returned signal.
          *  @param node The desired node.
          *  @param signal The desired signal. Valid signals are
          *         <tt>"MouseEnter"</tt>, <tt>"MouseLeave"</tt>,
          *         <tt>"MouseMove"</tt>, <tt>"MouseDown"</tt>,
          *         <tt>"MouseUp"</tt>, <tt>"Click"</tt>,
          *         <tt>"DoubleClick"</tt>, <tt>"MouseWheelUp"</tt>,
          *         <tt>"MouseWheelDown"</tt>, <tt>"KeyUp"</tt> and
          *         <tt>"KeyDown"</tt>.
          */
         SignalPtr getSignal (const NodePtr node, const std::string& signal);

         /** Ignores or stops to ignore faces that are back-facing the viewer
          *  when picking. It may be useful to ignore back faces when backface
          *  culling is enabled.
          *  @param ignore If \c true, back faces will be ignored when picking.
          *         If \c false, back faces will be considered when piking.
          */
         void ignoreBackFaces (bool ignore = true)
         { ignoreBackFaces_ = ignore; }

         /// Sets the node that will receive keyboard events.
         void setKeyboardFocus (const NodePtr node);

         /// Sets the node that will receive mouse wheel events.
         void setMouseWheelFocus (const NodePtr node);

         /** Sets the focus policy for keyboard events to a given one.
          *  @param policyFactory The factory that will be used to create the
          *         actual policy.
          */
         void setKeyboardFocusPolicy (const FocusPolicyFactory& policyFactory);

         /** Sets the focus policy for mouse wheel events to a given one.
          *  @param policyFactory The factory that will be used to create the
          *         actual policy.
          */
         void setMouseWheelFocusPolicy (const FocusPolicyFactory& policyFactory);

      private:
         /** Returns the first node in an \c osg::NodePath that is present in the
          *  list of nodes being "observed" by this \c EventHandler. This is
          *  necessary in the cases in which the user is picking a node that is
          *  child of an added node. That's the case, for instance, of when the
          *  user adds a node read from a 3D model file returned by
          *  \c osgDB::readNodeFile().
          *  @param nodePath The node path leading to the node being queried.
          *  @returns The first in \c nodePath that as added to the list of
          *           nodes being observed.
          */
         NodePtr getObservedNode (const osg::NodePath& nodePath);

         /** Handles a \c FRAME event triggered by Producer. Signals triggered
          *  here are <tt>"MouseEnter"</tt>, <tt>"MouseLeave"</tt> and
          *  <tt>"MouseMove"</tt>.
          *  @param ea The event generated by Producer.
          */
         void handleFrameEvent (const osgGA::GUIEventAdapter& ea);

         /** Handles a \c PUSH event triggered by Producer. The only signal
          *  triggered here is <tt>"MouseDown"</tt>, but this function also does
          *  bookkeeping related to other mouse signals.
          *  @param ea The event generated by Producer.
          */
         void handlePushEvent (const osgGA::GUIEventAdapter& ea);

         /** Handles a \c RELEASE event triggered by Producer. Signals triggered
          *  here are <tt>"MouseUp"</tt>, <tt>"Click"</tt> and
          *  <tt>"DoubleClick"</tt>.
          *  @param ea The event generated by Producer.
          */
         void handleReleaseEvent (const osgGA::GUIEventAdapter& ea);

         /** Handles a \c KEYDOWN event triggered by Producer. The only signal
          *  triggered here is <tt>"KeyDown"</tt>.
          *  @param ea The event generated by Producer.
          */
         void handleKeyDownEvent (const osgGA::GUIEventAdapter& ea);

         /** Handles a \c KEYUP event triggered by Producer. The only signal
          *  triggered here is <tt>"KeyUp"</tt>.
          *  @param ea The event generated by Producer.
          */
         void handleKeyUpEvent (const osgGA::GUIEventAdapter& ea);

         /** Handles a \c SCROLL event triggered by Producer. The signal
          *  triggered here are <tt>"ScrollUp"</tt> and <tt>"ScrollDown"</tt>.
          *  @param ea The event generated by Producer.
          */
         void handleScrollEvent (const osgGA::GUIEventAdapter& ea);

         /// The viewer viewing the nodes.
         osgProducer::Viewer& viewer_;

         /** If this is \c true, faces back-facing the viewer will be ignored
          *  while picking.
          */
         bool ignoreBackFaces_;

         /** The list of root nodes used when picking.
          *  @see setPickingRoots for a discussion on how this is used and why
          *       this is necessary.
          */
         std::vector<NodePtr> pickingRoots_;

         /** The values to be returned by the \c handle() method, depending on
          *  the event type it is handling. Values are not initialized, meaning
          *  that \c handle(), by default, returns \c false for all event types.
          *  @todo Implement a method like \c setHandleReturnValue(), so that
          *        the user can configure this.
          */
         std::map <osgGA::GUIEventAdapter::EventType, bool> handleReturnValues_;

         /// Type mapping a signal name to the signal object.
         typedef std::map <std::string, SignalPtr> SignalCollection_t;

         /// Type mapping nodes to the collection of signals associated to it.
         typedef std::map <NodePtr, SignalCollection_t > SignalsMap_t;

         /** Structure containing all the signals used by this \c EventHandler.
          *  It can be used with a syntax like this:
          *  <tt>signals_[node]["MouseMove"]->connect(&MyHandler);</tt>
          */
         SignalsMap_t signals_;

         /** The \c osgUtil::Hit structure for the node currently under the
          *  mouse pointer. (Respecting the \c ignoreBackFaces_ flag.)
          */
         osgUtil::Hit hitUnderMouse_;

         //
         // For "MouseEnter", "MouseLeave", "MouseMove"
         //

         /// The node currently under the mouse pointer.
         NodePtr nodeUnderMouse_;

         /** The position (in the object coordinate system) of
          *  \c nodeUnderMouse_ currently under the mouse pointer.
          */
         osg::Vec3 positionUnderMouse_;

         //
         // For "Click" and "DoubleClick"
         //

         /// The buttons of a mouse.
         enum MouseButton
         {
            LEFT_MOUSE_BUTTON,   ///< The left button.
            MIDDLE_MOUSE_BUTTON, ///< The middle button.
            RIGHT_MOUSE_BUTTON,  ///< The right button.
            MOUSE_BUTTON_COUNT   ///< The number of buttons in a mouse.
         };

         /** Returns the mouse button used in the \c osgGA::GUIEventAdapter
          *  passed as parameter.
          */
         MouseButton getMouseButton (const osgGA::GUIEventAdapter& ea);

         /** An array indicating (for every mouse button) which was the node
          *  that received the last mouse down event. This is used to identify
          *  clicks.
          */
         NodePtr nodeThatGotMouseDown_[MOUSE_BUTTON_COUNT];

         /** An array indicating (for every mouse button) which was the node
          *  that received the last click event. This is used to identify double
          *  clicks.
          */
         NodePtr nodeThatGotClick_[MOUSE_BUTTON_COUNT];

         /** An array indicating (for every mouse button) the time at which the
          *  last click event has happened. This is used to identify double
          *  clicks.
          */
         double timeOfLastClick_[MOUSE_BUTTON_COUNT];

         //
         // For "KeyUp" and "KeyDown"
         //

         /// The node receiving keyboard events.
         NodePtr kbdFocus_;

         /// The focus policy for keyboard-related events.
         FocusPolicyPtr kbdFocusPolicy_;

         //
         // For "MouseWheelUp" and "MouseWheelDown"
         //

         /// The node receiving mouse wheel events.
         NodePtr wheelFocus_;

         /// The focus policy for mouse wheel-related events.
         FocusPolicyPtr wheelFocusPolicy_;
   };

} // namespace OSGUIsh

#endif // _GUISH_EVENT_HANDLER_HPP_
<commit_msg>Documented the glitch concerning the call to 'osgProducer::Viewer::setSceneData()', the construction of 'OSGUIsh::EventHandler' and the default picking root.<commit_after>/******************************************************************************\
* EventHandler.hpp                                                             *
* An event handler providing GUI-like events                                   *
*                                                                              *
*                                                                              *
* Copyright (C) 2006 by Leandro Motta Barros.                                  *
*                                                                              *
* This program is distributed under the OpenSceneGraph Public License. You     *
* should have received a copy of it with the source distribution, in a file    *
* named 'COPYING.txt'.                                                         *
\******************************************************************************/

#ifndef _GUISH_EVENT_HANDLER_HPP_
#define _GUISH_EVENT_HANDLER_HPP_

#include <boost/signal.hpp>
#include <osgProducer/Viewer>
#include <OSGUIsh/FocusPolicy.hpp>
#include <OSGUIsh/ManualFocusPolicy.hpp>

namespace OSGUIsh
{
   /** A \c struct grouping parameters passed to event handlers. Future versions
    *  of OSGUish may add more members here if necessary without breaking
    *  existing user code.
    *  @note Be aware that, in the general case,
    *        <tt>hit.getNodePath().back() != node.get()</tt>. \c hit contains
    *        the actual, "low level" hit, while \c node contains the node
    *        registered with OSGUish. For instance, suppose  you register a
    *        car node, that has a car body node and four wheel nodes as
    *        subnodes. \c node will always be the whole car, while \c hit will
    *        be the "car body" or one of the "wheels".
    */
   struct HandlerParams
   {
      public:
         /// Convenience constructor.
         HandlerParams (NodePtr nodeParam,
                        const osgGA::GUIEventAdapter& eventParam,
                        const osgUtil::Hit& hitParam)
            : node(nodeParam), event(eventParam), hit(hitParam)
         { }

         /// The node generating the event.
         NodePtr node;

         /** The event data, as passed by OSG. Here you can find many useful
          *  information, like "which mouse button was pressed".
          */
         const osgGA::GUIEventAdapter& event;

         /** The \c osgUtil::Hit for the node that was under the mouse pointer
          *  when the event was generated.
          *  @note Notice that, in some cases, the \c osgUtil::Hit for the node
          *        under the mouse pointer doesn't really have something to do
          *        with the event being handled. For example, if the event is a
          *        <tt>KeyUp</tt> and the focus policy is not the "node under
          *        mouse has focus" policy, than the hit will not be related to
          *        the node generating the event.
          *
Also, in cases like the above, the hit may even be
          *        invalid, since, perhaps, there will not be any registered
          *        node under the mouse pointer.
          */
         const osgUtil::Hit& hit;
   };

   /** An event handler providing GUI-like events for nodes. The \c EventHandler
    *  has an internal list of nodes being "observed". Every observed node has a
    *  collection of signals associated to it. These signals represent the
    *  events that can be generated for the node.
    */
   class EventHandler: public osgGA::GUIEventHandler
   {
      public:
         /** Constructs an \c EventHandler. The constructor will set the picking
          *  root to \c viewer.getSceneSceneData(). So, if you want to use this
          *  default value, call setSceneData() on the viewer before passing it
          *  to this constructor.
          *  @param viewer The viewer used to view the scene graph. This used
          *         for calling its \c computeIntersections() method.
          *  @param kbdPolicyFactory The factory that will be used to create the
          *         \c FocusPolicy used to automatically set the focus for
          *         keyboard events.
          *  @param wheelPolicyFactory The factory that will be used to create
          *         the \c FocusPolicy used to automatically set the focus for
          *         mouse wheel events.
          *  @see setPickingRoots for a way to manually set the picking roots
          *       (and also for an explanation on what are these "picking roots"
          *       after all).
          *  @see setPickingRoot for another way to manually set the picking
          *       roots.
          */
         EventHandler (osgProducer::Viewer& viewer,
                       const FocusPolicyFactory& kbdPolicyFactory =
                       FocusPolicyFactoryMason<ManualFocusPolicy>(),
                       const FocusPolicyFactory& wheelPolicyFactory =
                       FocusPolicyFactoryMason<ManualFocusPolicy>());

         /** Handles upcoming events (overloads virtual method).
          *  @return See \c handleReturnValues_ please.
          */
         bool handle (const osgGA::GUIEventAdapter& ea,
                      osgGA::GUIActionAdapter&);

         /** Sets the list of root nodes used when picking.
          *
This deserves some words: when using multiple
          *  <tt>osg::CameraNode</tt>s (in particular when using HUDs), picking
          *  in OSG can be problematic. The details of this problem are not
          *  important here (basically, we don't have control on the relative
          *  "z-order" of objects in different <tt>CameraNode</tt>s). But it is
          *  important to know that, if we want to pick objects in different
          *  camera nodes, we may have some unpredictable results.
          *
So, what's the solution? Actually, there is no solution. At
          *  least, not an easy one. So, OSGUIsh uses a list of root nodes when
          *  picking, as a way to offer some control to its users.
          *
Suppose, for instance, that you want to pick both in a group of
          *  objects and in a HUD. By default, OSGUIsh will pick from the root
          *  of the whole scene (objects and HUD), which (as described above)
          *  will not work. So, you call \c setPickingRoots() passing two nodes:
          *  first the HUD, second the group of objects.
          *
Once you do this, OSGUIsh will start picking in two stages.
          *  First, it will try picking the HUD. If it hits something in the
          *  HUD, that hit will be used. If not, OSGUIsh will try picking the
          *  group of objects.
          */
         void setPickingRoots (std::vector<NodePtr> newRoot);

         /** Sets the root used by OSGUIsh when picking.
          *  @see setPickingRoots for a longer discussion on how OSGUIsh
          *       performs picking (you can set more than one root, for
          *       example).
          */
         void setPickingRoot (NodePtr newRoot);

         /** A type representing a signal used in OSGUIsh. This signal returns
          *  nothing and takes a \c HandlerParams, which packs all relevant data
          *  for an event handler function.
          */
         typedef boost::signal<void (HandlerParams&)> Signal_t;

         /// A (smart) pointer to a \c Signal_t;
         typedef boost::shared_ptr<Signal_t> SignalPtr;

         /** Adds a given node to the list of nodes being "observed" by this
          *  \c EventHandler. In other words, signals for this node will be
          *  triggered from this call on.
          *  @param node The node that will be added to this \c EventHandler.
          */
         void addNode (const NodePtr node);

         /** Returns a signal associated with a given node. This is typically
          *  used to call \c connect() on the returned signal.
          *  @param node The desired node.
          *  @param signal The desired signal. Valid signals are
          *         <tt>"MouseEnter"</tt>, <tt>"MouseLeave"</tt>,
          *         <tt>"MouseMove"</tt>, <tt>"MouseDown"</tt>,
          *         <tt>"MouseUp"</tt>, <tt>"Click"</tt>,
          *         <tt>"DoubleClick"</tt>, <tt>"MouseWheelUp"</tt>,
          *         <tt>"MouseWheelDown"</tt>, <tt>"KeyUp"</tt> and
          *         <tt>"KeyDown"</tt>.
          */
         SignalPtr getSignal (const NodePtr node, const std::string& signal);

         /** Ignores or stops to ignore faces that are back-facing the viewer
          *  when picking. It may be useful to ignore back faces when backface
          *  culling is enabled.
          *  @param ignore If \c true, back faces will be ignored when picking.
          *         If \c false, back faces will be considered when piking.
          */
         void ignoreBackFaces (bool ignore = true)
         { ignoreBackFaces_ = ignore; }

         /// Sets the node that will receive keyboard events.
         void setKeyboardFocus (const NodePtr node);

         /// Sets the node that will receive mouse wheel events.
         void setMouseWheelFocus (const NodePtr node);

         /** Sets the focus policy for keyboard events to a given one.
          *  @param policyFactory The factory that will be used to create the
          *         actual policy.
          */
         void setKeyboardFocusPolicy (const FocusPolicyFactory& policyFactory);

         /** Sets the focus policy for mouse wheel events to a given one.
          *  @param policyFactory The factory that will be used to create the
          *         actual policy.
          */
         void setMouseWheelFocusPolicy (const FocusPolicyFactory& policyFactory);

      private:
         /** Returns the first node in an \c osg::NodePath that is present in the
          *  list of nodes being "observed" by this \c EventHandler. This is
          *  necessary in the cases in which the user is picking a node that is
          *  child of an added node. That's the case, for instance, of when the
          *  user adds a node read from a 3D model file returned by
          *  \c osgDB::readNodeFile().
          *  @param nodePath The node path leading to the node being queried.
          *  @returns The first in \c nodePath that as added to the list of
          *           nodes being observed.
          */
         NodePtr getObservedNode (const osg::NodePath& nodePath);

         /** Handles a \c FRAME event triggered by Producer. Signals triggered
          *  here are <tt>"MouseEnter"</tt>, <tt>"MouseLeave"</tt> and
          *  <tt>"MouseMove"</tt>.
          *  @param ea The event generated by Producer.
          */
         void handleFrameEvent (const osgGA::GUIEventAdapter& ea);

         /** Handles a \c PUSH event triggered by Producer. The only signal
          *  triggered here is <tt>"MouseDown"</tt>, but this function also does
          *  bookkeeping related to other mouse signals.
          *  @param ea The event generated by Producer.
          */
         void handlePushEvent (const osgGA::GUIEventAdapter& ea);

         /** Handles a \c RELEASE event triggered by Producer. Signals triggered
          *  here are <tt>"MouseUp"</tt>, <tt>"Click"</tt> and
          *  <tt>"DoubleClick"</tt>.
          *  @param ea The event generated by Producer.
          */
         void handleReleaseEvent (const osgGA::GUIEventAdapter& ea);

         /** Handles a \c KEYDOWN event triggered by Producer. The only signal
          *  triggered here is <tt>"KeyDown"</tt>.
          *  @param ea The event generated by Producer.
          */
         void handleKeyDownEvent (const osgGA::GUIEventAdapter& ea);

         /** Handles a \c KEYUP event triggered by Producer. The only signal
          *  triggered here is <tt>"KeyUp"</tt>.
          *  @param ea The event generated by Producer.
          */
         void handleKeyUpEvent (const osgGA::GUIEventAdapter& ea);

         /** Handles a \c SCROLL event triggered by Producer. The signal
          *  triggered here are <tt>"ScrollUp"</tt> and <tt>"ScrollDown"</tt>.
          *  @param ea The event generated by Producer.
          */
         void handleScrollEvent (const osgGA::GUIEventAdapter& ea);

         /// The viewer viewing the nodes.
         osgProducer::Viewer& viewer_;

         /** If this is \c true, faces back-facing the viewer will be ignored
          *  while picking.
          */
         bool ignoreBackFaces_;

         /** The list of root nodes used when picking.
          *  @see setPickingRoots for a discussion on how this is used and why
          *       this is necessary.
          */
         std::vector<NodePtr> pickingRoots_;

         /** The values to be returned by the \c handle() method, depending on
          *  the event type it is handling. Values are not initialized, meaning
          *  that \c handle(), by default, returns \c false for all event types.
          *  @todo Implement a method like \c setHandleReturnValue(), so that
          *        the user can configure this.
          */
         std::map <osgGA::GUIEventAdapter::EventType, bool> handleReturnValues_;

         /// Type mapping a signal name to the signal object.
         typedef std::map <std::string, SignalPtr> SignalCollection_t;

         /// Type mapping nodes to the collection of signals associated to it.
         typedef std::map <NodePtr, SignalCollection_t > SignalsMap_t;

         /** Structure containing all the signals used by this \c EventHandler.
          *  It can be used with a syntax like this:
          *  <tt>signals_[node]["MouseMove"]->connect(&MyHandler);</tt>
          */
         SignalsMap_t signals_;

         /** The \c osgUtil::Hit structure for the node currently under the
          *  mouse pointer. (Respecting the \c ignoreBackFaces_ flag.)
          */
         osgUtil::Hit hitUnderMouse_;

         //
         // For "MouseEnter", "MouseLeave", "MouseMove"
         //

         /// The node currently under the mouse pointer.
         NodePtr nodeUnderMouse_;

         /** The position (in the object coordinate system) of
          *  \c nodeUnderMouse_ currently under the mouse pointer.
          */
         osg::Vec3 positionUnderMouse_;

         //
         // For "Click" and "DoubleClick"
         //

         /// The buttons of a mouse.
         enum MouseButton
         {
            LEFT_MOUSE_BUTTON,   ///< The left button.
            MIDDLE_MOUSE_BUTTON, ///< The middle button.
            RIGHT_MOUSE_BUTTON,  ///< The right button.
            MOUSE_BUTTON_COUNT   ///< The number of buttons in a mouse.
         };

         /** Returns the mouse button used in the \c osgGA::GUIEventAdapter
          *  passed as parameter.
          */
         MouseButton getMouseButton (const osgGA::GUIEventAdapter& ea);

         /** An array indicating (for every mouse button) which was the node
          *  that received the last mouse down event. This is used to identify
          *  clicks.
          */
         NodePtr nodeThatGotMouseDown_[MOUSE_BUTTON_COUNT];

         /** An array indicating (for every mouse button) which was the node
          *  that received the last click event. This is used to identify double
          *  clicks.
          */
         NodePtr nodeThatGotClick_[MOUSE_BUTTON_COUNT];

         /** An array indicating (for every mouse button) the time at which the
          *  last click event has happened. This is used to identify double
          *  clicks.
          */
         double timeOfLastClick_[MOUSE_BUTTON_COUNT];

         //
         // For "KeyUp" and "KeyDown"
         //

         /// The node receiving keyboard events.
         NodePtr kbdFocus_;

         /// The focus policy for keyboard-related events.
         FocusPolicyPtr kbdFocusPolicy_;

         //
         // For "MouseWheelUp" and "MouseWheelDown"
         //

         /// The node receiving mouse wheel events.
         NodePtr wheelFocus_;

         /// The focus policy for mouse wheel-related events.
         FocusPolicyPtr wheelFocusPolicy_;
   };

} // namespace OSGUIsh

#endif // _GUISH_EVENT_HANDLER_HPP_
<|endoftext|>


<commit_before>///
/// anax
/// Copyright (C) 2013 Miguel Martin (miguel.martin7.5@hotmail.com)
///
///
/// This software is provided 'as-is', without any express or implied warranty.
/// In no event will the authors be held liable for any damages arising from the
/// use of this software.
///
/// Permission is hereby granted, free of charge, to any person
/// obtaining a copy of this software and associated documentation files (the "Software"),
/// to deal in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// 1. The origin of this software must not be misrepresented;
///    you must not claim that you wrote the original software.
///    If you use this software in a product, an acknowledgment
///    in the product documentation would be appreciated but is not required.
///
/// 2. Altered source versions must be plainly marked as such,
///	   and must not be misrepresented as being the original software.
///
/// 3. The above copyright notice and this permission notice shall be included in
///    all copies or substantial portions of the Software.
///

#ifndef __ANAX_COMPONENTFILTER_HPP__
#define __ANAX_COMPONENTFILTER_HPP__

#include <type_traits>

#include <boost/dynamic_bitset.hpp>

#include "detail/EntityIdPool.hpp"
#include "detail/ContainerUtils.hpp"

#include "config.hpp"
#include "Component.hpp"
#include "ComponentTypeList.hpp"

namespace anax
{
	/// \brief A class used to filter out Components
	///
	/// This class was designed to be used in conjuction
	/// with systems in the entity systems. As it grants
	/// the ability to filter out entities with specific
	/// components.
	///
	/// \author Miguel Martin
	class ComponentFilter
	{
	public:

		ComponentFilter() {}
		ComponentFilter(const ComponentFilter&) = default;
		ComponentFilter(ComponentFilter&&) = default;
		ComponentFilter& operator=(const ComponentFilter&) = default;
		ComponentFilter& operator=(ComponentFilter&&) = default;

		// TODO: Documentation

		template <typename C1>
		ComponentFilter& requires()
		{
			static_assert(std::is_base_of<BaseComponent, C1>(), "C1 does not inherit from Component");

			detail::EnsureCapacity(_requiredComponentsList, C1::GetTypeId());
			_requiredComponentsList[C1::GetTypeId()] = true;

			return *this;
		}

		template <typename C1>
		ComponentFilter& requiresOneOf()
		{
			static_assert(std::is_base_of<BaseComponent, C1>(), "C1 does not inherit from Component");

			detail::EnsureCapacity(_requiresOneOfComponentsList, C1::GetTypeId());
			_requiresOneOfComponentsList[C1::GetTypeId()] = true;

			return *this;
		}

		template <typename C1>
		ComponentFilter& exclude()
		{
			static_assert(std::is_base_of<BaseComponent, C1>(), "C1 does not inherit from Component");

			detail::EnsureCapacity(_excludeComponentsList, C1::GetTypeId());
			_excludeComponentsList[C1::GetTypeId()] = true;

			return *this;
		}

#ifndef ANAX_DONT_USE_VARIADIC_TEMPLATES

		template <typename C1, typename C2, typename... Components>
		ComponentFilter& requires()
		{
			requires<C1>();
			requires<C2, Components...>();

			return *this;
		}

		template <typename C1, typename C2, typename... Components>
		ComponentFilter& requiresOneOf()
		{
			requiresOneOf<C1>();
			requiresOneOf<C2, Components...>();

			return *this;
		}

		template <typename C1, typename C2, typename... Components>
		ComponentFilter& excludes()
		{
			excludes<C1>();
			excludes<C2, Components...>();

			return *this;
		}

#endif // ANAX_DONT_USE_VARIADIC_TEMPLATES

		/// Determines if a list of component types passes the filter
		/// \param componentTypeList The list of component types you wish to check if it passes through the filter
		/// \return true if the list of component types passes through the filter (i.e. is valid)
		bool doesPassFilter(const ComponentTypeList& componentTypeList) const;

		/// Clears the filter
		void clear();

	private:

		/// A list of component types that are required
		ComponentTypeList _requiredComponentsList;

		/// A list of component types that are required
		/// at least once
		ComponentTypeList _requiresOneOfComponentsList;

		/// A list of component types that must be excluded
		ComponentTypeList _excludeComponentsList;
	};
}

#endif // __ANAX_COMPONENTFILTER_HPP__<commit_msg>Forgot to add s to exclude method in ComponentFilter<commit_after>///
/// anax
/// Copyright (C) 2013 Miguel Martin (miguel.martin7.5@hotmail.com)
///
///
/// This software is provided 'as-is', without any express or implied warranty.
/// In no event will the authors be held liable for any damages arising from the
/// use of this software.
///
/// Permission is hereby granted, free of charge, to any person
/// obtaining a copy of this software and associated documentation files (the "Software"),
/// to deal in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// 1. The origin of this software must not be misrepresented;
///    you must not claim that you wrote the original software.
///    If you use this software in a product, an acknowledgment
///    in the product documentation would be appreciated but is not required.
///
/// 2. Altered source versions must be plainly marked as such,
///	   and must not be misrepresented as being the original software.
///
/// 3. The above copyright notice and this permission notice shall be included in
///    all copies or substantial portions of the Software.
///

#ifndef __ANAX_COMPONENTFILTER_HPP__
#define __ANAX_COMPONENTFILTER_HPP__

#include <type_traits>

#include <boost/dynamic_bitset.hpp>

#include "detail/EntityIdPool.hpp"
#include "detail/ContainerUtils.hpp"

#include "config.hpp"
#include "Component.hpp"
#include "ComponentTypeList.hpp"

namespace anax
{
	/// \brief A class used to filter out Components
	///
	/// This class was designed to be used in conjuction
	/// with systems in the entity systems. As it grants
	/// the ability to filter out entities with specific
	/// components.
	///
	/// \author Miguel Martin
	class ComponentFilter
	{
	public:

		ComponentFilter() {}
		ComponentFilter(const ComponentFilter&) = default;
		ComponentFilter(ComponentFilter&&) = default;
		ComponentFilter& operator=(const ComponentFilter&) = default;
		ComponentFilter& operator=(ComponentFilter&&) = default;

		// TODO: Documentation

		template <typename C1>
		ComponentFilter& requires()
		{
			static_assert(std::is_base_of<BaseComponent, C1>(), "C1 does not inherit from Component");

			detail::EnsureCapacity(_requiredComponentsList, C1::GetTypeId());
			_requiredComponentsList[C1::GetTypeId()] = true;

			return *this;
		}

		template <typename C1>
		ComponentFilter& requiresOneOf()
		{
			static_assert(std::is_base_of<BaseComponent, C1>(), "C1 does not inherit from Component");

			detail::EnsureCapacity(_requiresOneOfComponentsList, C1::GetTypeId());
			_requiresOneOfComponentsList[C1::GetTypeId()] = true;

			return *this;
		}

		template <typename C1>
		ComponentFilter& excludes()
		{
			static_assert(std::is_base_of<BaseComponent, C1>(), "C1 does not inherit from Component");

			detail::EnsureCapacity(_excludeComponentsList, C1::GetTypeId());
			_excludeComponentsList[C1::GetTypeId()] = true;

			return *this;
		}

#ifndef ANAX_DONT_USE_VARIADIC_TEMPLATES

		template <typename C1, typename C2, typename... Components>
		ComponentFilter& requires()
		{
			requires<C1>();
			requires<C2, Components...>();

			return *this;
		}

		template <typename C1, typename C2, typename... Components>
		ComponentFilter& requiresOneOf()
		{
			requiresOneOf<C1>();
			requiresOneOf<C2, Components...>();

			return *this;
		}

		template <typename C1, typename C2, typename... Components>
		ComponentFilter& excludes()
		{
			excludes<C1>();
			excludes<C2, Components...>();

			return *this;
		}

#endif // ANAX_DONT_USE_VARIADIC_TEMPLATES

		/// Determines if a list of component types passes the filter
		/// \param componentTypeList The list of component types you wish to check if it passes through the filter
		/// \return true if the list of component types passes through the filter (i.e. is valid)
		bool doesPassFilter(const ComponentTypeList& componentTypeList) const;

		/// Clears the filter
		void clear();

	private:

		/// A list of component types that are required
		ComponentTypeList _requiredComponentsList;

		/// A list of component types that are required
		/// at least once
		ComponentTypeList _requiresOneOfComponentsList;

		/// A list of component types that must be excluded
		ComponentTypeList _excludeComponentsList;
	};
}

#endif // __ANAX_COMPONENTFILTER_HPP__<|endoftext|>


<commit_before>#pragma once
#include <utility>
#include <type_traits>
#include <archie/meta/static_constexpr_storage.hpp>
#include <archie/fused/if_t.hpp>

namespace archie {
namespace detail {
  template <typename...>
  struct to_function_pointer_;

  template <typename R, typename... Args>
  struct to_function_pointer_<R(Args...)> {
    using type = R (*)(Args...);

    template <typename T>
    type operator()(T&& t) const {
      return fused::if_(std::is_convertible<std::decay_t<T>, type>{},
                        [](auto&& x) -> type { return std::forward<decltype(x)>(x); },
                        [](auto&& x) -> type {
                          using ObjT = std::decay_t<decltype(x)>;
                          static_assert(std::is_empty<ObjT>::value &&
                                            std::is_trivially_constructible<ObjT>::value,
                                        "");
                          return [](Args... args) {
                            return std::add_const_t<ObjT>{}(std::forward<Args>(args)...);
                          };
                        })(std::forward<T>(t));
    }
  };
}

template <typename...>
struct pure_function;

template <typename R, typename... Args>
struct pure_function<R(Args...)> {
  using type = R (*)(Args...);

  pure_function() = default;

  template <typename T>
  explicit pure_function(T t)
      : fptr(meta::instance<detail::to_function_pointer_<R(Args...)>>()(t)) {}

  template <typename T>
  pure_function& operator=(T t) {
    fptr = meta::instance<detail::to_function_pointer_<R(Args...)>>()(t);
    return *this;
  }

  template <typename... U>
  auto operator()(U&&... u) const {
    return (*fptr)(std::forward<U>(u)...);
  }

  explicit operator bool() const { return fptr != nullptr; }
  operator type() const { return fptr; }

private:
  type fptr = nullptr;
};
}
<commit_msg>decltype(auto)<commit_after>#pragma once
#include <utility>
#include <type_traits>
#include <archie/meta/static_constexpr_storage.hpp>
#include <archie/fused/if_t.hpp>

namespace archie {
namespace detail {
  template <typename...>
  struct to_function_pointer_;

  template <typename R, typename... Args>
  struct to_function_pointer_<R(Args...)> {
    using type = R (*)(Args...);

    template <typename T>
    type operator()(T&& t) const {
      return fused::if_(std::is_convertible<std::decay_t<T>, type>{},
                        [](auto&& x) -> type { return std::forward<decltype(x)>(x); },
                        [](auto&& x) -> type {
                          using ObjT = std::decay_t<decltype(x)>;
                          static_assert(std::is_empty<ObjT>::value &&
                                            std::is_trivially_constructible<ObjT>::value,
                                        "");
                          return [](Args... args) {
                            return std::add_const_t<ObjT>{}(std::forward<Args>(args)...);
                          };
                        })(std::forward<T>(t));
    }
  };
}

template <typename...>
struct pure_function;

template <typename R, typename... Args>
struct pure_function<R(Args...)> {
  using type = R (*)(Args...);

  pure_function() = default;

  template <typename T>
  explicit pure_function(T t)
      : fptr(meta::instance<detail::to_function_pointer_<R(Args...)>>()(t)) {}

  template <typename T>
  pure_function& operator=(T t) {
    fptr = meta::instance<detail::to_function_pointer_<R(Args...)>>()(t);
    return *this;
  }

  template <typename... U>
  decltype(auto) operator()(U&&... u) const {
    return (*fptr)(std::forward<U>(u)...);
  }

  explicit operator bool() const { return fptr != nullptr; }
  operator type() const { return fptr; }

private:
  type fptr = nullptr;
};
}
<|endoftext|>


<commit_before>#include <vector>
#include <string>
#include "blib/bun/CppTypeToSQLString.hpp"

namespace blib{
    namespace bun{
        namespace __private{
            template<typename T>
            struct OneToNCreation{
                std::string parent_table(){
                    return "";
                }

                std::string table_name(){
                    return "";
                }

                std::string sql(){
                    return "";
                }

                private:
                std::string __parent_table(const std::string& /*parent_table*/){
                    return "";
                }

                std::string __table_name(const std::string& /*table-name*/){
                    return "";
                }
            }

            template<typename T>
            struct OneToNCreation<std::vector<T>>{
                std::string parent_table(){
                    return "";
                }

                std::string table_name(){
                    return "";
                }

                std::string sql(){
                    return "";
                }

                private:
                std::string __parent_table(const std::string& parent_table){
                    return "";
                }

                std::string __table_name(const std::string& /*table-name*/){
                    return "";
                }
            }
        }
    }
}<commit_msg>Adding some more changes<commit_after>#include <vector>
#include <string>
#include "blib/bun/CppTypeToSQLString.hpp"

namespace blib{
    namespace bun{
        namespace __private{
            template<typename T>
            struct NxNMappingTables{
                static std::string base_table_name();
                static std::string table_name();
            }

            template<typename T>
            struct OneToNCreationSql{
                static std::string sql(){
                    return "";
                }
            }

            template<typename T>
            struct OneToNCreationSql<std::vector<T>>{
                static std::string const& table_name(){
                    static const std::string table_name = NxNMappingTables<std::vector<T>>::base_table_name() + "_" + NxNMappingTables<std::vector<T>>::table_name()
                    return table_name;
                }

                static std::string sql(){
                    static std::string sql = "CREATE TABLE '" + table_name() + "' WITH "
                }
            }
        }
    }
}<|endoftext|>


<commit_before>#pragma once

#include "clam/ClamAnalysisParams.hh"
#include "clam/Clam.hh"

#include <map>

namespace clam {

class DomainRegistry {
public:
  typedef std::map<CrabDomain::Type, clam_abstract_domain> FactoryMap;

  template<typename AbsDom>
  static bool add(CrabDomain::Type dom_ty) {
    auto &map = getFactoryMap();
    auto dom = DomainRegistry::makeTopDomain<AbsDom>();
    return map.insert({dom_ty, dom}).second;
  }

  static bool count(CrabDomain::Type dom_ty) {
    auto &map = getFactoryMap();
    return map.find(dom_ty) != map.end();
  }

  static clam_abstract_domain at(CrabDomain::Type dom_ty) {
    auto &map = getFactoryMap();
    return map.at(dom_ty);
  }

private:

  static FactoryMap& getFactoryMap() {
    static FactoryMap map;
    return map;
  }

  /* The domains instantiations happen in lib/Clam/domains */
  template<typename AbsDom>
  static clam_abstract_domain makeTopDomain();
};

#define REGISTER_DOMAIN(domain_enum_val, domain_decl)			\
  bool domain_decl ## _entry = DomainRegistry::add<domain_decl>(domain_enum_val);

} //end namespace clam
<commit_msg>refactor(RegisterAnalysis): reset stats after adding domain<commit_after>#pragma once

#include "clam/ClamAnalysisParams.hh"
#include "clam/Clam.hh"
#include "crab/support/stats.hpp"

#include <map>

namespace clam {

class DomainRegistry {
public:
  typedef std::map<CrabDomain::Type, clam_abstract_domain> FactoryMap;

  template<typename AbsDom>
  static bool add(CrabDomain::Type dom_ty) {
    auto &map = getFactoryMap();
    auto dom = DomainRegistry::makeTopDomain<AbsDom>();
    bool res = map.insert({dom_ty, dom}).second;
    crab::CrabStats::reset();
    return res;
  }

  static bool count(CrabDomain::Type dom_ty) {
    auto &map = getFactoryMap();
    return map.find(dom_ty) != map.end();
  }

  static clam_abstract_domain at(CrabDomain::Type dom_ty) {
    auto &map = getFactoryMap();
    return map.at(dom_ty);
  }

private:

  static FactoryMap& getFactoryMap() {
    static FactoryMap map;
    return map;
  }

  /* The domains instantiations happen in lib/Clam/domains */
  template<typename AbsDom>
  static clam_abstract_domain makeTopDomain();
};

#define REGISTER_DOMAIN(domain_enum_val, domain_decl)			\
  bool domain_decl ## _entry = DomainRegistry::add<domain_decl>(domain_enum_val);

} //end namespace clam
<|endoftext|>


<commit_before>#pragma once
/**
	@file
	@brief bit operation
*/
#include <assert.h>
#include <cybozu/inttype.hpp>

#if (CYBOZU_HOST == CYBOZU_HOST_INTEL)
	#if defined(_WIN32)
		#include <intrin.h>
	#elif defined(__linux__) || defined(__CYGWIN__) || defined(__clang__)
		#include <x86intrin.h>
	#elif defined(__GNUC__)
		#include <emmintrin.h>
	#endif
#endif

namespace cybozu {

namespace bit_op_local {

template<bool equalTo8>
struct Tag {};

// sizeof(T) < 8
template<>
struct Tag<false> {
	template<class T>
	static inline int bsf(T x)
	{
#if defined(_MSC_VER)
		unsigned long out;
		_BitScanForward(&out, x);
#pragma warning(suppress: 6102)
		return out;
#else
		return __builtin_ctz(x);
#endif
	}
	template<class T>
	static inline int bsr(T x)
	{
#if defined(_MSC_VER)
		unsigned long out;
		_BitScanReverse(&out, x);
#pragma warning(suppress: 6102)
		return out;
#else
		return __builtin_clz(x) ^ 0x1f;
#endif
	}
};

// sizeof(T) == 8
template<>
struct Tag<true> {
	template<class T>
	static inline int bsf(T x)
	{
#if defined(_MSC_VER) && defined(_WIN64)
		unsigned long out;
		_BitScanForward64(&out, x);
#pragma warning(suppress: 6102)
		return out;
#elif defined(__x86_64__)
		return __builtin_ctzl(x);
#else
		const uint32_t L = uint32_t(x);
		if (L) return Tag<false>::bsf(L);
		const uint32_t H = uint32_t(x >> 32);
		return Tag<false>::bsf(H) + 32;
#endif
	}
	template<class T>
	static inline int bsr(T x)
	{
#if defined(_MSC_VER) && defined(_WIN64)
		unsigned long out;
		_BitScanReverse64(&out, x);
#pragma warning(suppress: 6102)
		return out;
#elif defined(__x86_64__)
		return __builtin_clzl(x) ^ 0x3f;
#else
		const uint32_t H = uint32_t(x >> 32);
		if (H) return Tag<false>::bsr(H) + 32;
		const uint32_t L = uint32_t(x);
		return Tag<false>::bsr(L);
#endif
	}
};

} // bit_op_local

template<class T>
int bsf(T x)
{
	return bit_op_local::Tag<sizeof(T) == 8>::bsf(x);
}
template<class T>
int bsr(T x)
{
	return bit_op_local::Tag<sizeof(T) == 8>::bsr(x);
}

template<class T>
uint64_t makeBitMask64(T x)
{
	assert(x < 64);
	return (uint64_t(1) << x) - 1;
}

template<class T>
uint32_t popcnt(T x);

template<>
inline uint32_t popcnt<uint32_t>(uint32_t x)
{
#if defined(_MSC_VER)
	return static_cast<uint32_t>(_mm_popcnt_u32(x));
#else
	return static_cast<uint32_t>(__builtin_popcount(x));
#endif
}

template<>
inline uint32_t popcnt<uint64_t>(uint64_t x)
{
#if defined(_WIN64)
	return static_cast<uint32_t>(_mm_popcnt_u64(x));
#elif defined(__x86_64__)
	return static_cast<uint32_t>(__builtin_popcountl(x));
#else
	return popcnt<uint32_t>(static_cast<uint32_t>(x)) + popcnt<uint32_t>(static_cast<uint32_t>(x >> 32));
#endif
}

} // cybozu
<commit_msg>fix bsr/bsf for uint64_t on mingw<commit_after>#pragma once
/**
	@file
	@brief bit operation
*/
#include <assert.h>
#include <cybozu/inttype.hpp>

#if (CYBOZU_HOST == CYBOZU_HOST_INTEL)
	#if defined(_WIN32)
		#include <intrin.h>
	#elif defined(__linux__) || defined(__CYGWIN__) || defined(__clang__)
		#include <x86intrin.h>
	#elif defined(__GNUC__)
		#include <emmintrin.h>
	#endif
#endif

namespace cybozu {

namespace bit_op_local {

template<bool equalTo8>
struct Tag {};

// sizeof(T) < 8
template<>
struct Tag<false> {
	template<class T>
	static inline int bsf(T x)
	{
#if defined(_MSC_VER)
		unsigned long out;
		_BitScanForward(&out, x);
#pragma warning(suppress: 6102)
		return out;
#else
		return __builtin_ctz(x);
#endif
	}
	template<class T>
	static inline int bsr(T x)
	{
#if defined(_MSC_VER)
		unsigned long out;
		_BitScanReverse(&out, x);
#pragma warning(suppress: 6102)
		return out;
#else
		return __builtin_clz(x) ^ 0x1f;
#endif
	}
};

// sizeof(T) == 8
template<>
struct Tag<true> {
	template<class T>
	static inline int bsf(T x)
	{
#if defined(_MSC_VER) && defined(_WIN64)
		unsigned long out;
		_BitScanForward64(&out, x);
#pragma warning(suppress: 6102)
		return out;
#elif defined(__x86_64__)
		return __builtin_ctzll(x);
#else
		const uint32_t L = uint32_t(x);
		if (L) return Tag<false>::bsf(L);
		const uint32_t H = uint32_t(x >> 32);
		return Tag<false>::bsf(H) + 32;
#endif
	}
	template<class T>
	static inline int bsr(T x)
	{
#if defined(_MSC_VER) && defined(_WIN64)
		unsigned long out;
		_BitScanReverse64(&out, x);
#pragma warning(suppress: 6102)
		return out;
#elif defined(__x86_64__)
		return __builtin_clzll(x) ^ 0x3f;
#else
		const uint32_t H = uint32_t(x >> 32);
		if (H) return Tag<false>::bsr(H) + 32;
		const uint32_t L = uint32_t(x);
		return Tag<false>::bsr(L);
#endif
	}
};

} // bit_op_local

template<class T>
int bsf(T x)
{
	return bit_op_local::Tag<sizeof(T) == 8>::bsf(x);
}
template<class T>
int bsr(T x)
{
	return bit_op_local::Tag<sizeof(T) == 8>::bsr(x);
}

template<class T>
uint64_t makeBitMask64(T x)
{
	assert(x < 64);
	return (uint64_t(1) << x) - 1;
}

template<class T>
uint32_t popcnt(T x);

template<>
inline uint32_t popcnt<uint32_t>(uint32_t x)
{
#if defined(_MSC_VER)
	return static_cast<uint32_t>(_mm_popcnt_u32(x));
#else
	return static_cast<uint32_t>(__builtin_popcount(x));
#endif
}

template<>
inline uint32_t popcnt<uint64_t>(uint64_t x)
{
#if defined(__x86_64__)
	return static_cast<uint32_t>(__builtin_popcountll(x));
#elif defined(_WIN64)
	return static_cast<uint32_t>(_mm_popcnt_u64(x));
#else
	return popcnt<uint32_t>(static_cast<uint32_t>(x)) + popcnt<uint32_t>(static_cast<uint32_t>(x >> 32));
#endif
}

} // cybozu
<|endoftext|>


<commit_before>//
// Copyright (c) 2016 CNRS
// Authors: Joseph Mirabel from Florent Lamiraux
//
//
// This file is part of hpp-pinocchio.
// hpp-pinocchio is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// hpp-pinocchio is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details. You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-pinocchio. If not, see
// <http://www.gnu.org/licenses/>.

#ifndef HPP_PINOCCHIO_GRIPPER_HH
# define HPP_PINOCCHIO_GRIPPER_HH

# include <hpp/model/fwd.hh>
# include <hpp/model/joint.hh>

namespace hpp {
  namespace model {
    /// Definition of a robot gripper
    ///
    /// This class represent a robot gripper as a frame attached to the joint
    /// of the robot that holds the gripper.
    ///
    /// \image html figures/figure-gripper.png
    ///
    /// To graps a box-shaped object with small lengths along x and y, the
    /// gripper frame should coincide with the object frame.
    class HPP_MODEL_DLLAPI Gripper
    {
      public:
        /// Return a shared pointer to new instance
        /// \param joint joint of the robot that will hold handles,
        /// \param objectPositionInJoint object position in the the grasping
        ///        joint.
        static GripperPtr_t create (const std::string& name,
            const DevicePtr_t& device);
        {
          Gripper* ptr = new Gripper (name, device);
          GripperPtr_t shPtr (ptr);
          ptr->init (shPtr);
          return shPtr;
        }

        /// Get joint that grip
        const JointPtr_t& joint () const
        {
          return joint_;
        }

        /// Get handle position in the the Grippering joint
        const Transform3f& objectPositionInJoint () const
        {
          return device_->model()->getFramePlacement(fid_);
        }
        ///get name
        const std::string& name () const
        {
          return name_;
        }

        /// Get the clearance
        ///
        /// The clearance is a distance, from the center of the gripper and along
        /// the x-aixs, that "ensures" an object being at that distance is not
        /// colliding with this gripper.
        /// It also gives an order of magnitude of the size of the gripper.
        value_type clearance () const
        {
          return clearance_;
        }

        /// Set the clearance
        /// \sa clearance()
        void clearance (const value_type& clearance)
        {
          clearance_ = clearance;
        }

        GripperPtr_t clone () const;

        virtual std::ostream& print (std::ostream& os) const;

      protected:
        /// Constructor
        /// \param name of the gripper in the device,
        /// \param device
        /// \todo device should be of type DeviceConstPtr_t but the constructor of
        /// JointPtr_t needs a DevicePtr_t.
        Gripper (const std::string& name, const DevicePtr_t& device) :
          name_ (name),
          device_ (device),
          clearance_ (0)
        {
          fid_ = device->model()->getFrameId (name);
          joint_ = JointPtr_t (
              new Joint(device, device->model()->getFrameParent (fid)));
        }

        void init (GripperWkPtr_t weakPtr)
        {
          weakPtr_ = weakPtr;
        }

      private:
        std::string name_;
        DeviceConstPtr_t device_;
        /// Joint of the robot that holds handles.
        JointPtr_t joint_;
        se3::FrameIndex fid_;
        /// Clearance
        value_type clearance_;
        /// Weak pointer to itself
        GripperWkPtr_t weakPtr_;
    }; // class Gripper
    std::ostream& operator<< (std::ostream& os, const Gripper& gripper);
  } // namespace model
} // namespace hpp

#endif // HPP_PINOCCHIO_GRIPPER_HH
<commit_msg>Add Gripper::frameId<commit_after>//
// Copyright (c) 2016 CNRS
// Authors: Joseph Mirabel from Florent Lamiraux
//
//
// This file is part of hpp-pinocchio.
// hpp-pinocchio is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation, either version
// 3 of the License, or (at your option) any later version.
//
// hpp-pinocchio is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Lesser Public License for more details. You should have
// received a copy of the GNU Lesser General Public License along with
// hpp-pinocchio. If not, see
// <http://www.gnu.org/licenses/>.

#ifndef HPP_PINOCCHIO_GRIPPER_HH
# define HPP_PINOCCHIO_GRIPPER_HH

# include <hpp/model/fwd.hh>
# include <hpp/model/joint.hh>

namespace hpp {
  namespace model {
    /// Definition of a robot gripper
    ///
    /// This class represent a robot gripper as a frame attached to the joint
    /// of the robot that holds the gripper.
    ///
    /// \image html figures/figure-gripper.png
    ///
    /// To graps a box-shaped object with small lengths along x and y, the
    /// gripper frame should coincide with the object frame.
    class HPP_MODEL_DLLAPI Gripper
    {
      public:
        /// Return a shared pointer to new instance
        /// \param joint joint of the robot that will hold handles,
        /// \param objectPositionInJoint object position in the the grasping
        ///        joint.
        static GripperPtr_t create (const std::string& name,
            const DevicePtr_t& device);
        {
          Gripper* ptr = new Gripper (name, device);
          GripperPtr_t shPtr (ptr);
          ptr->init (shPtr);
          return shPtr;
        }

        /// Get joint to which the gripper is attached
        const JointPtr_t& joint () const
        {
          return joint_;
        }

        /// Get the frame Id of the gripper in the vector of frame of the Model
        const se3::FrameIndex& frameId () const
        {
          return fid_;
        }

        /// Get handle position in the the Grippering joint
        const Transform3f& objectPositionInJoint () const
        {
          return device_->model()->getFramePlacement(fid_);
        }
        ///get name
        const std::string& name () const
        {
          return name_;
        }

        /// Get the clearance
        ///
        /// The clearance is a distance, from the center of the gripper and along
        /// the x-aixs, that "ensures" an object being at that distance is not
        /// colliding with this gripper.
        /// It also gives an order of magnitude of the size of the gripper.
        value_type clearance () const
        {
          return clearance_;
        }

        /// Set the clearance
        /// \sa clearance()
        void clearance (const value_type& clearance)
        {
          clearance_ = clearance;
        }

        GripperPtr_t clone () const;

        virtual std::ostream& print (std::ostream& os) const;

      protected:
        /// Constructor
        /// \param name of the gripper in the device,
        /// \param device
        /// \todo device should be of type DeviceConstPtr_t but the constructor of
        /// JointPtr_t needs a DevicePtr_t.
        Gripper (const std::string& name, const DevicePtr_t& device) :
          name_ (name),
          device_ (device),
          clearance_ (0)
        {
          fid_ = device->model()->getFrameId (name);
          joint_ = JointPtr_t (
              new Joint(device, device->model()->getFrameParent (fid)));
        }

        void init (GripperWkPtr_t weakPtr)
        {
          weakPtr_ = weakPtr;
        }

      private:
        std::string name_;
        DeviceConstPtr_t device_;
        /// Joint of the robot that holds handles.
        JointPtr_t joint_;
        se3::FrameIndex fid_;
        /// Clearance
        value_type clearance_;
        /// Weak pointer to itself
        GripperWkPtr_t weakPtr_;
    }; // class Gripper
    std::ostream& operator<< (std::ostream& os, const Gripper& gripper);
  } // namespace model
} // namespace hpp

#endif // HPP_PINOCCHIO_GRIPPER_HH
<|endoftext|>


<commit_before>/*

Copyright (c) 2006, Arvid Norberg
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 author 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.

*/

#ifndef TORRENT_FILE_POOL_HPP
#define TORRENT_FILE_POOL_HPP

#ifdef _MSC_VER
#pragma warning(push, 1)
#endif

#include <boost/filesystem/path.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/shared_ptr.hpp>

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "libtorrent/file.hpp"

namespace libtorrent
{

	using boost::multi_index::multi_index_container;
	using boost::multi_index::ordered_non_unique;
	using boost::multi_index::ordered_unique;
	using boost::multi_index::indexed_by;
	using boost::multi_index::member;
	namespace pt = boost::posix_time;
	namespace fs = boost::filesystem;

	struct TORRENT_EXPORT file_pool : boost::noncopyable
	{
		file_pool(int size = 40): m_size(size) {}

		boost::shared_ptr<file> open_file(void* st, fs::path const& p, file::open_mode m);
		void release(void* st);
		void resize(int size);

	private:
		int m_size;

		struct lru_file_entry
		{
			lru_file_entry(boost::shared_ptr<file> const& f)
				: file_ptr(f)
				, last_use(pt::second_clock::universal_time()) {}
			mutable boost::shared_ptr<file> file_ptr;
			fs::path file_path;
			void* key;
			pt::ptime last_use;
			file::open_mode mode;
		};

		typedef multi_index_container<
			lru_file_entry, indexed_by<
				ordered_unique<member<lru_file_entry, fs::path
					, &lru_file_entry::file_path> >
				, ordered_non_unique<member<lru_file_entry, pt::ptime
					, &lru_file_entry::last_use> >
				, ordered_non_unique<member<lru_file_entry, void*
					, &lru_file_entry::key> >
				>
			> file_set;

		file_set m_files;
	};
}

#endif<commit_msg>added missing newline at the end of file<commit_after>/*

Copyright (c) 2006, Arvid Norberg
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 author 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.

*/

#ifndef TORRENT_FILE_POOL_HPP
#define TORRENT_FILE_POOL_HPP

#ifdef _MSC_VER
#pragma warning(push, 1)
#endif

#include <boost/filesystem/path.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/shared_ptr.hpp>

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "libtorrent/file.hpp"

namespace libtorrent
{

	using boost::multi_index::multi_index_container;
	using boost::multi_index::ordered_non_unique;
	using boost::multi_index::ordered_unique;
	using boost::multi_index::indexed_by;
	using boost::multi_index::member;
	namespace pt = boost::posix_time;
	namespace fs = boost::filesystem;

	struct TORRENT_EXPORT file_pool : boost::noncopyable
	{
		file_pool(int size = 40): m_size(size) {}

		boost::shared_ptr<file> open_file(void* st, fs::path const& p, file::open_mode m);
		void release(void* st);
		void resize(int size);

	private:
		int m_size;

		struct lru_file_entry
		{
			lru_file_entry(boost::shared_ptr<file> const& f)
				: file_ptr(f)
				, last_use(pt::second_clock::universal_time()) {}
			mutable boost::shared_ptr<file> file_ptr;
			fs::path file_path;
			void* key;
			pt::ptime last_use;
			file::open_mode mode;
		};

		typedef multi_index_container<
			lru_file_entry, indexed_by<
				ordered_unique<member<lru_file_entry, fs::path
					, &lru_file_entry::file_path> >
				, ordered_non_unique<member<lru_file_entry, pt::ptime
					, &lru_file_entry::last_use> >
				, ordered_non_unique<member<lru_file_entry, void*
					, &lru_file_entry::key> >
				>
			> file_set;

		file_set m_files;
	};
}

#endif
<|endoftext|>


<commit_before>/*

Copyright (c) 2009, Arvid Norberg
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 author 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.

*/

#ifndef TORRENT_SOCKET_IO_HPP_INCLUDED
#define TORRENT_SOCKET_IO_HPP_INCLUDED

#include "libtorrent/socket.hpp"
#include "libtorrent/address.hpp"
#include "libtorrent/io.hpp"
#include "libtorrent/error_code.hpp"
#include "libtorrent/lazy_entry.hpp"
#include <string>

namespace libtorrent
{
	TORRENT_EXPORT std::string print_address(address const& addr);
	TORRENT_EXPORT std::string print_endpoint(tcp::endpoint const& ep);
	TORRENT_EXPORT std::string print_endpoint(udp::endpoint const& ep);

	namespace detail
	{
		template<class OutIt>
		void write_address(address const& a, OutIt& out)
		{
#if TORRENT_USE_IPV6
			if (a.is_v4())
			{
#endif
				write_uint32(a.to_v4().to_ulong(), out);
#if TORRENT_USE_IPV6
			}
			else if (a.is_v6())
			{
				address_v6::bytes_type bytes
					= a.to_v6().to_bytes();
				std::copy(bytes.begin(), bytes.end(), out);
			}
#endif
		}

		template<class InIt>
		address read_v4_address(InIt& in)
		{
			unsigned long ip = read_uint32(in);
			return address_v4(ip);
		}

#if TORRENT_USE_IPV6
		template<class InIt>
		address read_v6_address(InIt& in)
		{
			typedef address_v6::bytes_type bytes_t;
			bytes_t bytes;
			for (bytes_t::iterator i = bytes.begin()
				, end(bytes.end()); i != end; ++i)
				*i = read_uint8(in);
			return address_v6(bytes);
		}
#endif

		template<class Endpoint, class OutIt>
		void write_endpoint(Endpoint const& e, OutIt& out)
		{
			write_address(e.address(), out);
			write_uint16(e.port(), out);
		}

		template<class Endpoint, class InIt>
		Endpoint read_v4_endpoint(InIt& in)
		{
			address addr = read_v4_address(in);
			int port = read_uint16(in);
			return Endpoint(addr, port);
		}

#if TORRENT_USE_IPV6
		template<class Endpoint, class InIt>
		Endpoint read_v6_endpoint(InIt& in)
		{
			address addr = read_v6_address(in);
			int port = read_uint16(in);
			return Endpoint(addr, port);
		}
#endif

		template <class EndpointType>
		void read_endpoint_list(libtorrent::lazy_entry const* n, std::vector<EndpointType>& epl)
		{
			using namespace libtorrent;
			if (n->type() != lazy_entry::list_t) return;
			for (int i = 0; i < n->list_size(); ++i)
			{
				lazy_entry const* e = n->list_at(i);
				if (e->type() != lazy_entry::string_t) return;
				if (e->string_length() < 6) continue;
				char const* in = e->string_ptr();
				if (e->string_length() == 6)
					epl.push_back(read_v4_endpoint<EndpointType>(in));
#if TORRENT_USE_IPV6
				else if (e->string_length() == 18)
					epl.push_back(read_v6_endpoint<EndpointType>(in));
#endif
			}
		}

	}

}

#endif

<commit_msg>fixed bug in write_address<commit_after>/*

Copyright (c) 2009, Arvid Norberg
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 author 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.

*/

#ifndef TORRENT_SOCKET_IO_HPP_INCLUDED
#define TORRENT_SOCKET_IO_HPP_INCLUDED

#include "libtorrent/socket.hpp"
#include "libtorrent/address.hpp"
#include "libtorrent/io.hpp"
#include "libtorrent/error_code.hpp"
#include "libtorrent/lazy_entry.hpp"
#include <string>

namespace libtorrent
{
	TORRENT_EXPORT std::string print_address(address const& addr);
	TORRENT_EXPORT std::string print_endpoint(tcp::endpoint const& ep);
	TORRENT_EXPORT std::string print_endpoint(udp::endpoint const& ep);

	namespace detail
	{
		template<class OutIt>
		void write_address(address const& a, OutIt& out)
		{
#if TORRENT_USE_IPV6
			if (a.is_v4())
			{
#endif
				write_uint32(a.to_v4().to_ulong(), out);
#if TORRENT_USE_IPV6
			}
			else if (a.is_v6())
			{
				typedef address_v6::bytes_type bytes_t;
				bytes_t bytes = a.to_v6().to_bytes();
				for (bytes_t::iterator i = bytes.begin()
					, end(bytes.end()); i != end; ++i)
					write_uint8(*i, out);
			}
#endif
		}

		template<class InIt>
		address read_v4_address(InIt& in)
		{
			unsigned long ip = read_uint32(in);
			return address_v4(ip);
		}

#if TORRENT_USE_IPV6
		template<class InIt>
		address read_v6_address(InIt& in)
		{
			typedef address_v6::bytes_type bytes_t;
			bytes_t bytes;
			for (bytes_t::iterator i = bytes.begin()
				, end(bytes.end()); i != end; ++i)
				*i = read_uint8(in);
			return address_v6(bytes);
		}
#endif

		template<class Endpoint, class OutIt>
		void write_endpoint(Endpoint const& e, OutIt& out)
		{
			write_address(e.address(), out);
			write_uint16(e.port(), out);
		}

		template<class Endpoint, class InIt>
		Endpoint read_v4_endpoint(InIt& in)
		{
			address addr = read_v4_address(in);
			int port = read_uint16(in);
			return Endpoint(addr, port);
		}

#if TORRENT_USE_IPV6
		template<class Endpoint, class InIt>
		Endpoint read_v6_endpoint(InIt& in)
		{
			address addr = read_v6_address(in);
			int port = read_uint16(in);
			return Endpoint(addr, port);
		}
#endif

		template <class EndpointType>
		void read_endpoint_list(libtorrent::lazy_entry const* n, std::vector<EndpointType>& epl)
		{
			using namespace libtorrent;
			if (n->type() != lazy_entry::list_t) return;
			for (int i = 0; i < n->list_size(); ++i)
			{
				lazy_entry const* e = n->list_at(i);
				if (e->type() != lazy_entry::string_t) return;
				if (e->string_length() < 6) continue;
				char const* in = e->string_ptr();
				if (e->string_length() == 6)
					epl.push_back(read_v4_endpoint<EndpointType>(in));
#if TORRENT_USE_IPV6
				else if (e->string_length() == 18)
					epl.push_back(read_v6_endpoint<EndpointType>(in));
#endif
			}
		}

	}

}

#endif

<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_TEXT_RENDERER_HPP
#define MAPNIK_TEXT_RENDERER_HPP

// mapnik
#include <mapnik/text/placement_finder.hpp>
#include <mapnik/image_compositing.hpp>
#include <mapnik/symbolizer_enumerations.hpp>
#include <mapnik/util/noncopyable.hpp>
// agg
#include <agg_trans_affine.h>

// freetype2
extern "C"
{
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_STROKER_H
}

namespace mapnik
{

struct glyph_t
{
    FT_Glyph image;
    detail::evaluated_format_properties const& properties;
    glyph_t(FT_Glyph image_, detail::evaluated_format_properties const& properties_)
        : image(image_), properties(properties_) {}
};

class text_renderer : private util::noncopyable
{
public:
    text_renderer (halo_rasterizer_e rasterizer,
                   composite_mode_e comp_op = src_over,
                   composite_mode_e halo_comp_op = src_over,
                   double scale_factor=1.0,
                   stroker_ptr stroker=stroker_ptr());
    void set_transform(agg::trans_affine const& transform);
    void set_halo_transform(agg::trans_affine const& halo_transform);
protected:
    using glyph_vector = std::vector<glyph_t>;
    void prepare_glyphs(glyph_positions const& positions);
    halo_rasterizer_e rasterizer_;
    composite_mode_e comp_op_;
    composite_mode_e halo_comp_op_;
    double scale_factor_;
    glyph_vector glyphs_;
    stroker_ptr stroker_;
    agg::trans_affine transform_;
    agg::trans_affine halo_transform_;
};

template <typename T>
class agg_text_renderer : public text_renderer
{
public:
    using pixmap_type = T;
    agg_text_renderer (pixmap_type & pixmap, halo_rasterizer_e rasterizer,
                       composite_mode_e comp_op = src_over,
                       composite_mode_e halo_comp_op = src_over,
                       double scale_factor = 1.0,
                       stroker_ptr stroker = stroker_ptr());
    void render(glyph_positions const& positions);
private:
    pixmap_type & pixmap_;
    void render_halo(FT_Bitmap_ *bitmap, unsigned rgba, int x, int y,
                     double halo_radius, double opacity,
                     composite_mode_e comp_op);
};

template <typename T>
class grid_text_renderer : public text_renderer
{
public:
    using pixmap_type = T;
    grid_text_renderer (pixmap_type & pixmap,
                        composite_mode_e comp_op = src_over,
                        double scale_factor = 1.0);
    void render(glyph_positions const& positions, value_integer feature_id);
private:
    pixmap_type & pixmap_;
    void render_halo_id(FT_Bitmap_ *bitmap, mapnik::value_integer feature_id, int x, int y, int halo_radius);
};

}
#endif // RENDERER_HPP
<commit_msg>formattin<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_TEXT_RENDERER_HPP
#define MAPNIK_TEXT_RENDERER_HPP

// mapnik
#include <mapnik/text/placement_finder.hpp>
#include <mapnik/image_compositing.hpp>
#include <mapnik/symbolizer_enumerations.hpp>
#include <mapnik/util/noncopyable.hpp>
// agg
#include <agg_trans_affine.h>

// freetype2
extern "C"
{
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_STROKER_H
}

namespace mapnik
{

struct glyph_t
{
    FT_Glyph image;
    detail::evaluated_format_properties const& properties;
    glyph_t(FT_Glyph image_, detail::evaluated_format_properties const& properties_)
        : image(image_), properties(properties_) {}
};

class text_renderer : private util::noncopyable
{
public:
    text_renderer (halo_rasterizer_e rasterizer,
                   composite_mode_e comp_op = src_over,
                   composite_mode_e halo_comp_op = src_over,
                   double scale_factor = 1.0,
                   stroker_ptr stroker = stroker_ptr());
    void set_transform(agg::trans_affine const& transform);
    void set_halo_transform(agg::trans_affine const& halo_transform);
protected:
    using glyph_vector = std::vector<glyph_t>;
    void prepare_glyphs(glyph_positions const& positions);
    halo_rasterizer_e rasterizer_;
    composite_mode_e comp_op_;
    composite_mode_e halo_comp_op_;
    double scale_factor_;
    glyph_vector glyphs_;
    stroker_ptr stroker_;
    agg::trans_affine transform_;
    agg::trans_affine halo_transform_;
};

template <typename T>
class agg_text_renderer : public text_renderer
{
public:
    using pixmap_type = T;
    agg_text_renderer (pixmap_type & pixmap, halo_rasterizer_e rasterizer,
                       composite_mode_e comp_op = src_over,
                       composite_mode_e halo_comp_op = src_over,
                       double scale_factor = 1.0,
                       stroker_ptr stroker = stroker_ptr());
    void render(glyph_positions const& positions);
private:
    pixmap_type & pixmap_;
    void render_halo(FT_Bitmap_ *bitmap, unsigned rgba, int x, int y,
                     double halo_radius, double opacity,
                     composite_mode_e comp_op);
};

template <typename T>
class grid_text_renderer : public text_renderer
{
public:
    using pixmap_type = T;
    grid_text_renderer (pixmap_type & pixmap,
                        composite_mode_e comp_op = src_over,
                        double scale_factor = 1.0);
    void render(glyph_positions const& positions, value_integer feature_id);
private:
    pixmap_type & pixmap_;
    void render_halo_id(FT_Bitmap_ *bitmap, mapnik::value_integer feature_id, int x, int y, int halo_radius);
};

}
#endif // RENDERER_HPP
<|endoftext|>