<commit_before>/*!
 * \file WRATHBrush.hpp
 * \brief file WRATHBrush.hpp
 *
 * Copyright 2013 by Nomovok Ltd.
 *
 * Contact: info@nomovok.com
 *
 * This Source Code Form is subject to the
 * terms of the Mozilla Public License, v. 2.0.
 * If a copy of the MPL was not distributed with
 * this file, You can obtain one at
 * http://mozilla.org/MPL/2.0/.
 *
 * \author Kevin Rogovin <kevin.rogovin@nomovok.com>
 *
 */

/*! \addtogroup Imaging
 * @{
 */

#ifndef WRATH_HEADER_BRUSH_HPP_
#define WRATH_HEADER_BRUSH_HPP_

#include "WRATHConfig.hpp"
#include "WRATHUtil.hpp"
#include "WRATHGradient.hpp"
#include "WRATHImage.hpp"
#include "WRATHGradientSourceBase.hpp"
#include "WRATHTextureCoordinateSourceBase.hpp"
#include "WRATHColorValueSource.hpp"
#include "WRATHItemDrawState.hpp"

/*!\namespace WRATHBrushBits
  Enumeration to hold bit-flags for different
  configurations of a \ref WRATHShaderBrush.
 */
namespace WRATHBrushBits
{

  /*!\enum brush_bits
    Enumeration bit values indicating
    various shader options applied
    to a brush
   */
  enum brush_bits
    {
      /*!
        Bit up indicates to add anti-aliasing logic
        to shading.
       */
      anti_alias_bit=1,

      /*!
        Bit up indicates to perform alpha test
        against image alpha
       */
      image_alpha_test_bit=2,

      /*!
        Bit up indicates to perform alpha test
        against gradient alpha
       */
      gradient_alpha_test_bit=4,

      /*!
        Bit up indicates to perform alpha
        test on const-color value
       */
      color_alpha_test_bit=8,

      /*!
        Bit up indicates to perform alpha
        test on final, cumalative, color value.
       */
      final_color_alpha_test_bit=16,

      /*!
        Bit up indicates to pre-multiply alpha
       */
      premultiply_alpha_bit=32,

      /*!
        Bit flag to indicate to discard
        a fragment if the gradient interpolate
        is less than 0.
       */
      gradient_interpolate_enforce_positive_bit=64,

      /*!
        Bit flag to indicate to discard
        a fragment if the gradient interpolate
        is greater than 1.0
       */
      gradient_interpolate_enforce_greater_than_one_bit=128,

      /*!
        Bit flag to indicate how to enforce the gradient
        interpolate requirements.
        If the bit is up, then it is enforced by making the
        gradient color as (0,0,0,0), ideal for blending.
        If the bit is down, then is enforced by discard,
        required for opaque items.
       */
      gradient_interpolate_enforce_by_blend_bit=256,

      /*!
        If bit is up, indicates to flip the image in the
        y-coordinate
       */
      flip_image_y_bit=512,
    };

  /*!\class BrushBits
    Conveniance class to hold the enumerations
    of above and provide methods to set them.
    The usual use-pattern is:
    \code
    class Foo:public BrushBits<Foo>
    {
    //...
    };
    \endcode
    \tparam T type to return for setting.
   */
  template<typename T>
  class BrushBits
  {
  public:
    /*!\fn BrushBits
      Ctor.
      \param bits value to which to initialize \var m_bits
     */
    explicit
    BrushBits(uint32_t bits=0):
      m_bits(bits),
      m_custom_bits(0)
    {}

    #define BIT_PROP(X)\
      T& X(bool b) { m_bits=WRATHUtil::apply_bit_flag(m_bits, b, X##_bit); return *static_cast<T*>(this); } \
      bool X(void) const { return m_bits & X##_bit; }

    BIT_PROP(anti_alias)
    BIT_PROP(image_alpha_test)
    BIT_PROP(gradient_alpha_test)
    BIT_PROP(color_alpha_test)
    BIT_PROP(final_color_alpha_test)
    BIT_PROP(premultiply_alpha)
    BIT_PROP(gradient_interpolate_enforce_positive)
    BIT_PROP(gradient_interpolate_enforce_greater_than_one)
    BIT_PROP(gradient_interpolate_enforce_by_blend)
    BIT_PROP(flip_image_y)

    #undef BIT_PROP

    /*!\var m_bits
      Bit field from the enumeration listed by
      \ref brush_bits
     */
    uint32_t m_bits;

    /*!\var m_custom_bits
      Bit field affecting shader construction
      with bit meanings from \ref brush_bits
     */
    uint32_t m_custom_bits;
  };
};

/*!\class WRATHShaderBrush
  A WRATHShaderBrush represents how(and if)
  to apply a gradient, texture and color, it is
  a container for essentialy GLSL shader code.
 */
class WRATHShaderBrush:public WRATHBrushBits::BrushBits<WRATHShaderBrush>
{
public:
  /*!\fn WRATHShaderBrush(const WRATHGradientSourceBase*,
                   const WRATHTextureCoordinateSourceBase*,
                   const WRATHColorValueSource*,
                   uint32_t)
    Ctor.
    \param grad value to which to initalize \ref m_gradient_source
    \param tex value to which to initalize \ref m_texture_coordinate_source
    \param color value to which to initalize \ref m_color_value_source
    \param pbits bitfield indicating shader bits, see ctor of
                 \ref WRATHBrushBits::BrushBits
   */
  WRATHShaderBrush(const WRATHGradientSourceBase *grad=NULL,
                   const WRATHTextureCoordinateSourceBase *tex=NULL,
                   const WRATHColorValueSource *color=NULL,
                   uint32_t pbits=0):
    WRATHBrushBits::BrushBits<WRATHShaderBrush>(pbits),
    m_gradient_source(grad),
    m_texture_coordinate_source(tex),
    m_color_value_source(color)
  {}

  /*!\fn WRATHShaderBrush(uint32_t)
    Ctor, \ref m_gradient_source, \ref m_texture_coordinate_source
    and \ref m_color_value_source initialized as NULL.
    \param pbits bitfield indicating shader bits, see ctor of
                 \ref WRATHBrushBits::BrushBits
   */
  explicit
  WRATHShaderBrush(uint32_t pbits):
    WRATHBrushBits::BrushBits<WRATHShaderBrush>(pbits),
    m_gradient_source(NULL),
    m_texture_coordinate_source(NULL),
    m_color_value_source(NULL)
  {}

  /*!\fn WRATHShaderBrush& gradient_source
    Set \ref m_gradient_source
    \param v value to which to set \ref m_gradient_source
   */
  WRATHShaderBrush&
  gradient_source(const WRATHGradientSourceBase* v)
  {
    m_gradient_source=v;
    return *this;
  }

  /*!\fn WRATHShaderBrush& texture_coordinate_source
    Set \ref m_texture_coordinate_source
    \param v value to which to set \ref m_texture_coordinate_source
   */
  WRATHShaderBrush&
  texture_coordinate_source(const WRATHTextureCoordinateSourceBase* v)
  {
    m_texture_coordinate_source=v;
    return *this;
  }

  /*!\fn WRATHShaderBrush& color_value_source
    Set \ref m_color_value_source
    \param v value to which to set \ref m_color_value_source
   */
  WRATHShaderBrush&
  color_value_source(const WRATHColorValueSource* v)
  {
    m_color_value_source=v;
    return *this;
  }

  /*!\fn bool operator<(const WRATHShaderBrush&) const
    Comparison operator
    \param rhs value to which to compare
   */
  bool
  operator<(const WRATHShaderBrush &rhs) const;

  /*!\var m_gradient_source
    Holds the GLSL code for computing the gradient interpolate
   */
  const WRATHGradientSourceBase *m_gradient_source;

  /*!\var m_texture_coordinate_source
    Holds the GLSL code for computing the texture coordinate
   */
  const WRATHTextureCoordinateSourceBase *m_texture_coordinate_source;

  /*!\var m_color_value_source
    Holds the GLSL code for computing the color value
   */
  const WRATHColorValueSource *m_color_value_source;

  /*!\var m_draw_state
    Additional GL state needed/wanted by the shader code
    to work correctly.
   */
  WRATHSubItemDrawState m_draw_state;
};

/*!\class WRATHBrush
  A WRATHBrush represents how/if to
  apply a texture, gradient and color
  and what texture, gradient and color
  to apply.
 */
class WRATHBrush:public WRATHShaderBrush
{
public:

  /*!\fn WRATHBrush(WRATHImage*, WRATHGradient*, uint32_t)
    Ctor.
    \param pImage value to which to initialize \ref m_image
    \param pGradient value to which to initialize \ref m_gradient
    \param pbits bitfield indicating shader bits, see ctor of
                 \ref WRATHBrushBits::BrushBits
   */
  WRATHBrush(WRATHImage *pImage=NULL,
             WRATHGradient *pGradient=NULL,
             uint32_t pbits=0):
    WRATHShaderBrush(pbits),
    m_image(pImage),
    m_gradient(pGradient)
  {}

  /*!\fn WRATHBrush(WRATHGradient*, WRATHImage*, uint32_t)
    Ctor.
    \param pGradient value to which to initialize \ref m_gradient
    \param pImage value to which to initialize \ref m_image
    \param pbits bitfield indicating shader bits, see ctor of
                 \ref WRATHBrushBits::BrushBits
   */
  WRATHBrush(WRATHGradient *pGradient,
             WRATHImage *pImage=NULL,
             uint32_t pbits=0):
    WRATHShaderBrush(pbits),
    m_image(pImage),
    m_gradient(pGradient)
  {}

  /*!\fn bool image_consistent
    Returns true if \ref m_image
    value is consistent with \ref
    WRATHShaderBrush::m_texture_coordinate_source
    value, i.e. returns true if both are
    NULL or both are non-NULL
   */
  bool
  image_consistent(void) const
  {
    return bool(m_image==NULL)==bool(m_texture_coordinate_source==NULL);
  }

  /*!\fn void make_image_consistent
    Makes \ref m_image and \ref m_texture_coordinate_source
    consitent by setting both to NULL if one is already NULL.
   */
  void
  make_image_consistent(void)
  {
    m_image=(m_texture_coordinate_source!=NULL)?
      m_image:
      NULL;

    m_texture_coordinate_source=(m_image!=NULL)?
      m_texture_coordinate_source:
      NULL;
  }

  /*!\fn bool gradient_consistent
    Returns true if \ref m_gradient
    value is consistent with \ref
    WRATHShaderBrush::m_gradient_source
    value, i.e. returns true if both are
    NULL or both are non-NULL.
   */
  bool
  gradient_consistent(void) const
  {
    return bool(m_gradient==NULL)==bool(m_gradient_source==NULL);
  }

   /*!\fn void make_gradient_consistent
    Makes \ref m_gradient and \ref m_gradient_source
    consitent by setting both to NULL if one is already NULL.
   */
  void
  make_gradient_consistent(void)
  {
    m_gradient=(m_gradient_source!=NULL)?
      m_gradient:
      NULL;

    m_gradient_source=(m_gradient!=NULL)?
      m_gradient_source:
      NULL;
  }

  /*!\fn bool consistent
    Provided as a conveniance, equivalent to
    \code
    image_consistent() and gradient_consistent()
    \endcode
   */
  bool
  consistent(void) const
  {
    return image_consistent() and gradient_consistent();
  }

  /*!\fn void make_consistent
    Provided as a conveniance, equivalent to
    \code
    make_image_consistent();
    make_gradient_consistent();
    \endcode
   */
  void
  make_consistent(void)
  {
    make_gradient_consistent();
    make_image_consistent();
  }

  /*!\var m_image
    Image to apply to the brush.
   */
  WRATHImage *m_image;

  /*!\var m_gradient
    Gradient color values to apply to the brush.
   */
  WRATHGradient *m_gradient;
};

/*! @} */

#endif
<commit_msg>convenience ctor for WRATHBrush to apply set_shader_brush<commit_after>/*!
 * \file WRATHBrush.hpp
 * \brief file WRATHBrush.hpp
 *
 * Copyright 2013 by Nomovok Ltd.
 *
 * Contact: info@nomovok.com
 *
 * This Source Code Form is subject to the
 * terms of the Mozilla Public License, v. 2.0.
 * If a copy of the MPL was not distributed with
 * this file, You can obtain one at
 * http://mozilla.org/MPL/2.0/.
 *
 * \author Kevin Rogovin <kevin.rogovin@nomovok.com>
 *
 */

/*! \addtogroup Imaging
 * @{
 */

#ifndef WRATH_HEADER_BRUSH_HPP_
#define WRATH_HEADER_BRUSH_HPP_

#include "WRATHConfig.hpp"
#include "WRATHUtil.hpp"
#include "WRATHGradient.hpp"
#include "WRATHImage.hpp"
#include "WRATHGradientSourceBase.hpp"
#include "WRATHTextureCoordinateSourceBase.hpp"
#include "WRATHColorValueSource.hpp"
#include "WRATHItemDrawState.hpp"

/*!\namespace WRATHBrushBits
  Enumeration to hold bit-flags for different
  configurations of a \ref WRATHShaderBrush.
 */
namespace WRATHBrushBits
{

  /*!\enum brush_bits
    Enumeration bit values indicating
    various shader options applied
    to a brush
   */
  enum brush_bits
    {
      /*!
        Bit up indicates to add anti-aliasing logic
        to shading.
       */
      anti_alias_bit=1,

      /*!
        Bit up indicates to perform alpha test
        against image alpha
       */
      image_alpha_test_bit=2,

      /*!
        Bit up indicates to perform alpha test
        against gradient alpha
       */
      gradient_alpha_test_bit=4,

      /*!
        Bit up indicates to perform alpha
        test on const-color value
       */
      color_alpha_test_bit=8,

      /*!
        Bit up indicates to perform alpha
        test on final, cumalative, color value.
       */
      final_color_alpha_test_bit=16,

      /*!
        Bit up indicates to pre-multiply alpha
       */
      premultiply_alpha_bit=32,

      /*!
        Bit flag to indicate to discard
        a fragment if the gradient interpolate
        is less than 0.
       */
      gradient_interpolate_enforce_positive_bit=64,

      /*!
        Bit flag to indicate to discard
        a fragment if the gradient interpolate
        is greater than 1.0
       */
      gradient_interpolate_enforce_greater_than_one_bit=128,

      /*!
        Bit flag to indicate how to enforce the gradient
        interpolate requirements.
        If the bit is up, then it is enforced by making the
        gradient color as (0,0,0,0), ideal for blending.
        If the bit is down, then is enforced by discard,
        required for opaque items.
       */
      gradient_interpolate_enforce_by_blend_bit=256,

      /*!
        If bit is up, indicates to flip the image in the
        y-coordinate
       */
      flip_image_y_bit=512,
    };

  /*!\class BrushBits
    Conveniance class to hold the enumerations
    of above and provide methods to set them.
    The usual use-pattern is:
    \code
    class Foo:public BrushBits<Foo>
    {
    //...
    };
    \endcode
    \tparam T type to return for setting.
   */
  template<typename T>
  class BrushBits
  {
  public:
    /*!\fn BrushBits
      Ctor.
      \param bits value to which to initialize \var m_bits
     */
    explicit
    BrushBits(uint32_t bits=0):
      m_bits(bits),
      m_custom_bits(0)
    {}

    #define BIT_PROP(X)\
      T& X(bool b) { m_bits=WRATHUtil::apply_bit_flag(m_bits, b, X##_bit); return *static_cast<T*>(this); } \
      bool X(void) const { return m_bits & X##_bit; }

    BIT_PROP(anti_alias)
    BIT_PROP(image_alpha_test)
    BIT_PROP(gradient_alpha_test)
    BIT_PROP(color_alpha_test)
    BIT_PROP(final_color_alpha_test)
    BIT_PROP(premultiply_alpha)
    BIT_PROP(gradient_interpolate_enforce_positive)
    BIT_PROP(gradient_interpolate_enforce_greater_than_one)
    BIT_PROP(gradient_interpolate_enforce_by_blend)
    BIT_PROP(flip_image_y)

    #undef BIT_PROP

    /*!\var m_bits
      Bit field from the enumeration listed by
      \ref brush_bits
     */
    uint32_t m_bits;

    /*!\var m_custom_bits
      Bit field affecting shader construction
      with bit meanings from \ref brush_bits
     */
    uint32_t m_custom_bits;
  };
};

/*!\class WRATHShaderBrush
  A WRATHShaderBrush represents how(and if)
  to apply a gradient, texture and color, it is
  a container for essentialy GLSL shader code.
 */
class WRATHShaderBrush:public WRATHBrushBits::BrushBits<WRATHShaderBrush>
{
public:
  /*!\fn WRATHShaderBrush(const WRATHGradientSourceBase*,
                   const WRATHTextureCoordinateSourceBase*,
                   const WRATHColorValueSource*,
                   uint32_t)
    Ctor.
    \param grad value to which to initalize \ref m_gradient_source
    \param tex value to which to initalize \ref m_texture_coordinate_source
    \param color value to which to initalize \ref m_color_value_source
    \param pbits bitfield indicating shader bits, see ctor of
                 \ref WRATHBrushBits::BrushBits
   */
  WRATHShaderBrush(const WRATHGradientSourceBase *grad=NULL,
                   const WRATHTextureCoordinateSourceBase *tex=NULL,
                   const WRATHColorValueSource *color=NULL,
                   uint32_t pbits=0):
    WRATHBrushBits::BrushBits<WRATHShaderBrush>(pbits),
    m_gradient_source(grad),
    m_texture_coordinate_source(tex),
    m_color_value_source(color)
  {}

  /*!\fn WRATHShaderBrush(uint32_t)
    Ctor, \ref m_gradient_source, \ref m_texture_coordinate_source
    and \ref m_color_value_source initialized as NULL.
    \param pbits bitfield indicating shader bits, see ctor of
                 \ref WRATHBrushBits::BrushBits
   */
  explicit
  WRATHShaderBrush(uint32_t pbits):
    WRATHBrushBits::BrushBits<WRATHShaderBrush>(pbits),
    m_gradient_source(NULL),
    m_texture_coordinate_source(NULL),
    m_color_value_source(NULL)
  {}

  /*!\fn WRATHShaderBrush& gradient_source
    Set \ref m_gradient_source
    \param v value to which to set \ref m_gradient_source
   */
  WRATHShaderBrush&
  gradient_source(const WRATHGradientSourceBase* v)
  {
    m_gradient_source=v;
    return *this;
  }

  /*!\fn WRATHShaderBrush& texture_coordinate_source
    Set \ref m_texture_coordinate_source
    \param v value to which to set \ref m_texture_coordinate_source
   */
  WRATHShaderBrush&
  texture_coordinate_source(const WRATHTextureCoordinateSourceBase* v)
  {
    m_texture_coordinate_source=v;
    return *this;
  }

  /*!\fn WRATHShaderBrush& color_value_source
    Set \ref m_color_value_source
    \param v value to which to set \ref m_color_value_source
   */
  WRATHShaderBrush&
  color_value_source(const WRATHColorValueSource* v)
  {
    m_color_value_source=v;
    return *this;
  }

  /*!\fn bool operator<(const WRATHShaderBrush&) const
    Comparison operator
    \param rhs value to which to compare
   */
  bool
  operator<(const WRATHShaderBrush &rhs) const;

  /*!\var m_gradient_source
    Holds the GLSL code for computing the gradient interpolate
   */
  const WRATHGradientSourceBase *m_gradient_source;

  /*!\var m_texture_coordinate_source
    Holds the GLSL code for computing the texture coordinate
   */
  const WRATHTextureCoordinateSourceBase *m_texture_coordinate_source;

  /*!\var m_color_value_source
    Holds the GLSL code for computing the color value
   */
  const WRATHColorValueSource *m_color_value_source;

  /*!\var m_draw_state
    Additional GL state needed/wanted by the shader code
    to work correctly.
   */
  WRATHSubItemDrawState m_draw_state;
};

/*!\class WRATHBrush
  A WRATHBrush represents how/if to
  apply a texture, gradient and color
  and what texture, gradient and color
  to apply.
 */
class WRATHBrush:public WRATHShaderBrush
{
public:

  /*!\fn WRATHBrush(WRATHImage*, WRATHGradient*, uint32_t)
    Ctor.
    \param pImage value to which to initialize \ref m_image
    \param pGradient value to which to initialize \ref m_gradient
    \param pbits bitfield indicating shader bits, see ctor of
                 \ref WRATHBrushBits::BrushBits
   */
  WRATHBrush(WRATHImage *pImage=NULL,
             WRATHGradient *pGradient=NULL,
             uint32_t pbits=0):
    WRATHShaderBrush(pbits),
    m_image(pImage),
    m_gradient(pGradient)
  {}

  /*!\fn WRATHBrush(WRATHGradient*, WRATHImage*, uint32_t)
    Ctor.
    \param pGradient value to which to initialize \ref m_gradient
    \param pImage value to which to initialize \ref m_image
    \param pbits bitfield indicating shader bits, see ctor of
                 \ref WRATHBrushBits::BrushBits
   */
  WRATHBrush(WRATHGradient *pGradient,
             WRATHImage *pImage=NULL,
             uint32_t pbits=0):
    WRATHShaderBrush(pbits),
    m_image(pImage),
    m_gradient(pGradient)
  {}

  /*!\fn WRATHBrush(WRATHImage*, WRATHGradient*, uint32_t)
    Ctor.
    \tparam Node type which implement the static method set_shader_brush(WRATHShaderBrush&)
                 that sets the shader for the brush
    \param pImage value to which to initialize \ref m_image
    \param pGradient value to which to initialize \ref m_gradient
    \param pbits bitfield indicating shader bits, see ctor of
                 \ref WRATHBrushBits::BrushBits
   */
  template<typename Node>
  WRATHBrush(type_tag<Node>,
             WRATHImage *pImage=NULL,
             WRATHGradient *pGradient=NULL,
             uint32_t pbits=0):
    WRATHShaderBrush(pbits),
    m_image(pImage),
    m_gradient(pGradient)
  {
    Node::set_shader_brush(*this);
  }

  /*!\fn WRATHBrush(WRATHGradient*, WRATHImage*, uint32_t)
    Ctor.
    \tparam Node type which implement the static method set_shader_brush(WRATHShaderBrush&)
                 that sets the shader for the brush
    \param pGradient value to which to initialize \ref m_gradient
    \param pImage value to which to initialize \ref m_image
    \param pbits bitfield indicating shader bits, see ctor of
                 \ref WRATHBrushBits::BrushBits
   */
  template<typename Node>
  WRATHBrush(type_tag<Node>,
             WRATHGradient *pGradient,
             WRATHImage *pImage=NULL,
             uint32_t pbits=0):
    WRATHShaderBrush(pbits),
    m_image(pImage),
    m_gradient(pGradient)
  {
    Node::set_shader_brush(*this);
  }

  /*!\fn bool image_consistent
    Returns true if \ref m_image
    value is consistent with \ref
    WRATHShaderBrush::m_texture_coordinate_source
    value, i.e. returns true if both are
    NULL or both are non-NULL
   */
  bool
  image_consistent(void) const
  {
    return bool(m_image==NULL)==bool(m_texture_coordinate_source==NULL);
  }

  /*!\fn void make_image_consistent
    Makes \ref m_image and \ref m_texture_coordinate_source
    consitent by setting both to NULL if one is already NULL.
   */
  void
  make_image_consistent(void)
  {
    m_image=(m_texture_coordinate_source!=NULL)?
      m_image:
      NULL;

    m_texture_coordinate_source=(m_image!=NULL)?
      m_texture_coordinate_source:
      NULL;
  }

  /*!\fn bool gradient_consistent
    Returns true if \ref m_gradient
    value is consistent with \ref
    WRATHShaderBrush::m_gradient_source
    value, i.e. returns true if both are
    NULL or both are non-NULL.
   */
  bool
  gradient_consistent(void) const
  {
    return bool(m_gradient==NULL)==bool(m_gradient_source==NULL);
  }

   /*!\fn void make_gradient_consistent
    Makes \ref m_gradient and \ref m_gradient_source
    consitent by setting both to NULL if one is already NULL.
   */
  void
  make_gradient_consistent(void)
  {
    m_gradient=(m_gradient_source!=NULL)?
      m_gradient:
      NULL;

    m_gradient_source=(m_gradient!=NULL)?
      m_gradient_source:
      NULL;
  }

  /*!\fn bool consistent
    Provided as a conveniance, equivalent to
    \code
    image_consistent() and gradient_consistent()
    \endcode
   */
  bool
  consistent(void) const
  {
    return image_consistent() and gradient_consistent();
  }

  /*!\fn void make_consistent
    Provided as a conveniance, equivalent to
    \code
    make_image_consistent();
    make_gradient_consistent();
    \endcode
   */
  void
  make_consistent(void)
  {
    make_gradient_consistent();
    make_image_consistent();
  }

  /*!\var m_image
    Image to apply to the brush.
   */
  WRATHImage *m_image;

  /*!\var m_gradient
    Gradient color values to apply to the brush.
   */
  WRATHGradient *m_gradient;
};

/*! @} */

#endif
<|endoftext|>


<commit_before>#ifndef Bull_Window_hpp
#define Bull_Window_hpp

#include <memory>

#include <Bull/Core/Integer.hpp>
#include <Bull/Core/Pattern/NonCopyable.hpp>
#include <Bull/Core/String.hpp>
#include <Bull/Core/System/Export.hpp>

#include <Bull/Hardware/Joystick.hpp>
#include <Bull/Hardware/Keyboard.hpp>
#include <Bull/Hardware/Mouse.hpp>

#include <Bull/Math/Vector/Vector2.hpp>

#include <Bull/Render/Context/ContextResource.hpp>
#include <Bull/Render/Context/ContextSettings.hpp>

#include <Bull/Window/VideoMode.hpp>
#include <Bull/Window/WindowHandler.hpp>

#ifdef None
    #undef None
#endif

namespace Bull
{
    namespace prv
    {
        class WindowImpl;
        class GlContext;
    }

    class BULL_API Window : public ContextResource, public NonCopyable
    {
    public:

        /*! \brief Get the fullscreen window
         *
         * \return Return a pointer to the window in fullscreen
         *
         */
        static const Window* getFullscreen();

        struct Event
        {
            enum Type
            {
                Closed,
                Resized,
                Moved,
                KeyDown,
                KeyUp,
                MouseMoved,
                MouseButtonUp,
                MouseButtonDown,
                MouseWheel,
                LostFocus,
                GainFocus,
                JoystickButtonUp,
                JoystickButtonDown,
                JoystickMoved,
                JoystickConnected,
                JoystickDisconnected,
            };

            struct WindowResizedEvent
            {
                unsigned int width;
                unsigned int height;
            };

            struct WindowMovedEvent
            {
                int x;
                int y;
            };

            struct KeyEvent
            {
                Keyboard::Key code;
                bool          alt;
                bool          control;
                bool          shift;
                bool          system;
            };

            struct MouseMoveEvent
            {
                int x;
                int y;
            };

            struct MouseButtonEvent
            {
                Mouse::Button button;

                int x;
                int y;
            };

            struct MouseWheelEvent
            {
                Mouse::Wheel wheel;

                bool up;

                int x;
                int y;
            };

            struct JoystickConnectionEvent
            {
                Uint8 joystick;
            };

            struct JoystickMovedEvent
            {
                Uint8 joystick;
                Joystick::Axis axis;
                float position;
                float relative;
            };

            struct JoystickButtonEvent
            {
                Uint8 joystick;
                Uint8 button;
            };

            union
            {
                WindowResizedEvent      windowResize;
                WindowMovedEvent        windowMove;
                KeyEvent                key;
                MouseMoveEvent          mouseMove;
                MouseButtonEvent        mouseButton;
                MouseWheelEvent         mouseWheel;
                JoystickConnectionEvent joystickConnection;
                JoystickMovedEvent      joystickMoved;
                JoystickButtonEvent     joystickButton;
            };

            Type type;
        };

        enum Style
        {
            None        = 0x0,  /*!< The Window do not have any decoration */

            Visible     = 0x1,  /*!< The Window is visible */
            Closable    = 0x2,  /*!< The Window has a exit button */
            Minimizable = 0x4,  /*!< The Window has a minimize button */
            Maximizable = 0x8,  /*!< The Window has a maximize button */
            Resizable   = 0x16, /*!< The Window is resizable with drag&drop */

            Fullscreen  = 0x32, /*!< The Window is in full screen */

            Default     = Visible | Closable | Minimizable | Maximizable | Resizable
        };

    private:

        static Window* m_fullscreen;

    public:

        /*! \brief Default constructor
         *
         */
        Window() = default;

        /*! \brief Constructor
         *
         * \param mode  The VideoMode
         * \param title The title of the window
         * \param style The window decorations
         *
         */
        Window(const VideoMode& mode, const String& title, Uint32 style = Style::Default);

        /*! \brief Destructor
         *
         */
        virtual ~Window();

        /*! \brief Open the window. If a window was already opened, its closed
         *
         * \param mode  The VideoMode
         * \param title The title of the window
         * \param style The window decorations
         *
         * \return Return true if the window was open successfully
         *
         */
        bool open(const VideoMode& mode, const String& title, Uint32 style = Style::Default);

        /*! \brief Check if the window is open
         *
         * \return Return true if the window is open, else return false
         *
         */
        bool isOpen() const;

        /*! \brief Close the window
         *
         */
        void close();

        /*! \brief Get the first event on the stack without blocking the current thread
         *
         * \param e An event to fill
         *
         * \return Return true if the event stack was not empty, else return false
         *
         */
        bool pollEvent(Event& e);

        /*! \brief Get the first event on the stack and blocking the current thread
         *
         * \return Return the first event of the stack
         *
         */
        Event nextEvent();

        /*! \brief Enable or disable the capture of the cursor inside the window
         *
         * \param enable The state of the capture
         *
         */
        void enableCaptureCursor(bool enable = true);

        /*! \brief Hide or the cursor
         *
         * \param enable The state of the cursor
         *
         */
        void showCursor(bool enable = true);

        /*! \brief Minimize a window
         *
         */
        void minimize();

        /*! \brief Check if the window is minimized
         *
         * \return Return true if the window is minimized, false otherwise
         *
         */
        bool isMinimized() const;

        /*! \brief Maximize a window
         *
         */
        void maximize();

        /*! \brief Check if the window is maximized
         *
         * \return Return true if the window is maximized, false otherwise
         *
         */
        bool isMaximized() const;

        /*! \brief Set the window position
         *
         * \param position The new position of the window
         *
         */
        void setPosition(const Vector2I& position);

        /*! \brief Set the window position
         *
         * \param x The new position of the left side of the window in the screen
         * \param y The new position of the top of the window in the screen
         *
         */
        void setPosition(int x, int y);

        /*! \brief Get the position in the screen of the window
         *
         * \return Return the window position
         *
         */
        Vector2I getPosition() const;

        /*! \brief Set the size of the window
         *
         * \param size The new size of the window
         *
         */
        void setSize(const Vector2UI& size);

        /*! \brief Set the size of the window
         *
         * \param x The new width of the window
         * \param y The new height of the window
         *
         */
        void setSize(unsigned int x, unsigned int y);

        /*! \brief Get the size of the window
         *
         * \return Return the size of the window
         *
         */
        Vector2UI getSize() const;

        /*! \brief Set the title of the window
         *
         * \param title The new title of the window
         *
         */
        void setTitle(const String& title);

        /*! \brief Get the title of the window
         *
         * \return Return the title of the window
         *
         */
        String getTitle() const;

        /*! \brief Enable or disable the key repeat
         *
         * \param enable The state of the key repeat
         *
         */
        void enableKeyRepeat(bool enable = true);

        /*! \brief Get the state of the key repeat
         *
         * \param Return true if the key repeat is enable, false otherwise
         *
         */
        bool isKeyRepeatEnable() const;

        /*! \brief Check if the window has the focus
         *
         * \param Return true if the window has the focus, false otherwise
         *
         */
        bool hasFocus() const;

        /*! \brief Show or hide the window
         *
         * \param visible True to show the window, false to hide the window
         *
         */
        void setVisible(bool visible = true);

        /*! \brief Check if a window is in fullscreen
         *
         * \return Return true if the window is in fullscreen, false otherwise
         *
         */
        bool isFullscreen() const;

        /*! \brief Enter or leave the fullscreen mode
         *
         * \param mode The VideoMode to use
         * \param fullscreen False to leave the fullscreen mode, true to enter the fullscreen mode
         *
         * \return Return true if the switch was done successfully, false otherwise
         *
         */
        bool switchFullscreen(const VideoMode& mode = VideoMode::getCurrent(), bool fullscreen = true);

        /*! \brief Get the window system handler
         *
         * \return Return the native window system handler
         *
         */
        WindowHandler getSystemHandler() const;

    protected:

        std::unique_ptr<prv::GlContext> m_context; /*!< The OS specific implementation of the OpenGL context */

        /*! \brief Constructor
         *
         * \param mode     The VideoMode
         * \param title    The title of the window
         * \param style    The window decorations
         * \param settings Settings to use to create the OpenGL context
         *
         */
        Window(const VideoMode& mode, const String& title, Uint32 style, const ContextSettings& settings);

        /*! \brief Open the window. If a window was already opened, its closed
         *
         * \param mode     The VideoMode
         * \param title    The title of the window
         * \param style    The window decorations
         * \param settings Settings to use to create the OpenGL context
         *
         * \return Return true if the window was open successfully
         *
         */
        bool open(const VideoMode& mode, const String& title, Uint32 style, const ContextSettings& settings);

    private:

        std::unique_ptr<prv::WindowImpl> m_impl;    /*!< The OS specific implementation of the window */
    };
}

#endif // Bull_Window_hpp
<commit_msg>Remove useless undef<commit_after>#ifndef Bull_Window_hpp
#define Bull_Window_hpp

#include <memory>

#include <Bull/Core/Integer.hpp>
#include <Bull/Core/Pattern/NonCopyable.hpp>
#include <Bull/Core/String.hpp>
#include <Bull/Core/System/Export.hpp>

#include <Bull/Hardware/Joystick.hpp>
#include <Bull/Hardware/Keyboard.hpp>
#include <Bull/Hardware/Mouse.hpp>

#include <Bull/Math/Vector/Vector2.hpp>

#include <Bull/Render/Context/ContextResource.hpp>
#include <Bull/Render/Context/ContextSettings.hpp>

#include <Bull/Window/VideoMode.hpp>
#include <Bull/Window/WindowHandler.hpp>

namespace Bull
{
    namespace prv
    {
        class WindowImpl;
        class GlContext;
    }

    class BULL_API Window : public ContextResource, public NonCopyable
    {
    public:

        /*! \brief Get the fullscreen window
         *
         * \return Return a pointer to the window in fullscreen
         *
         */
        static const Window* getFullscreen();

        struct Event
        {
            enum Type
            {
                Closed,
                Resized,
                Moved,
                KeyDown,
                KeyUp,
                MouseMoved,
                MouseButtonUp,
                MouseButtonDown,
                MouseWheel,
                LostFocus,
                GainFocus,
                JoystickButtonUp,
                JoystickButtonDown,
                JoystickMoved,
                JoystickConnected,
                JoystickDisconnected,
            };

            struct WindowResizedEvent
            {
                unsigned int width;
                unsigned int height;
            };

            struct WindowMovedEvent
            {
                int x;
                int y;
            };

            struct KeyEvent
            {
                Keyboard::Key code;
                bool          alt;
                bool          control;
                bool          shift;
                bool          system;
            };

            struct MouseMoveEvent
            {
                int x;
                int y;
            };

            struct MouseButtonEvent
            {
                Mouse::Button button;

                int x;
                int y;
            };

            struct MouseWheelEvent
            {
                Mouse::Wheel wheel;

                bool up;

                int x;
                int y;
            };

            struct JoystickConnectionEvent
            {
                Uint8 joystick;
            };

            struct JoystickMovedEvent
            {
                Uint8 joystick;
                Joystick::Axis axis;
                float position;
                float relative;
            };

            struct JoystickButtonEvent
            {
                Uint8 joystick;
                Uint8 button;
            };

            union
            {
                WindowResizedEvent      windowResize;
                WindowMovedEvent        windowMove;
                KeyEvent                key;
                MouseMoveEvent          mouseMove;
                MouseButtonEvent        mouseButton;
                MouseWheelEvent         mouseWheel;
                JoystickConnectionEvent joystickConnection;
                JoystickMovedEvent      joystickMoved;
                JoystickButtonEvent     joystickButton;
            };

            Type type;
        };

        enum Style
        {
            None        = 0x0,  /*!< The Window do not have any decoration */

            Visible     = 0x1,  /*!< The Window is visible */
            Closable    = 0x2,  /*!< The Window has a exit button */
            Minimizable = 0x4,  /*!< The Window has a minimize button */
            Maximizable = 0x8,  /*!< The Window has a maximize button */
            Resizable   = 0x16, /*!< The Window is resizable with drag&drop */

            Fullscreen  = 0x32, /*!< The Window is in full screen */

            Default     = Visible | Closable | Minimizable | Maximizable | Resizable
        };

    private:

        static Window* m_fullscreen;

    public:

        /*! \brief Default constructor
         *
         */
        Window() = default;

        /*! \brief Constructor
         *
         * \param mode  The VideoMode
         * \param title The title of the window
         * \param style The window decorations
         *
         */
        Window(const VideoMode& mode, const String& title, Uint32 style = Style::Default);

        /*! \brief Destructor
         *
         */
        virtual ~Window();

        /*! \brief Open the window. If a window was already opened, its closed
         *
         * \param mode  The VideoMode
         * \param title The title of the window
         * \param style The window decorations
         *
         * \return Return true if the window was open successfully
         *
         */
        bool open(const VideoMode& mode, const String& title, Uint32 style = Style::Default);

        /*! \brief Check if the window is open
         *
         * \return Return true if the window is open, else return false
         *
         */
        bool isOpen() const;

        /*! \brief Close the window
         *
         */
        void close();

        /*! \brief Get the first event on the stack without blocking the current thread
         *
         * \param e An event to fill
         *
         * \return Return true if the event stack was not empty, else return false
         *
         */
        bool pollEvent(Event& e);

        /*! \brief Get the first event on the stack and blocking the current thread
         *
         * \return Return the first event of the stack
         *
         */
        Event nextEvent();

        /*! \brief Enable or disable the capture of the cursor inside the window
         *
         * \param enable The state of the capture
         *
         */
        void enableCaptureCursor(bool enable = true);

        /*! \brief Hide or the cursor
         *
         * \param enable The state of the cursor
         *
         */
        void showCursor(bool enable = true);

        /*! \brief Minimize a window
         *
         */
        void minimize();

        /*! \brief Check if the window is minimized
         *
         * \return Return true if the window is minimized, false otherwise
         *
         */
        bool isMinimized() const;

        /*! \brief Maximize a window
         *
         */
        void maximize();

        /*! \brief Check if the window is maximized
         *
         * \return Return true if the window is maximized, false otherwise
         *
         */
        bool isMaximized() const;

        /*! \brief Set the window position
         *
         * \param position The new position of the window
         *
         */
        void setPosition(const Vector2I& position);

        /*! \brief Set the window position
         *
         * \param x The new position of the left side of the window in the screen
         * \param y The new position of the top of the window in the screen
         *
         */
        void setPosition(int x, int y);

        /*! \brief Get the position in the screen of the window
         *
         * \return Return the window position
         *
         */
        Vector2I getPosition() const;

        /*! \brief Set the size of the window
         *
         * \param size The new size of the window
         *
         */
        void setSize(const Vector2UI& size);

        /*! \brief Set the size of the window
         *
         * \param x The new width of the window
         * \param y The new height of the window
         *
         */
        void setSize(unsigned int x, unsigned int y);

        /*! \brief Get the size of the window
         *
         * \return Return the size of the window
         *
         */
        Vector2UI getSize() const;

        /*! \brief Set the title of the window
         *
         * \param title The new title of the window
         *
         */
        void setTitle(const String& title);

        /*! \brief Get the title of the window
         *
         * \return Return the title of the window
         *
         */
        String getTitle() const;

        /*! \brief Enable or disable the key repeat
         *
         * \param enable The state of the key repeat
         *
         */
        void enableKeyRepeat(bool enable = true);

        /*! \brief Get the state of the key repeat
         *
         * \param Return true if the key repeat is enable, false otherwise
         *
         */
        bool isKeyRepeatEnable() const;

        /*! \brief Check if the window has the focus
         *
         * \param Return true if the window has the focus, false otherwise
         *
         */
        bool hasFocus() const;

        /*! \brief Show or hide the window
         *
         * \param visible True to show the window, false to hide the window
         *
         */
        void setVisible(bool visible = true);

        /*! \brief Check if a window is in fullscreen
         *
         * \return Return true if the window is in fullscreen, false otherwise
         *
         */
        bool isFullscreen() const;

        /*! \brief Enter or leave the fullscreen mode
         *
         * \param mode The VideoMode to use
         * \param fullscreen False to leave the fullscreen mode, true to enter the fullscreen mode
         *
         * \return Return true if the switch was done successfully, false otherwise
         *
         */
        bool switchFullscreen(const VideoMode& mode = VideoMode::getCurrent(), bool fullscreen = true);

        /*! \brief Get the window system handler
         *
         * \return Return the native window system handler
         *
         */
        WindowHandler getSystemHandler() const;

    protected:

        std::unique_ptr<prv::GlContext> m_context; /*!< The OS specific implementation of the OpenGL context */

        /*! \brief Constructor
         *
         * \param mode     The VideoMode
         * \param title    The title of the window
         * \param style    The window decorations
         * \param settings Settings to use to create the OpenGL context
         *
         */
        Window(const VideoMode& mode, const String& title, Uint32 style, const ContextSettings& settings);

        /*! \brief Open the window. If a window was already opened, its closed
         *
         * \param mode     The VideoMode
         * \param title    The title of the window
         * \param style    The window decorations
         * \param settings Settings to use to create the OpenGL context
         *
         * \return Return true if the window was open successfully
         *
         */
        bool open(const VideoMode& mode, const String& title, Uint32 style, const ContextSettings& settings);

    private:

        std::unique_ptr<prv::WindowImpl> m_impl;    /*!< The OS specific implementation of the window */
    };
}

#endif // Bull_Window_hpp
<|endoftext|>


<commit_before>#ifndef IPV4_5TUPLEL2IDENT_HPP
#define IPV4_5TUPLEL2IDENT_HPP

#include <cstdint>
#include <exception>
#include <functional>
#include <sstream>
#include <stdexcept>
#include <string>

#include "headers.hpp"

#include "exceptions.hpp"

template <class Packet> class IPv4_5TupleL2Ident {
public:
	struct Hasher;
	struct ConnectionID {
		uint32_t dstIP;
		uint32_t srcIP;
		uint16_t dstPort;
		uint16_t srcPort;
		uint8_t proto;

		bool operator==(const ConnectionID &c) const {
			if ((dstIP == c.dstIP) && (srcIP == c.srcIP) && (dstPort == c.dstPort) &&
				(srcPort == c.srcPort) && (proto == c.proto)) {
				return true;
			} else {
				return false;
			}
		};

		bool operator<(const ConnectionID &c) const {
			if (Hasher(this) < Hasher(c)) {
				return true;
			} else {
				return false;
			}
		};

		operator std::string() const {
			std::stringstream sstream;
			sstream << "DstIP: " << std::hex << ntohl(dstIP) << ", ";
			sstream << "SrcIP: " << std::hex << ntohl(srcIP) << ", ";
			sstream << "DstPort: " << std::dec << ntohs(dstPort) << ", ";
			sstream << "SrcPort: " << std::dec << ntohs(srcPort);
			return sstream.str();
		}

		ConnectionID(const ConnectionID &c)
			: dstIP(c.dstIP), srcIP(c.srcIP), dstPort(c.dstPort), srcPort(c.srcPort),
			  proto(c.proto){};
		ConnectionID() : dstIP(0), srcIP(0), dstPort(0), srcPort(0), proto(0){};
	};

	struct Hasher {
		// In the future, maybe we find something more random...
		size_t operator()(const ConnectionID &c) const {
			uint32_t res = c.dstPort;
			res |= c.srcPort << 16;
			res ^= c.dstIP;
			res += c.srcIP;
			res += c.proto;
			return res;
		}
	};

	static ConnectionID identify(Packet *pkt) {
		ConnectionID id;
		struct Headers::IPv4 *ip = reinterpret_cast<struct Headers::IPv4 *>(
			reinterpret_cast<uint8_t *>(pkt->getData()) + 14);
		id.dstIP = ip->dstIP;
		id.srcIP = ip->srcIP;
		id.proto = ip->proto;

		if (id.proto == IPPROTO_UDP) {
			struct Headers::Udp *udp =
				reinterpret_cast<struct Headers::Udp *>(ip->getPayload());
			id.dstPort = udp->dstPort;
			id.srcPort = udp->srcPort;
		} else if (id.proto == IPPROTO_TCP) {
			struct Headers::Tcp *tcp =
				reinterpret_cast<struct Headers::Tcp *>(ip->getPayload());
			id.dstPort = tcp->dstPort;
			id.srcPort = tcp->srcPort;
		} else {
			throw new PacketNotIdentified();
		}

		return id;
	};
};

#endif /* IPV4_5TUPLEL2IDENT_HPP */
<commit_msg>more debug info for unidentified packets<commit_after>#ifndef IPV4_5TUPLEL2IDENT_HPP
#define IPV4_5TUPLEL2IDENT_HPP

#include <cstdint>
#include <exception>
#include <functional>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <string>

#include "common.hpp"
#include "headers.hpp"

#include "exceptions.hpp"

template <class Packet> class IPv4_5TupleL2Ident {
public:
	struct Hasher;
	struct ConnectionID {
		uint32_t dstIP;
		uint32_t srcIP;
		uint16_t dstPort;
		uint16_t srcPort;
		uint8_t proto;

		bool operator==(const ConnectionID &c) const {
			if ((dstIP == c.dstIP) && (srcIP == c.srcIP) && (dstPort == c.dstPort) &&
				(srcPort == c.srcPort) && (proto == c.proto)) {
				return true;
			} else {
				return false;
			}
		};

		bool operator<(const ConnectionID &c) const {
			if (Hasher(this) < Hasher(c)) {
				return true;
			} else {
				return false;
			}
		};

		operator std::string() const {
			std::stringstream sstream;
			sstream << "DstIP: " << std::hex << ntohl(dstIP) << ", ";
			sstream << "SrcIP: " << std::hex << ntohl(srcIP) << ", ";
			sstream << "DstPort: " << std::dec << ntohs(dstPort) << ", ";
			sstream << "SrcPort: " << std::dec << ntohs(srcPort);
			return sstream.str();
		}

		ConnectionID(const ConnectionID &c)
			: dstIP(c.dstIP), srcIP(c.srcIP), dstPort(c.dstPort), srcPort(c.srcPort),
			  proto(c.proto){};
		ConnectionID() : dstIP(0), srcIP(0), dstPort(0), srcPort(0), proto(0){};
	};

	struct Hasher {
		// In the future, maybe we find something more random...
		size_t operator()(const ConnectionID &c) const {
			uint32_t res = c.dstPort;
			res |= c.srcPort << 16;
			res ^= c.dstIP;
			res += c.srcIP;
			res += c.proto;
			return res;
		}
	};

	static ConnectionID identify(Packet *pkt) {
		ConnectionID id;
		struct Headers::IPv4 *ip = reinterpret_cast<struct Headers::IPv4 *>(
			reinterpret_cast<uint8_t *>(pkt->getData()) + 14);
		id.dstIP = ip->dstIP;
		id.srcIP = ip->srcIP;
		id.proto = ip->proto;

		if (id.proto == IPPROTO_UDP) {
			struct Headers::Udp *udp =
				reinterpret_cast<struct Headers::Udp *>(ip->getPayload());
			id.dstPort = udp->dstPort;
			id.srcPort = udp->srcPort;
		} else if (id.proto == IPPROTO_TCP) {
			struct Headers::Tcp *tcp =
				reinterpret_cast<struct Headers::Tcp *>(ip->getPayload());
			id.dstPort = tcp->dstPort;
			id.srcPort = tcp->srcPort;
		} else {
#ifdef DEBUG
			std::cout << "IPv4_5TupleL2Ident::indentify() failed" << std::endl;
			std::cout << "IPv4_5TupleL2Ident::indentify() id.proto="
					  << static_cast<unsigned int>(id.proto) << std::endl;
#endif
			hexdump(pkt->getData(), pkt->getDataLen());
			throw new PacketNotIdentified();
		}

		return id;
	};
};

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


<commit_before>#include <iostream>
#include <fstream>
#include <string>

template <typename T>
struct Node
{
	Node<T>* leftNode;
	Node<T>* rightNode;
	T value;

	Node(T value)
	{
		this->value = value;
		leftNode = nullptr;
		rightNode = nullptr;
	}
};

template <typename T>
class BinarySearchTree
{
private:
	Node<T>* _root;
	void destroyTree(Node<T>* node);
	void insertElement(Node<T>* &node, const T &value);
	Node<T>* findElement(const T& value) const;

public:
	BinarySearchTree();
	~BinarySearchTree();

	T value_() const;
	int count_(const Node<T>* node) const;

	Node<T>* leftNode_() const;
	Node<T>* rightNode_() const;
	Node<T>* root() const;

	void insert(const T& value);
	bool isFound(const T& value) const;

	void infile(std::string filename);
	void outfile(Node<T>* root, std::ostream& outfile) const;
	void out(std::string filename) const;
	void paintTree(const Node<T>* node, int level) const;
	void deleteNode(const T& value);
};

template <typename T>
BinarySearchTree<T>::BinarySearchTree()
{
	_root = nullptr;
}

template <typename T>
BinarySearchTree<T>::~BinarySearchTree()
{
	destroyTree(_root);
}

template <typename T>
void BinarySearchTree<T>::destroyTree(Node<T>* node)
{
	if (!node)
		return;

	destroyTree(node->leftNode);
	destroyTree(node->rightNode);

	delete node;
}

template <typename T>
T BinarySearchTree<T>::value_() const
{
	return _root->value;
}

template <typename T>
int BinarySearchTree<T>::count_(const Node<T>* node) const
{
	if (!node)
		return 0;

	else
		return count_(node->leftNode) + count_(node->rightNode) + 1;
}

template <typename T>
Node<T>* BinarySearchTree<T>::root() const
{
	return _root;
}

template <typename T>
Node<T>* BinarySearchTree<T>::leftNode_() const
{
	return _root->leftNode;
}

template <typename T>
Node<T>* BinarySearchTree<T>::rightNode_() const
{
	return _root->rightNode;
}

template <typename T>
void BinarySearchTree<T>::insertElement(Node<T>* &node, const T &value)
{
	Node<T>* parent = nullptr;
	Node<T>* currNode = node;

	while(currNode)
	{
		if (value < currNode->value)
			currNode = currNode->leftNode;
		else if (value > currNode->value)
			currNode = currNode->rightNode;
		else
			return;
	}
	else node = new Node<T>(value);
}

template <typename T>
void BinarySearchTree<T>::insert(const T& value)
{
	insertElement(_root, value);
}

template <typename T>
Node<T>*  BinarySearchTree<T>::findElement(const T& value) const
{
	Node<T> *currNode = _root;

	while (currNode)
	{
		if (currNode->value == value)
			break;
		else
		{
			if (currNode->value < value)
				currNode = currNode->rightNode;
			else
				currNode = currNode->leftNode;
		}
	}
	return currNode;
}

template <typename T>
bool BinarySearchTree<T>::isFound(const T& value) const
{
	Node<T> *retNode = findElement(value);
	if (retNode)
		return true;
	else
		return false;
}

template <typename T>
void BinarySearchTree<T>::infile(std::string filename)
{
	std::ifstream infile;
	infile.open(filename);
	T value;
	int count;
	infile >> count;
	while (count--)
	{
		infile >> value;
		insert(value);
	}
	infile.close();
}

template <typename T>
void BinarySearchTree<T>::out(std::string filename) const
{
	std::ofstream ofile(filename);
	int count = count_(_root);
	if (!ofile)
		std::cout << "Error! Please, try again!" << std::endl;
	else
		ofile << count << " ";
	outfile(_root, ofile);
	ofile.close();
}

template <typename T>
void BinarySearchTree<T>::outfile(Node<T>* root, std::ostream& ofile) const
{
	if (!root)
		return;
	else
	{
		ofile << root->value << " ";
		outfile(root->rightNode, ofile);
		outfile(root->leftNode, ofile);
	}
}

template <typename T>
void BinarySearchTree<T>::paintTree(const Node<T>* node, int level) const
{
	if (node)
	{
		paintTree(node->rightNode, level++);
		for (int i = 0; i < level; i++)
		{
			std::cout << "-";
		}
		std::cout << node->value << std::endl;
		paintTree(node->leftNode, level++);
	}
}

template <typename T>
void BinarySearchTree<T>::deleteNode(const T& value)
{
	Node<T> *currNode = findElement(value);

	if (currNode->leftNode == nullptr && currNode->rightNode == nullptr)
	{
		if (currNode->parentNode->leftNode == currNode)
			currNode->parentNode->leftNode = nullptr;
		if (currNode->parentNode->rightNode == currNode)
			currNode->parentNode->rightNode = nullptr;
		currNode = nullptr;
	}

	else if (currNode->rightNode == nullptr)
	{
		if (currNode->parentNode->leftNode == currNode)
			currNode->parentNode->leftNode = currNode->leftNode;
		if (currNode->parentNode->rightNode == currNode)
			currNode->parentNode->rightNode = currNode->leftNode;
	}

	else
	{
		Node <T>* minNode = currNode->rightNode;
		while (minNode->leftNode)
			minNode = minNode->leftNode;
		T val = minNode->value;
		deleteNode(minNode->value);
		currNode->value = val;
	}
}
<commit_msg>Update binary_search_tree.hpp<commit_after>#include <iostream>
#include <fstream>
#include <string>

template <typename T>
struct Node
{
	Node<T>* leftNode;
	Node<T>* rightNode;
	T value;

	Node(T value)
	{
		this->value = value;
		leftNode = nullptr;
		rightNode = nullptr;
	}
};

template <typename T>
class BinarySearchTree
{
private:
	Node<T>* _root;
	void destroyTree(Node<T>* node);
	void insertElement(Node<T>* &node, const T &value);
	Node<T>* findElement(const T& value) const;

public:
	BinarySearchTree();
	~BinarySearchTree();

	T value_() const;
	int count_(const Node<T>* node) const;

	Node<T>* leftNode_() const;
	Node<T>* rightNode_() const;
	Node<T>* root() const;

	void insert(const T& value);
	bool isFound(const T& value) const;

	void infile(std::string filename);
	void outfile(Node<T>* root, std::ostream& outfile) const;
	void out(std::string filename) const;
	void paintTree(const Node<T>* node, int level) const;
};

template <typename T>
BinarySearchTree<T>::BinarySearchTree()
{
	_root = nullptr;
}

template <typename T>
BinarySearchTree<T>::~BinarySearchTree()
{
	destroyTree(_root);
}

template <typename T>
void BinarySearchTree<T>::destroyTree(Node<T>* node)
{
	if (!node)
		return;

	destroyTree(node->leftNode);
	destroyTree(node->rightNode);

	delete node;
}

template <typename T>
T BinarySearchTree<T>::value_() const
{
	return _root->value;
}

template <typename T>
int BinarySearchTree<T>::count_(const Node<T>* node) const
{
	if (!node)
		return 0;

	else
		return count_(node->leftNode) + count_(node->rightNode) + 1;
}

template <typename T>
Node<T>* BinarySearchTree<T>::root() const
{
	return _root;
}

template <typename T>
Node<T>* BinarySearchTree<T>::leftNode_() const
{
	return _root->leftNode;
}

template <typename T>
Node<T>* BinarySearchTree<T>::rightNode_() const
{
	return _root->rightNode;
}

template <typename T>
void BinarySearchTree<T>::insertElement(Node<T>* &node, const T &value)
{
	if (node)
	{
		if (value < node->value)
			insertElement(node->leftNode, value);
		else if (value > node->value)
			insertElement(node->rightNode, value);
		else
			return;
	}
	else
	{
		node = new Node<T>(value);
	}
}

template <typename T>
void BinarySearchTree<T>::insert(const T& value)
{
	insertElement(_root, value);
}

template <typename T>
Node<T>*  BinarySearchTree<T>::findElement(const T& value) const
{
	Node<T> *currNode = _root;

	while (currNode)
	{
		if (currNode->value == value)
			break;
		else
		{
			if (currNode->value < value)
				currNode = currNode->rightNode;
			else
				currNode = currNode->leftNode;
		}
	}
	return currNode;
}

template <typename T>
bool BinarySearchTree<T>::isFound(const T& value) const
{
	Node<T> *retNode = findElement(value);
	if (retNode)
		return true;
	else
		return false;
}

template <typename T>
void BinarySearchTree<T>::infile(std::string filename)
{
	std::ifstream infile;
	infile.open(filename);
	T value;
	int count;
	infile >> count;
	while (count--)
	{
		infile >> value;
		insert(value);
	}
	infile.close();
}

template <typename T>
void BinarySearchTree<T>::out(std::string filename) const
{
	std::ofstream ofile(filename);
	int count = count_(_root);
	if (!ofile)
		std::cout << "Error! Please, try again!" << std::endl;
	else
		ofile << count << " ";
	outfile(_root, ofile);
	ofile.close();
}

template <typename T>
void BinarySearchTree<T>::outfile(Node<T>* root, std::ostream& ofile) const
{
	if (!root)
		return;
	else
	{
		ofile << root->value << " ";
		outfile(root->rightNode, ofile);
		outfile(root->leftNode, ofile);
	}
}

template <typename T>
void BinarySearchTree<T>::paintTree(const Node<T>* node, int level) const
{
	if (node)
	{
		paintTree(node->rightNode, level++);
		for (int i = 0; i < level; i++)
		{
			std::cout << "-";
		}
		std::cout << node->value << std::endl;
		paintTree(node->leftNode, level++);
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2014, LAAS-CNRS
// Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
//
// This file is part of hpp-core.
// hpp-core 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-core 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-core. If not, see <http://www.gnu.org/licenses/>.

#ifndef HPP_CORE_INEQUALITY_HH
# define HPP_CORE_INEQUALITY_HH

# include <hpp/core/fwd.hh>
# include <hpp/core/config.hh>

namespace hpp {
  namespace core {
    /// Abstract class defining the comparison for a function value
    /// and doing a saturation, necessary for inequality constraint.
    /// used to compare two vector.
    /// They are used in ConfigProjector to implement inequality
    /// constraint.
    class Inequality
    {
      public:
        /// Return the result of the comparison.
        /// \param[in,out] value the value that will be compared and saturated.
        /// \param[in,out] jacobian the jacobian to be saturated depending on the value.
        /// \return true is the constraint is - at least partially - active
        virtual bool operator () (vector_t& value, matrix_t& jacobian) const = 0;
    };

    /// Implement the comparison for equality constraint.
    class Equality : public Inequality
    {
      public:
        /// \return Always true.
        inline bool operator () (vector_t&, matrix_t&) const
        {
          return true;
        }

        static EqualityPtr_t create ()
        {
          if (!unique_)
            unique_ = EqualityPtr_t (new Equality());
          return unique_;
        }

      private:
        static EqualityPtr_t unique_;
    };

    /// Implementation of Inequality that compare the value to
    /// a reference with the possibility of inverting axis.
    class InequalityRef : public Inequality
    {
      public:
        InequalityRef (size_type dim) :
          ref_ (vector_t::Zero (dim)), invert_ (vector_t::Ones (dim))
        {}

        InequalityRef (const vector_t& ref) :
          ref_ (ref), invert_ (vector_t::Ones (ref.size ()))
        {}

        InequalityRef (const vector_t& ref, const vector_t& invert) :
          ref_ (ref), invert_ (invert)
        {}

        virtual bool operator () (vector_t& value, matrix_t& jacobian) const
        {
          bool isActive = true;
          for (size_type i = 0; i < ref_.size (); i++)
            if (invert_[i] * (value[i] - ref_[i]) > 0) {
              value[i] = 0;
              jacobian.row (i).setZero ();
              isActive = false;
            }
          return isActive;
        }

      private:
        /// The reference to which comparison is done
        vector_t ref_;

        /// A vector of +/- 1 depending on whether the direction
        /// is inverted along the corresponding axis.
        vector_t invert_;
    };
  } // namespace core
} // namespace hpp

#endif // HPP_CORE_INEQUALITY_HH
<commit_msg>Fix Inequality<commit_after>// Copyright (c) 2014, LAAS-CNRS
// Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
//
// This file is part of hpp-core.
// hpp-core 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-core 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-core. If not, see <http://www.gnu.org/licenses/>.

#ifndef HPP_CORE_INEQUALITY_HH
# define HPP_CORE_INEQUALITY_HH

# include <hpp/core/fwd.hh>
# include <hpp/core/config.hh>

namespace hpp {
  namespace core {
    /// Abstract class defining the comparison for a function value
    /// and doing a saturation, necessary for inequality constraint.
    /// used to compare two vector.
    /// They are used in ConfigProjector to implement inequality
    /// constraint.
    class HPP_CORE_DLLAPI Inequality
    {
      public:
        /// Return the result of the comparison.
        /// \param[in,out] value the value that will be compared and saturated.
        /// \param[in,out] jacobian the jacobian to be saturated depending on the value.
        /// \return true is the constraint is - at least partially - active
        virtual bool operator () (vector_t& value, matrix_t& jacobian) const = 0;
    };

    /// Implement the comparison for equality constraint.
    class HPP_CORE_DLLAPI Equality : public Inequality
    {
      public:
        /// \return Always true.
        inline bool operator () (vector_t&, matrix_t&) const
        {
          return true;
        }

        static EqualityPtr_t create ()
        {
          if (!unique_)
            unique_ = EqualityPtr_t (new Equality());
          return unique_;
        }

        static EqualityPtr_t unique_;
    };

    /// Implementation of Inequality that compare the value to
    /// a reference with the possibility of inverting axis.
    class HPP_CORE_DLLAPI InequalityRef : public Inequality
    {
      public:
        InequalityRef (size_type dim) :
          ref_ (vector_t::Zero (dim)), invert_ (vector_t::Ones (dim))
        {}

        InequalityRef (const vector_t& ref) :
          ref_ (ref), invert_ (vector_t::Ones (ref.size ()))
        {}

        InequalityRef (const vector_t& ref, const vector_t& invert) :
          ref_ (ref), invert_ (invert)
        {}

        virtual bool operator () (vector_t& value, matrix_t& jacobian) const
        {
          bool isActive = true;
          for (size_type i = 0; i < ref_.size (); i++)
            if (invert_[i] * (value[i] - ref_[i]) > 0) {
              value[i] = 0;
              jacobian.row (i).setZero ();
              isActive = false;
            }
          return isActive;
        }

      private:
        /// The reference to which comparison is done
        vector_t ref_;

        /// A vector of +/- 1 depending on whether the direction
        /// is inverted along the corresponding axis.
        vector_t invert_;
    };
  } // namespace core
} // namespace hpp

#endif // HPP_CORE_INEQUALITY_HH
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 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_ENUMERATION_HPP
#define MAPNIK_ENUMERATION_HPP

// mapnik
#include <mapnik/config.hpp>
#include <mapnik/debug.hpp>

// stl
#include <vector>
#include <bitset>
#include <iostream>
#include <cstdlib>

namespace mapnik {

class illegal_enum_value : public std::exception
{
public:
    illegal_enum_value():
        what_() {}

    illegal_enum_value( std::string const& what ) :
        what_( what )
    {
    }
    virtual ~illegal_enum_value() throw() {}

    virtual const char * what() const throw()
    {
        return what_.c_str();
    }

protected:
    std::string what_;
};

/** Slim wrapper for enumerations. It creates a new type from a native enum and
 * a char pointer array. It almost exactly behaves like a native enumeration
 * type. It supports string conversion through stream operators. This is usefull
 * for debugging, serialization/deserialization and also helps with implementing
 * language bindings. The two convinient macros DEFINE_ENUM() and IMPLEMENT_ENUM()
 * are provided to help with instanciation.
 *
 * @par Limitations:
 *    - The enum must start at zero.
 *    - The enum must be consecutive.
 *    - The enum must be terminated with a special token consisting of the enum's
 *      name plus "_MAX".
 *    - The corresponding char pointer array must be terminated with an empty string.
 *    - The names must only consist of characters and digits (a-z, A-Z, 0-9),
 *      underscores (_) and dashes (-).
 *
 *
 * @warning At the moment the verify_mapnik_enum() method is called during static initialization.
 * It quits the application with exit code 1 if any error is detected. The other solution
 * i thought of is to do the checks at compile time (using boost::mpl).
 *
 * @par Example:
 * The following code goes into the header file:
 * @code
 * enum fruit_enum {
 *      APPLE,
 *      CHERRY,
 *      BANANA,
 *      PASSION_FRUIT,
 *      fruit_enum_MAX
 * };
 *
 * static const char * fruit_strings[] = {
 *      "apple",
 *      "cherry",
 *      "banana",
 *      "passion_fruit",
 *      ""
 * };
 *
 * DEFINE_ENUM( fruit, fruit_enum);
 * @endcode
 * In the corresponding cpp file do:
 * @code
 * IMPLEMENT_ENUM( fruit, fruit_strings );
 * @endcode
 * And here is how to use the resulting type Fruit
 * @code
 *
 * int
 * main(int argc, char * argv[]) {
 *      fruit f(APPLE);
 *      switch ( f ) {
 *          case BANANA:
 *          case APPLE:
 *              cerr << "No thanks. I hate " << f << "s" << endl;
 *              break;
 *          default:
 *              cerr << "Hmmm ... yummy " << f << endl;
 *              break;
 *      }
 *
 *      f = CHERRY;
 *
 *      fruit_enum native_enum = f;
 *
 *      f.from_string("passion_fruit");
 *
 *      for (unsigned i = 0; i < fruit::MAX; ++i) {
 *          cerr << i << " = " << fruit::get_string(i) << endl;
 *      }
 *
 *      f.from_string("elephant"); // throws illegal_enum_value
 *
 *      return 0;
 * }
 * @endcode
 */

template <class ENUM, int THE_MAX>
class MAPNIK_DECL enumeration {
public:
    typedef ENUM native_type;

    enumeration()
      :  value_() {}

    enumeration( ENUM v )
      :  value_(v) {}

    enumeration( const enumeration & other )
      : value_(other.value_) {}

    /** Assignment operator for native enum values. */
    void operator=(ENUM v)
    {
        value_ = v;
    }

    /** Assignment operator. */
    void operator=(const enumeration & other)
    {
        value_ = other.value_;
    }

    /** Conversion operator for native enum values. */
    operator ENUM() const
    {
        return value_;
    }

    enum Max
    {
        MAX = THE_MAX
    };

    ENUM max() const
    {
        return THE_MAX;
    }

    /** Converts @p str to an enum.
     * @throw illegal_enum_value @p str is not a legal identifier.
     * */
    void from_string(std::string const& str)
    {
        for (unsigned i = 0; i < THE_MAX; ++i)
        {
            if (str == our_strings_[i])
            {
                value_ = static_cast<ENUM>(i);
                return;
            }
        }
        throw illegal_enum_value(std::string("Illegal enumeration value '") +
                                 str + "' for enum " + our_name_);
    }

    /** Parses the input stream @p is for a word consisting of characters and
     * digits (a-z, A-Z, 0-9) and underscores (_).
     * The failbit of the stream is set if the word is not a valid identifier.
     */
    std::istream & parse(std::istream & is)
    {
        std::string word;
        char c;

        while ( is.peek() != std::char_traits< char >::eof())
        {
            is >> c;
            if ( isspace(c) && word.empty() )
            {
                continue;
            }
            if ( isalnum(c) || (c == '_') || c == '-' )
            {
                word += c;
            }
            else
            {
                is.unget();
                break;
            }
        }

        try
        {
            from_string( word );
        }
        catch (const illegal_enum_value &)
        {
            is.setstate(std::ios::failbit);
        }

        return is;
    }

    /** Returns the current value as a string identifier. */
    std::string as_string() const
    {
        return our_strings_[value_];
    }

    /** Prints the string identifier to the output stream @p os. */
    std::ostream & print(std::ostream & os = std::cerr) const
    {
        return os << our_strings_[value_];
    }

    /** Static helper function to iterate over valid identifiers. */
    static const char * get_string(unsigned i)
    {
        return our_strings_[i];
    }

    /** Performs some simple checks and quits the application if
     * any error is detected. Tries to print helpful error messages.
     */
    static bool verify_mapnik_enum(const char * filename, unsigned line_no)
    {
        for (unsigned i = 0; i < THE_MAX; ++i)
        {
            if (our_strings_[i] == 0 )
            {
                MAPNIK_LOG_ERROR(enumeration)
                        << "### FATAL: Not enough strings for enum "
                        << our_name_ << " defined in file '" << filename
                        << "' at line " << line_no;
                //std::exit(1);
            }
        }
        if ( std::string("") != our_strings_[THE_MAX])
        {
            MAPNIK_LOG_ERROR(enumeration)
                    << "### FATAL: The string array for enum " << our_name_
                    << " defined in file '" << filename << "' at line " << line_no
                    << " has too many items or is not terminated with an "
                    << "empty string";
            //std::exit(1);
        }
        return true;
    }

    static std::string const& get_full_qualified_name()
    {
        return our_name_;
    }

    static std::string get_name()
    {
        std::string::size_type idx = our_name_.find_last_of(":");
        if ( idx == std::string::npos )
        {
            return our_name_;
        } else {
            return our_name_.substr( idx + 1 );
        }
    }

private:
    ENUM value_;
    static const char ** our_strings_ ;
    static std::string our_name_ ;
    static bool  our_verified_flag_;
};

/** ostream operator for enumeration
 * @relates mapnik::enumeration
 */
template <class ENUM, int THE_MAX>
std::ostream &
operator<<(std::ostream & os, const mapnik::enumeration<ENUM, THE_MAX> & e)
{
    e.print( os );
    return os;
}

/** istream operator for enumeration
 * @relates mapnik::enumeration
 */
template <class ENUM, int THE_MAX>
std::istream &
operator>>(std::istream & is, mapnik::enumeration<ENUM, THE_MAX> & e)
{
    e.parse( is );
    return is;
}

} // end of namespace

/** Helper macro. Creates a typedef.
 * @relates mapnik::enumeration
 */
#define DEFINE_ENUM( name, e)                   \
    typedef enumeration<e, e ## _MAX> name

/** Helper macro. Runs the verify_mapnik_enum() method during static initialization.
 * @relates mapnik::enumeration
 */

#define IMPLEMENT_ENUM( name, strings )                                 \
    template <> const char ** name ::our_strings_ = strings;            \
    template <> std::string name ::our_name_ = #name;                   \
    template <> bool name ::our_verified_flag_( name ::verify_mapnik_enum(__FILE__, __LINE__));

#endif // MAPNIK_ENUMERATION_HPP
<commit_msg>no need to turn off stderr in enumeration since they are fatal and therefore no need for debug.hpp<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 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_ENUMERATION_HPP
#define MAPNIK_ENUMERATION_HPP

// mapnik
#include <mapnik/config.hpp>

// stl
#include <vector>
#include <bitset>
#include <iostream>
#include <cstdlib>

namespace mapnik {

class illegal_enum_value : public std::exception
{
public:
    illegal_enum_value():
        what_() {}

    illegal_enum_value( std::string const& what ) :
        what_( what )
    {
    }
    virtual ~illegal_enum_value() throw() {}

    virtual const char * what() const throw()
    {
        return what_.c_str();
    }

protected:
    std::string what_;
};

/** Slim wrapper for enumerations. It creates a new type from a native enum and
 * a char pointer array. It almost exactly behaves like a native enumeration
 * type. It supports string conversion through stream operators. This is usefull
 * for debugging, serialization/deserialization and also helps with implementing
 * language bindings. The two convinient macros DEFINE_ENUM() and IMPLEMENT_ENUM()
 * are provided to help with instanciation.
 *
 * @par Limitations:
 *    - The enum must start at zero.
 *    - The enum must be consecutive.
 *    - The enum must be terminated with a special token consisting of the enum's
 *      name plus "_MAX".
 *    - The corresponding char pointer array must be terminated with an empty string.
 *    - The names must only consist of characters and digits (a-z, A-Z, 0-9),
 *      underscores (_) and dashes (-).
 *
 *
 * @warning At the moment the verify_mapnik_enum() method is called during static initialization.
 * It quits the application with exit code 1 if any error is detected. The other solution
 * i thought of is to do the checks at compile time (using boost::mpl).
 *
 * @par Example:
 * The following code goes into the header file:
 * @code
 * enum fruit_enum {
 *      APPLE,
 *      CHERRY,
 *      BANANA,
 *      PASSION_FRUIT,
 *      fruit_enum_MAX
 * };
 *
 * static const char * fruit_strings[] = {
 *      "apple",
 *      "cherry",
 *      "banana",
 *      "passion_fruit",
 *      ""
 * };
 *
 * DEFINE_ENUM( fruit, fruit_enum);
 * @endcode
 * In the corresponding cpp file do:
 * @code
 * IMPLEMENT_ENUM( fruit, fruit_strings );
 * @endcode
 * And here is how to use the resulting type Fruit
 * @code
 *
 * int
 * main(int argc, char * argv[]) {
 *      fruit f(APPLE);
 *      switch ( f ) {
 *          case BANANA:
 *          case APPLE:
 *              cerr << "No thanks. I hate " << f << "s" << endl;
 *              break;
 *          default:
 *              cerr << "Hmmm ... yummy " << f << endl;
 *              break;
 *      }
 *
 *      f = CHERRY;
 *
 *      fruit_enum native_enum = f;
 *
 *      f.from_string("passion_fruit");
 *
 *      for (unsigned i = 0; i < fruit::MAX; ++i) {
 *          cerr << i << " = " << fruit::get_string(i) << endl;
 *      }
 *
 *      f.from_string("elephant"); // throws illegal_enum_value
 *
 *      return 0;
 * }
 * @endcode
 */

template <class ENUM, int THE_MAX>
class MAPNIK_DECL enumeration {
public:
    typedef ENUM native_type;

    enumeration()
      :  value_() {}

    enumeration( ENUM v )
      :  value_(v) {}

    enumeration( const enumeration & other )
      : value_(other.value_) {}

    /** Assignment operator for native enum values. */
    void operator=(ENUM v)
    {
        value_ = v;
    }

    /** Assignment operator. */
    void operator=(const enumeration & other)
    {
        value_ = other.value_;
    }

    /** Conversion operator for native enum values. */
    operator ENUM() const
    {
        return value_;
    }

    enum Max
    {
        MAX = THE_MAX
    };

    ENUM max() const
    {
        return THE_MAX;
    }

    /** Converts @p str to an enum.
     * @throw illegal_enum_value @p str is not a legal identifier.
     * */
    void from_string(std::string const& str)
    {
        for (unsigned i = 0; i < THE_MAX; ++i)
        {
            if (str == our_strings_[i])
            {
                value_ = static_cast<ENUM>(i);
                return;
            }
        }
        throw illegal_enum_value(std::string("Illegal enumeration value '") +
                                 str + "' for enum " + our_name_);
    }

    /** Parses the input stream @p is for a word consisting of characters and
     * digits (a-z, A-Z, 0-9) and underscores (_).
     * The failbit of the stream is set if the word is not a valid identifier.
     */
    std::istream & parse(std::istream & is)
    {
        std::string word;
        char c;

        while ( is.peek() != std::char_traits< char >::eof())
        {
            is >> c;
            if ( isspace(c) && word.empty() )
            {
                continue;
            }
            if ( isalnum(c) || (c == '_') || c == '-' )
            {
                word += c;
            }
            else
            {
                is.unget();
                break;
            }
        }

        try
        {
            from_string( word );
        }
        catch (const illegal_enum_value &)
        {
            is.setstate(std::ios::failbit);
        }

        return is;
    }

    /** Returns the current value as a string identifier. */
    std::string as_string() const
    {
        return our_strings_[value_];
    }

    /** Prints the string identifier to the output stream @p os. */
    std::ostream & print(std::ostream & os = std::cerr) const
    {
        return os << our_strings_[value_];
    }

    /** Static helper function to iterate over valid identifiers. */
    static const char * get_string(unsigned i)
    {
        return our_strings_[i];
    }

    /** Performs some simple checks and quits the application if
     * any error is detected. Tries to print helpful error messages.
     */
    static bool verify_mapnik_enum(const char * filename, unsigned line_no)
    {
        for (unsigned i = 0; i < THE_MAX; ++i)
        {
            if (our_strings_[i] == 0 )
            {
                std::cerr << "### FATAL: Not enough strings for enum "
                        << our_name_ << " defined in file '" << filename
                        << "' at line " << line_no;
            }
        }
        if ( std::string("") != our_strings_[THE_MAX])
        {
            std::cerr << "### FATAL: The string array for enum " << our_name_
                      << " defined in file '" << filename << "' at line " << line_no
                      << " has too many items or is not terminated with an "
                      << "empty string";
        }
        return true;
    }

    static std::string const& get_full_qualified_name()
    {
        return our_name_;
    }

    static std::string get_name()
    {
        std::string::size_type idx = our_name_.find_last_of(":");
        if ( idx == std::string::npos )
        {
            return our_name_;
        } else {
            return our_name_.substr( idx + 1 );
        }
    }

private:
    ENUM value_;
    static const char ** our_strings_ ;
    static std::string our_name_ ;
    static bool  our_verified_flag_;
};

/** ostream operator for enumeration
 * @relates mapnik::enumeration
 */
template <class ENUM, int THE_MAX>
std::ostream &
operator<<(std::ostream & os, const mapnik::enumeration<ENUM, THE_MAX> & e)
{
    e.print( os );
    return os;
}

/** istream operator for enumeration
 * @relates mapnik::enumeration
 */
template <class ENUM, int THE_MAX>
std::istream &
operator>>(std::istream & is, mapnik::enumeration<ENUM, THE_MAX> & e)
{
    e.parse( is );
    return is;
}

} // end of namespace

/** Helper macro. Creates a typedef.
 * @relates mapnik::enumeration
 */
#define DEFINE_ENUM( name, e)                   \
    typedef enumeration<e, e ## _MAX> name

/** Helper macro. Runs the verify_mapnik_enum() method during static initialization.
 * @relates mapnik::enumeration
 */

#define IMPLEMENT_ENUM( name, strings )                                 \
    template <> const char ** name ::our_strings_ = strings;            \
    template <> std::string name ::our_name_ = #name;                   \
    template <> bool name ::our_verified_flag_( name ::verify_mapnik_enum(__FILE__, __LINE__));

#endif // MAPNIK_ENUMERATION_HPP
<|endoftext|>


<commit_before>#include "editor/ui2oh.hpp"

#include "std/algorithm.hpp"
#include "std/array.hpp"
#include "std/string.hpp"

#include "3party/opening_hours/opening_hours.hpp"

namespace
{
void SetUpWeekdays(osmoh::Weekdays const & wds, editor::ui::TimeTable & tt)
{
  set<osmoh::Weekday> openingDays;
  for (auto const & wd : wds.GetWeekdayRanges())
  {
    if (wd.HasSunday())
      openingDays.insert(osmoh::Weekday::Sunday);
    if (wd.HasMonday())
      openingDays.insert(osmoh::Weekday::Monday);
    if (wd.HasTuesday())
      openingDays.insert(osmoh::Weekday::Tuesday);
    if (wd.HasWednesday())
      openingDays.insert(osmoh::Weekday::Wednesday);
    if (wd.HasThursday())
      openingDays.insert(osmoh::Weekday::Thursday);
    if (wd.HasFriday())
      openingDays.insert(osmoh::Weekday::Friday);
    if (wd.HasSaturday())
      openingDays.insert(osmoh::Weekday::Saturday);
  }
  tt.SetOpeningDays(openingDays);
}

void SetUpTimeTable(osmoh::TTimespans spans, editor::ui::TimeTable & tt)
{
  using namespace osmoh;

  sort(begin(spans), end(spans), [](Timespan const & a, Timespan const & b)
       {
         auto const start1 = a.GetStart().GetHourMinutes().GetDuration();
         auto const start2 = b.GetStart().GetHourMinutes().GetDuration();

         return start1 < start2;
       });

  // Take first start and last end as opening time span.
  tt.SetOpeningTime({spans.front().GetStart(), spans.back().GetEnd()});

  // Add an end of a span of index i and start of following span
  // as exclude time.
  for (auto i = 0; i + 1 < spans.size(); ++i)
    tt.AddExcludeTime({spans[i].GetEnd(), spans[i + 1].GetStart()});
}

int32_t WeekdayNumber(osmoh::Weekday const wd) { return static_cast<int32_t>(wd); }

constexpr uint32_t kDaysInWeek = 7;

// Shifts values from 1 to 7 like this: 1 2 3 4 5 6 7 -> 2 3 4 5 6 7 1
int32_t NextWeekdayNumber(osmoh::Weekday const wd)
{
  auto dayNumber = WeekdayNumber(wd);
  // If first element of the gourp would be evaluated to 0
  // the resulting formula whould be (dayNumber + 1) % kDaysInWeek.
  // Since the first one evaluates to 1
  // the formula is:
  return dayNumber % kDaysInWeek + 1;
}

// Returns a vector of Weekdays with no gaps and with Sunday as the last day.
// Exampls:
// su, mo, we -> mo, we, su;
// su, mo, fr, sa -> fr, sa, su, mo.
vector<osmoh::Weekday> RemoveInversion(editor::ui::TOpeningDays const & days)
{
  vector<osmoh::Weekday> result(begin(days), end(days));
  if ((NextWeekdayNumber(result.back()) != WeekdayNumber(result.front()) &&
       result.back() != osmoh::Weekday::Sunday) || result.size() < 2)
    return result;

  auto inversion = adjacent_find(begin(result), end(result),
                [](osmoh::Weekday const a, osmoh::Weekday const b)
                {
                  return NextWeekdayNumber(a) != WeekdayNumber(b);
                });

  if (inversion != end(result))
    rotate(begin(result), ++inversion, end(result));

  if (result.front() == osmoh::Weekday::Sunday)
    rotate(begin(result), begin(result) + 1, end(result));

  return result;
}

using TWeekdays = vector<osmoh::Weekday>;

vector<TWeekdays> SplitIntoIntervals(editor::ui::TOpeningDays const & days)
{
  vector<TWeekdays> result;
  auto const & noInversionDays = RemoveInversion(days);

  auto previous = *begin(noInversionDays);
  result.push_back({previous});

  for (auto it = next(begin(noInversionDays)); it != end(noInversionDays); ++it)
  {
    if (NextWeekdayNumber(previous) != WeekdayNumber(*it))
      result.push_back({});
    result.back().push_back(*it);
    previous = *it;
  }

  return result;
}

osmoh::Weekdays MakeWeekdays(editor::ui::TimeTable const & tt)
{
  osmoh::Weekdays wds;

  for (auto const & daysInterval : SplitIntoIntervals(tt.GetOpeningDays()))
  {
    osmoh::WeekdayRange wdr;
    wdr.SetStart(*begin(daysInterval));
    if (daysInterval.size() > 1)
      wdr.SetEnd(*(prev(end(daysInterval))));

    wds.AddWeekdayRange(wdr);
  }

  return wds;
}

osmoh::TTimespans MakeTimespans(editor::ui::TimeTable const & tt)
{

  if (tt.IsTwentyFourHours())
    return {};

  auto const & excludeTime = tt.GetExcludeTime();
  if (excludeTime.empty())
    return {tt.GetOpeningTime()};

  osmoh::TTimespans spans{{tt.GetOpeningTime().GetStart(), excludeTime[0].GetStart()}};

  for (auto i = 0; i + 1 < excludeTime.size(); ++i)
    spans.emplace_back(excludeTime[i].GetEnd(), excludeTime[i + 1].GetStart());

  spans.emplace_back(excludeTime.back().GetEnd(), tt.GetOpeningTime().GetEnd());

  return spans;
}
}  // namespace

namespace editor
{
osmoh::OpeningHours MakeOpeningHours(ui::TimeTableSet const & tts)
{
  osmoh::TRuleSequences rule;
  for (auto const & tt : tts)
  {
    osmoh::RuleSequence rulePart;
    rulePart.SetWeekdays(MakeWeekdays(tt));
    rulePart.SetTimes(MakeTimespans(tt));
    rule.push_back(rulePart);
  }

  return rule;
}

bool MakeTimeTableSet(osmoh::OpeningHours const & oh, ui::TimeTableSet & tts)
{
  if (!oh.IsValid())
    return false;

  if (oh.HasYearSelector() || oh.HasWeekSelector() || oh.HasMonthSelector())
    return false;

  tts = ui::TimeTableSet();
  if (oh.IsTwentyFourHours())
    return true;

  bool first = true;
  for (auto const & rulePart : oh.GetRule())
  {
    ui::TimeTable tt;

    // TODO(mgsergio): We don't handle cases with speciffic time off.
    // I.e. Mo-Fr 08-20; Fr 18:00-17:00 off.
    // Can be implemented later.
    if (rulePart.GetModifier() == osmoh::RuleSequence::Modifier::Closed ||
        rulePart.GetModifier() == osmoh::RuleSequence::Modifier::Unknown ||
        rulePart.GetModifier() == osmoh::RuleSequence::Modifier::Comment)
      continue;

    if (rulePart.HasWeekdays())
      SetUpWeekdays(rulePart.GetWeekdays(), tt);

    if (rulePart.HasTimes())
    {
      tt.SetTwentyFourHours(false);
      SetUpTimeTable(rulePart.GetTimes(), tt);
    }
    else
    {
      tt.SetTwentyFourHours(true);
    }

    bool const appended = first ? tts.Replace(tt, 0) : tts.Append(tt);
    first = false;
    if (!appended)
      return false;
  }

  return true;
}
} // namespace editor
<commit_msg>Add default opening time to TimeTable when constucted from opening hours.<commit_after>#include "editor/ui2oh.hpp"

#include "std/algorithm.hpp"
#include "std/array.hpp"
#include "std/string.hpp"

#include "3party/opening_hours/opening_hours.hpp"

namespace
{
void SetUpWeekdays(osmoh::Weekdays const & wds, editor::ui::TimeTable & tt)
{
  set<osmoh::Weekday> openingDays;
  for (auto const & wd : wds.GetWeekdayRanges())
  {
    if (wd.HasSunday())
      openingDays.insert(osmoh::Weekday::Sunday);
    if (wd.HasMonday())
      openingDays.insert(osmoh::Weekday::Monday);
    if (wd.HasTuesday())
      openingDays.insert(osmoh::Weekday::Tuesday);
    if (wd.HasWednesday())
      openingDays.insert(osmoh::Weekday::Wednesday);
    if (wd.HasThursday())
      openingDays.insert(osmoh::Weekday::Thursday);
    if (wd.HasFriday())
      openingDays.insert(osmoh::Weekday::Friday);
    if (wd.HasSaturday())
      openingDays.insert(osmoh::Weekday::Saturday);
  }
  tt.SetOpeningDays(openingDays);
}

void SetUpTimeTable(osmoh::TTimespans spans, editor::ui::TimeTable & tt)
{
  using namespace osmoh;

  sort(begin(spans), end(spans), [](Timespan const & a, Timespan const & b)
       {
         auto const start1 = a.GetStart().GetHourMinutes().GetDuration();
         auto const start2 = b.GetStart().GetHourMinutes().GetDuration();

         return start1 < start2;
       });

  // Take first start and last end as opening time span.
  tt.SetOpeningTime({spans.front().GetStart(), spans.back().GetEnd()});

  // Add an end of a span of index i and start of following span
  // as exclude time.
  for (auto i = 0; i + 1 < spans.size(); ++i)
    tt.AddExcludeTime({spans[i].GetEnd(), spans[i + 1].GetStart()});
}

int32_t WeekdayNumber(osmoh::Weekday const wd) { return static_cast<int32_t>(wd); }

constexpr uint32_t kDaysInWeek = 7;

// Shifts values from 1 to 7 like this: 1 2 3 4 5 6 7 -> 2 3 4 5 6 7 1
int32_t NextWeekdayNumber(osmoh::Weekday const wd)
{
  auto dayNumber = WeekdayNumber(wd);
  // If first element of the gourp would be evaluated to 0
  // the resulting formula whould be (dayNumber + 1) % kDaysInWeek.
  // Since the first one evaluates to 1
  // the formula is:
  return dayNumber % kDaysInWeek + 1;
}

// Returns a vector of Weekdays with no gaps and with Sunday as the last day.
// Exampls:
// su, mo, we -> mo, we, su;
// su, mo, fr, sa -> fr, sa, su, mo.
vector<osmoh::Weekday> RemoveInversion(editor::ui::TOpeningDays const & days)
{
  vector<osmoh::Weekday> result(begin(days), end(days));
  if ((NextWeekdayNumber(result.back()) != WeekdayNumber(result.front()) &&
       result.back() != osmoh::Weekday::Sunday) || result.size() < 2)
    return result;

  auto inversion = adjacent_find(begin(result), end(result),
                [](osmoh::Weekday const a, osmoh::Weekday const b)
                {
                  return NextWeekdayNumber(a) != WeekdayNumber(b);
                });

  if (inversion != end(result))
    rotate(begin(result), ++inversion, end(result));

  if (result.front() == osmoh::Weekday::Sunday)
    rotate(begin(result), begin(result) + 1, end(result));

  return result;
}

using TWeekdays = vector<osmoh::Weekday>;

vector<TWeekdays> SplitIntoIntervals(editor::ui::TOpeningDays const & days)
{
  vector<TWeekdays> result;
  auto const & noInversionDays = RemoveInversion(days);

  auto previous = *begin(noInversionDays);
  result.push_back({previous});

  for (auto it = next(begin(noInversionDays)); it != end(noInversionDays); ++it)
  {
    if (NextWeekdayNumber(previous) != WeekdayNumber(*it))
      result.push_back({});
    result.back().push_back(*it);
    previous = *it;
  }

  return result;
}

osmoh::Weekdays MakeWeekdays(editor::ui::TimeTable const & tt)
{
  osmoh::Weekdays wds;

  for (auto const & daysInterval : SplitIntoIntervals(tt.GetOpeningDays()))
  {
    osmoh::WeekdayRange wdr;
    wdr.SetStart(*begin(daysInterval));
    if (daysInterval.size() > 1)
      wdr.SetEnd(*(prev(end(daysInterval))));

    wds.AddWeekdayRange(wdr);
  }

  return wds;
}

osmoh::TTimespans MakeTimespans(editor::ui::TimeTable const & tt)
{

  if (tt.IsTwentyFourHours())
    return {};

  auto const & excludeTime = tt.GetExcludeTime();
  if (excludeTime.empty())
    return {tt.GetOpeningTime()};

  osmoh::TTimespans spans{{tt.GetOpeningTime().GetStart(), excludeTime[0].GetStart()}};

  for (auto i = 0; i + 1 < excludeTime.size(); ++i)
    spans.emplace_back(excludeTime[i].GetEnd(), excludeTime[i + 1].GetStart());

  spans.emplace_back(excludeTime.back().GetEnd(), tt.GetOpeningTime().GetEnd());

  return spans;
}
}  // namespace

namespace editor
{
osmoh::OpeningHours MakeOpeningHours(ui::TimeTableSet const & tts)
{
  osmoh::TRuleSequences rule;
  for (auto const & tt : tts)
  {
    osmoh::RuleSequence rulePart;
    rulePart.SetWeekdays(MakeWeekdays(tt));
    rulePart.SetTimes(MakeTimespans(tt));
    rule.push_back(rulePart);
  }

  return rule;
}

bool MakeTimeTableSet(osmoh::OpeningHours const & oh, ui::TimeTableSet & tts)
{
  if (!oh.IsValid())
    return false;

  if (oh.HasYearSelector() || oh.HasWeekSelector() || oh.HasMonthSelector())
    return false;

  tts = ui::TimeTableSet();
  if (oh.IsTwentyFourHours())
    return true;

  bool first = true;
  for (auto const & rulePart : oh.GetRule())
  {
    ui::TimeTable tt;
    tt.SetOpeningTime(tt.GetPredefinedOpeningTime());

    // TODO(mgsergio): We don't handle cases with speciffic time off.
    // I.e. Mo-Fr 08-20; Fr 18:00-17:00 off.
    // Can be implemented later.
    if (rulePart.GetModifier() == osmoh::RuleSequence::Modifier::Closed ||
        rulePart.GetModifier() == osmoh::RuleSequence::Modifier::Unknown ||
        rulePart.GetModifier() == osmoh::RuleSequence::Modifier::Comment)
      continue;

    if (rulePart.HasWeekdays())
      SetUpWeekdays(rulePart.GetWeekdays(), tt);

    if (rulePart.HasTimes())
    {
      tt.SetTwentyFourHours(false);
      SetUpTimeTable(rulePart.GetTimes(), tt);
    }
    else
    {
      tt.SetTwentyFourHours(true);
    }

    bool const appended = first ? tts.Replace(tt, 0) : tts.Append(tt);
    first = false;
    if (!appended)
      return false;
  }

  return true;
}
} // namespace editor
<|endoftext|>