<commit_before>// Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
#ifndef __BSE_CXXAUX_HH__
#define __BSE_CXXAUX_HH__

#include <sfi/sysconfig.h>
#include <sys/types.h>                  // uint, ssize
#include <cstdint>                      // uint64_t
#include <memory>
#include <vector>
#include <map>

namespace Bse {

// == uint ==
#if     BSE_SIZEOF_SYS_TYPESH_UINT == 0
typedef unsigned int            uint;   ///< Provide 'uint' if sys/types.h fails to do so.
#else
static_assert (BSE_SIZEOF_SYS_TYPESH_UINT == 4, "");
#endif
static_assert (sizeof (uint) == 4, "");

// == type aliases ==
typedef uint8_t         uint8;          ///< An 8-bit unsigned integer.
typedef uint16_t        uint16;         ///< A 16-bit unsigned integer.
typedef uint32_t        uint32;         ///< A 32-bit unsigned integer.
typedef uint64_t        uint64;         ///< A 64-bit unsigned integer, use PRI*64 in format strings.
typedef int8_t          int8;           ///< An 8-bit signed integer.
typedef int16_t         int16;          ///< A 16-bit signed integer.
typedef int32_t         int32;          ///< A 32-bit signed integer.
typedef int64_t         int64;          ///< A 64-bit unsigned integer, use PRI*64 in format strings.
typedef uint32_t        unichar;        ///< A 32-bit unsigned integer used for Unicode characters.
static_assert (sizeof (uint8) == 1 && sizeof (uint16) == 2 && sizeof (uint32) == 4 && sizeof (uint64) == 8, "");
static_assert (sizeof (int8)  == 1 && sizeof (int16)  == 2 && sizeof (int32)  == 4 && sizeof (int64)  == 8, "");
static_assert (sizeof (int) == 4 && sizeof (uint) == 4 && sizeof (unichar) == 4, "");
using   std::map;
using   std::vector;
typedef std::string String;             ///< Convenience alias for std::string.
typedef vector<String> StringVector;    ///< Convenience alias for a std::vector<std::string>.

// == Utility Macros ==
#define BSE_CPP_STRINGIFY(s)    BSE_CPP_STRINGIFY_ (s)                  ///< Convert macro argument into a C const char*.
#define BSE_CPP_STRINGIFY_(s)   #s                                      // Indirection helper, required to expand macros like __LINE__
#define BSE_CPP_PASTE2_(a,b)    a ## b                                  // Indirection helper, required to expand macros like __LINE__
#define BSE_CPP_PASTE2(a,b)     BSE_CPP_PASTE2_ (a,b)                   ///< Paste two macro arguments into one C symbol name
#define BSE_ISLIKELY(expr)      __builtin_expect (bool (expr), 1)       ///< Compiler hint to optimize for @a expr evaluating to true.
#define BSE_UNLIKELY(expr)      __builtin_expect (bool (expr), 0)       ///< Compiler hint to optimize for @a expr evaluating to false.
#define BSE_ABS(a)              ((a) < 0 ? -(a) : (a))                  ///< Yield the absolute value of @a a.
#define BSE_MIN(a,b)            ((a) <= (b) ? (a) : (b))                ///< Yield the smaller value of @a a and @a b.
#define BSE_MAX(a,b)            ((a) >= (b) ? (a) : (b))                ///< Yield the greater value of @a a and @a b.
#define BSE_CLAMP(v,mi,ma)      ((v) < (mi) ? (mi) : ((v) > (ma) ? (ma) : (v))) ///< Yield @a v clamped to [ @a mi .. @a ma ].
#define BSE_ARRAY_SIZE(array)   (sizeof (array) / sizeof ((array)[0]))          ///< Yield the number of C @a array elements.
#define BSE_ALIGN(size, base)   ((base) * ((size_t (size) + (base) - 1) / (base))) ///< Round up @a size to multiples of @a base.
/// @addtogroup GCC Attributes
/// Bse macros that are shorthands for GCC Attributes.
/// @{
#define BSE_ALWAYS_INLINE       __attribute__ ((always_inline))
#define BSE_COLD                __attribute__ ((__cold__))
#define BSE_CONST               __attribute__ ((__const__))
#define BSE_CONSTRUCTOR	        __attribute__ ((constructor,used))      // gcc-3.3 also needs "used" to emit code
#define BSE_DEPRECATED          __attribute__ ((__deprecated__))
#define BSE_FORMAT(fx)          __attribute__ ((__format_arg__ (fx)))
#define BSE_HOT                 __attribute__ ((__hot__))
#define BSE_MALLOC              __attribute__ ((__malloc__))
#define BSE_MAY_ALIAS           __attribute__ ((may_alias))
#define BSE_NOINLINE	        __attribute__ ((noinline))
#define BSE_NORETURN            __attribute__ ((__noreturn__))
#define BSE_NO_INSTRUMENT       __attribute__ ((__no_instrument_function__))
#define BSE_PRINTF(fx, ax)      __attribute__ ((__format__ (__printf__, fx, ax)))
#define BSE_PURE                __attribute__ ((__pure__))
#define BSE_SCANF(fx, ax)       __attribute__ ((__format__ (__scanf__, fx, ax)))
#define BSE_SENTINEL            __attribute__ ((__sentinel__))
#define BSE_UNUSED              __attribute__ ((__unused__))
#define BSE_USE_RESULT          __attribute__ ((warn_unused_result))
#define BSE_USED                __attribute__ ((__used__))
#define BSE_WEAK                __attribute__ ((__weak__))
/// @}

/// Return silently if @a cond does not evaluate to true, with return value @a ...
#define BSE_RETURN_UNLESS(cond, ...)      do { if (BSE_UNLIKELY (!bool (cond))) return __VA_ARGS__; } while (0)

/// Delete copy ctor and assignment operator.
#define BSE_CLASS_NON_COPYABLE(ClassName)  \
  /*copy-ctor*/ ClassName  (const ClassName&) = delete; \
  ClassName&    operator=  (const ClassName&) = delete
#ifdef __clang__ // clang++-3.8.0: work around 'variable length array of non-POD element type'
#define BSE_DECLARE_VLA(Type, var, count)          std::vector<Type> var (count)
#else // sane c++
#define BSE_DECLARE_VLA(Type, var, count)          Type var[count] ///< Declare a variable length array (clang++ uses std::vector<>).
#endif

/**
 * A std::make_shared<>() wrapper class to access private ctor & dtor.
 * To call std::make_shared<T>() on a class @a T, its constructor and
 * destructor must be public. For classes with private or protected
 * constructor or destructor, this class can be used as follows:
 * @code{.cc}
 * class Type {
 *   Type (ctor_args...);                // Private ctor.
 *   friend class FriendAllocator<Type>; // Allow access to ctor/dtor of Type.
 * };
 * std::shared_ptr<Type> t = FriendAllocator<Type>::make_shared (ctor_args...);
 * @endcode
 */
template<class T>
class FriendAllocator : public std::allocator<T> {
public:
  /// Construct type @a C object, standard allocator requirement.
  template<typename C, typename... Args> static inline void
  construct (C *p, Args &&... args)
  {
    ::new ((void*) p) C (std::forward<Args> (args)...);
  }
  /// Delete type @a C object, standard allocator requirement.
  template<typename C> static inline void
  destroy (C *p)
  {
    p->~C ();
  }
  /**
   * Construct an object of type @a T that is wrapped into a std::shared_ptr<T>.
   * @param args        The list of arguments to pass into a T() constructor.
   * @return            A std::shared_ptr<T> owning the newly created object.
   */
  template<typename ...Args> static inline std::shared_ptr<T>
  make_shared (Args &&... args)
  {
    return std::allocate_shared<T> (FriendAllocator(), std::forward<Args> (args)...);
  }
};

/** Shorthand for std::dynamic_pointer_cast<>(shared_from_this()).
 * A shared_ptr_cast() takes a std::shared_ptr or a pointer to an @a object that
 * supports std::enable_shared_from_this::shared_from_this().
 * Using std::dynamic_pointer_cast(), the shared_ptr passed in (or retrieved via
 * calling shared_from_this()) is cast into a std::shared_ptr<@a Target>, possibly
 * resulting in an empty (NULL) std::shared_ptr if the underlying dynamic_cast()
 * was not successful or if a NULL @a object was passed in.
 * Note that shared_from_this() can throw a std::bad_weak_ptr exception if
 * the object has no associated std::shared_ptr (usually during ctor and dtor), in
 * which case the exception will also be thrown from shared_ptr_cast<Target>().
 * However a shared_ptr_cast<Target*>() call will not throw and yield an empty
 * (NULL) std::shared_ptr<@a Target>. This is analogous to dynamic_cast<T@amp> which
 * throws, versus dynamic_cast<T*> which yields NULL.
 * @return A std::shared_ptr<@a Target> storing a pointer to @a object or NULL.
 * @throws std::bad_weak_ptr if shared_from_this() throws, unless the @a Target* form is used.
 */
template<class Target, class Source> std::shared_ptr<typename std::remove_pointer<Target>::type>
shared_ptr_cast (Source *object)
{
  if (!object)
    return NULL;
  // construct shared_ptr if possible
  typedef decltype (object->shared_from_this()) ObjectP;
  ObjectP sptr;
  if (std::is_pointer<Target>::value)
    try {
      sptr = object->shared_from_this();
    } catch (const std::bad_weak_ptr&) {
      return NULL;
    }
  else // for non-pointers, allow bad_weak_ptr exceptions
    sptr = object->shared_from_this();
  // cast into target shared_ptr<> type
  return std::dynamic_pointer_cast<typename std::remove_pointer<Target>::type> (sptr);
}
/// See shared_ptr_cast(Source*).
template<class Target, class Source> const std::shared_ptr<typename std::remove_pointer<Target>::type>
shared_ptr_cast (const Source *object)
{
  return shared_ptr_cast<Target> (const_cast<Source*> (object));
}
/// See shared_ptr_cast(Source*).
template<class Target, class Source> std::shared_ptr<typename std::remove_pointer<Target>::type>
shared_ptr_cast (std::shared_ptr<Source> &sptr)
{
  return std::dynamic_pointer_cast<typename std::remove_pointer<Target>::type> (sptr);
}
/// See shared_ptr_cast(Source*).
template<class Target, class Source> const std::shared_ptr<typename std::remove_pointer<Target>::type>
shared_ptr_cast (const std::shared_ptr<Source> &sptr)
{
  return shared_ptr_cast<Target> (const_cast<std::shared_ptr<Source>&> (sptr));
}

} // Bse

#endif // __BSE_CXXAUX_HH__
<commit_msg>SFI: cxxaux: add type-safe new_inplace and delete_inplace<commit_after>// Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
#ifndef __BSE_CXXAUX_HH__
#define __BSE_CXXAUX_HH__

#include <sfi/sysconfig.h>
#include <sys/types.h>                  // uint, ssize
#include <cstdint>                      // uint64_t
#include <memory>
#include <vector>
#include <map>

namespace Bse {

// == uint ==
#if     BSE_SIZEOF_SYS_TYPESH_UINT == 0
typedef unsigned int            uint;   ///< Provide 'uint' if sys/types.h fails to do so.
#else
static_assert (BSE_SIZEOF_SYS_TYPESH_UINT == 4, "");
#endif
static_assert (sizeof (uint) == 4, "");

// == type aliases ==
typedef uint8_t         uint8;          ///< An 8-bit unsigned integer.
typedef uint16_t        uint16;         ///< A 16-bit unsigned integer.
typedef uint32_t        uint32;         ///< A 32-bit unsigned integer.
typedef uint64_t        uint64;         ///< A 64-bit unsigned integer, use PRI*64 in format strings.
typedef int8_t          int8;           ///< An 8-bit signed integer.
typedef int16_t         int16;          ///< A 16-bit signed integer.
typedef int32_t         int32;          ///< A 32-bit signed integer.
typedef int64_t         int64;          ///< A 64-bit unsigned integer, use PRI*64 in format strings.
typedef uint32_t        unichar;        ///< A 32-bit unsigned integer used for Unicode characters.
static_assert (sizeof (uint8) == 1 && sizeof (uint16) == 2 && sizeof (uint32) == 4 && sizeof (uint64) == 8, "");
static_assert (sizeof (int8)  == 1 && sizeof (int16)  == 2 && sizeof (int32)  == 4 && sizeof (int64)  == 8, "");
static_assert (sizeof (int) == 4 && sizeof (uint) == 4 && sizeof (unichar) == 4, "");
using   std::map;
using   std::vector;
typedef std::string String;             ///< Convenience alias for std::string.
typedef vector<String> StringVector;    ///< Convenience alias for a std::vector<std::string>.

// == Utility Macros ==
#define BSE_CPP_STRINGIFY(s)    BSE_CPP_STRINGIFY_ (s)                  ///< Convert macro argument into a C const char*.
#define BSE_CPP_STRINGIFY_(s)   #s                                      // Indirection helper, required to expand macros like __LINE__
#define BSE_CPP_PASTE2_(a,b)    a ## b                                  // Indirection helper, required to expand macros like __LINE__
#define BSE_CPP_PASTE2(a,b)     BSE_CPP_PASTE2_ (a,b)                   ///< Paste two macro arguments into one C symbol name
#define BSE_ISLIKELY(expr)      __builtin_expect (bool (expr), 1)       ///< Compiler hint to optimize for @a expr evaluating to true.
#define BSE_UNLIKELY(expr)      __builtin_expect (bool (expr), 0)       ///< Compiler hint to optimize for @a expr evaluating to false.
#define BSE_ABS(a)              ((a) < 0 ? -(a) : (a))                  ///< Yield the absolute value of @a a.
#define BSE_MIN(a,b)            ((a) <= (b) ? (a) : (b))                ///< Yield the smaller value of @a a and @a b.
#define BSE_MAX(a,b)            ((a) >= (b) ? (a) : (b))                ///< Yield the greater value of @a a and @a b.
#define BSE_CLAMP(v,mi,ma)      ((v) < (mi) ? (mi) : ((v) > (ma) ? (ma) : (v))) ///< Yield @a v clamped to [ @a mi .. @a ma ].
#define BSE_ARRAY_SIZE(array)   (sizeof (array) / sizeof ((array)[0]))          ///< Yield the number of C @a array elements.
#define BSE_ALIGN(size, base)   ((base) * ((size_t (size) + (base) - 1) / (base))) ///< Round up @a size to multiples of @a base.
/// @addtogroup GCC Attributes
/// Bse macros that are shorthands for GCC Attributes.
/// @{
#define BSE_ALWAYS_INLINE       __attribute__ ((always_inline))
#define BSE_COLD                __attribute__ ((__cold__))
#define BSE_CONST               __attribute__ ((__const__))
#define BSE_CONSTRUCTOR	        __attribute__ ((constructor,used))      // gcc-3.3 also needs "used" to emit code
#define BSE_DEPRECATED          __attribute__ ((__deprecated__))
#define BSE_FORMAT(fx)          __attribute__ ((__format_arg__ (fx)))
#define BSE_HOT                 __attribute__ ((__hot__))
#define BSE_MALLOC              __attribute__ ((__malloc__))
#define BSE_MAY_ALIAS           __attribute__ ((may_alias))
#define BSE_NOINLINE	        __attribute__ ((noinline))
#define BSE_NORETURN            __attribute__ ((__noreturn__))
#define BSE_NO_INSTRUMENT       __attribute__ ((__no_instrument_function__))
#define BSE_PRINTF(fx, ax)      __attribute__ ((__format__ (__printf__, fx, ax)))
#define BSE_PURE                __attribute__ ((__pure__))
#define BSE_SCANF(fx, ax)       __attribute__ ((__format__ (__scanf__, fx, ax)))
#define BSE_SENTINEL            __attribute__ ((__sentinel__))
#define BSE_UNUSED              __attribute__ ((__unused__))
#define BSE_USE_RESULT          __attribute__ ((warn_unused_result))
#define BSE_USED                __attribute__ ((__used__))
#define BSE_WEAK                __attribute__ ((__weak__))
/// @}

/// Return silently if @a cond does not evaluate to true, with return value @a ...
#define BSE_RETURN_UNLESS(cond, ...)      do { if (BSE_UNLIKELY (!bool (cond))) return __VA_ARGS__; } while (0)

/// Delete copy ctor and assignment operator.
#define BSE_CLASS_NON_COPYABLE(ClassName)  \
  /*copy-ctor*/ ClassName  (const ClassName&) = delete; \
  ClassName&    operator=  (const ClassName&) = delete
#ifdef __clang__ // clang++-3.8.0: work around 'variable length array of non-POD element type'
#define BSE_DECLARE_VLA(Type, var, count)          std::vector<Type> var (count)
#else // sane c++
#define BSE_DECLARE_VLA(Type, var, count)          Type var[count] ///< Declare a variable length array (clang++ uses std::vector<>).
#endif

/// Call inplace new operator by automatically inferring the Type.
template<class Type, class ...Ts> __attribute__ ((always_inline)) inline void
new_inplace (Type &typemem, Ts &&... args)
{
  new (&typemem) Type (std::forward<Ts> (args)...);
}

/// Call inplace delete operator by automatically inferring the Type.
template<class Type> __attribute__ ((always_inline)) inline void
delete_inplace (Type &typemem)
{
  typemem.~Type();
}

/**
 * A std::make_shared<>() wrapper class to access private ctor & dtor.
 * To call std::make_shared<T>() on a class @a T, its constructor and
 * destructor must be public. For classes with private or protected
 * constructor or destructor, this class can be used as follows:
 * @code{.cc}
 * class Type {
 *   Type (ctor_args...);                // Private ctor.
 *   friend class FriendAllocator<Type>; // Allow access to ctor/dtor of Type.
 * };
 * std::shared_ptr<Type> t = FriendAllocator<Type>::make_shared (ctor_args...);
 * @endcode
 */
template<class T>
class FriendAllocator : public std::allocator<T> {
public:
  /// Construct type @a C object, standard allocator requirement.
  template<typename C, typename... Args> static inline void
  construct (C *p, Args &&... args)
  {
    ::new ((void*) p) C (std::forward<Args> (args)...);
  }
  /// Delete type @a C object, standard allocator requirement.
  template<typename C> static inline void
  destroy (C *p)
  {
    p->~C ();
  }
  /**
   * Construct an object of type @a T that is wrapped into a std::shared_ptr<T>.
   * @param args        The list of arguments to pass into a T() constructor.
   * @return            A std::shared_ptr<T> owning the newly created object.
   */
  template<typename ...Args> static inline std::shared_ptr<T>
  make_shared (Args &&... args)
  {
    return std::allocate_shared<T> (FriendAllocator(), std::forward<Args> (args)...);
  }
};

/** Shorthand for std::dynamic_pointer_cast<>(shared_from_this()).
 * A shared_ptr_cast() takes a std::shared_ptr or a pointer to an @a object that
 * supports std::enable_shared_from_this::shared_from_this().
 * Using std::dynamic_pointer_cast(), the shared_ptr passed in (or retrieved via
 * calling shared_from_this()) is cast into a std::shared_ptr<@a Target>, possibly
 * resulting in an empty (NULL) std::shared_ptr if the underlying dynamic_cast()
 * was not successful or if a NULL @a object was passed in.
 * Note that shared_from_this() can throw a std::bad_weak_ptr exception if
 * the object has no associated std::shared_ptr (usually during ctor and dtor), in
 * which case the exception will also be thrown from shared_ptr_cast<Target>().
 * However a shared_ptr_cast<Target*>() call will not throw and yield an empty
 * (NULL) std::shared_ptr<@a Target>. This is analogous to dynamic_cast<T@amp> which
 * throws, versus dynamic_cast<T*> which yields NULL.
 * @return A std::shared_ptr<@a Target> storing a pointer to @a object or NULL.
 * @throws std::bad_weak_ptr if shared_from_this() throws, unless the @a Target* form is used.
 */
template<class Target, class Source> std::shared_ptr<typename std::remove_pointer<Target>::type>
shared_ptr_cast (Source *object)
{
  if (!object)
    return NULL;
  // construct shared_ptr if possible
  typedef decltype (object->shared_from_this()) ObjectP;
  ObjectP sptr;
  if (std::is_pointer<Target>::value)
    try {
      sptr = object->shared_from_this();
    } catch (const std::bad_weak_ptr&) {
      return NULL;
    }
  else // for non-pointers, allow bad_weak_ptr exceptions
    sptr = object->shared_from_this();
  // cast into target shared_ptr<> type
  return std::dynamic_pointer_cast<typename std::remove_pointer<Target>::type> (sptr);
}
/// See shared_ptr_cast(Source*).
template<class Target, class Source> const std::shared_ptr<typename std::remove_pointer<Target>::type>
shared_ptr_cast (const Source *object)
{
  return shared_ptr_cast<Target> (const_cast<Source*> (object));
}
/// See shared_ptr_cast(Source*).
template<class Target, class Source> std::shared_ptr<typename std::remove_pointer<Target>::type>
shared_ptr_cast (std::shared_ptr<Source> &sptr)
{
  return std::dynamic_pointer_cast<typename std::remove_pointer<Target>::type> (sptr);
}
/// See shared_ptr_cast(Source*).
template<class Target, class Source> const std::shared_ptr<typename std::remove_pointer<Target>::type>
shared_ptr_cast (const std::shared_ptr<Source> &sptr)
{
  return shared_ptr_cast<Target> (const_cast<std::shared_ptr<Source>&> (sptr));
}

} // Bse

#endif // __BSE_CXXAUX_HH__
<|endoftext|>


<commit_before>#include "mainwindow.h"
#include "pagefactory.h"
#include "dcppage.h"
#include <duinavigationbar.h>
#include <duideviceprofile.h>

MainWindow::MainWindow()
{
   connect(navigationBar(), SIGNAL(homeClicked()), this, SLOT(homeClicked()));
   connect(navigationBar(), SIGNAL(backClicked()), this, SLOT(backClicked()));
   Pages::Handle handle = {Pages::MAIN, ""};
   changePage(handle);
}

void MainWindow::homeClicked()
{
//   changePage(Pages::MAIN);
   onRotateClicked();
}

void MainWindow::backClicked()
{
    DcpPage* page = PageFactory::page(currentPage());
    changePage(page->referer());
}

MainWindow::~MainWindow()
{
}

void
MainWindow::changePage(Pages::Handle handle)
{

  if (handle.id == Pages::NOPAGE)
        return;
    DcpPage* page = PageFactory::instance()->create(handle.id, handle.param);
//    addPage(page);
    connect (page, SIGNAL(openSubPage(Pages::Handle)), this,
		SLOT(changePage(Pages::Handle)));
    qDebug() << Q_FUNC_INFO;
    DcpPage* oldPage = PageFactory::page(currentPage());
    if (oldPage)
      {
	if (page->referer().id == Pages::NOPAGE)
	    page->setReferer(oldPage->handle());
//	removePage(oldPage);
      }
    page->handle().id == Pages::MAIN ?
       navigationBar()->showCloseButton()
    :
       navigationBar()->showBackButton();

//    showPage(page);
   page->appearNow();

}
void MainWindow::onRotateClicked()
{
    DuiDeviceProfile *profile = DuiDeviceProfile::instance();
   // m_Category->onOrientationChange(profile->orientation());

    if ( profile->orientation() == Dui::Portrait ) {
        qDebug() << "mode changes to Angle0";
        profile->setOrientationAngle (DuiDeviceProfile::Angle0);
    } else {
        qDebug() << "mode changes to Angle90";
        profile->setOrientationAngle (DuiDeviceProfile::Angle90);
    }
}
<commit_msg>adjusting to DuiApplicationPage changes<commit_after>#include "mainwindow.h"
#include "pagefactory.h"
#include "dcppage.h"
#include <duinavigationbar.h>
#include <duideviceprofile.h>

MainWindow::MainWindow()
{
   connect(navigationBar(), SIGNAL(homeClicked()), this, SLOT(homeClicked()));
   connect(navigationBar(), SIGNAL(backClicked()), this, SLOT(backClicked()));
   Pages::Handle handle = {Pages::MAIN, ""};
   changePage(handle);
}

void MainWindow::homeClicked()
{
//   changePage(Pages::MAIN);
   onRotateClicked();
}

void MainWindow::backClicked()
{
    DcpPage* page = PageFactory::page(currentPage());
    changePage(page->referer());
}

MainWindow::~MainWindow()
{
}

void
MainWindow::changePage(Pages::Handle handle)
{

  if (handle.id == Pages::NOPAGE)
        return;
    DcpPage* page = PageFactory::instance()->create(handle.id, handle.param);
    connect (page, SIGNAL(openSubPage(Pages::Handle)), this,
		SLOT(changePage(Pages::Handle)));
    qDebug() << Q_FUNC_INFO;
    DcpPage* oldPage = PageFactory::page(currentPage());
    if (oldPage)
      {
	if (page->referer().id == Pages::NOPAGE)
	    page->setReferer(oldPage->handle());
	oldPage->dissappearNow();
      }
    page->handle().id == Pages::MAIN ?
       navigationBar()->showCloseButton()
    :
       navigationBar()->showBackButton();
   page->appearNow(DuiSceneWindow::DestroyWhenDone);

}
void MainWindow::onRotateClicked()
{
    DuiDeviceProfile *profile = DuiDeviceProfile::instance();
   // m_Category->onOrientationChange(profile->orientation());

    if ( profile->orientation() == Dui::Portrait ) {
        qDebug() << "mode changes to Angle0";
        profile->setOrientationAngle (DuiDeviceProfile::Angle0);
    } else {
        qDebug() << "mode changes to Angle90";
        profile->setOrientationAngle (DuiDeviceProfile::Angle90);
    }
}
<|endoftext|>


<commit_before>#pragma once

#include <utility>
#include <vector>
#include <cmath>
#include <fstream>
#include <iomanip>

#include "derivative.hpp"

namespace fp {

    template<typename Func, typename Float>
    std::tuple<std::vector<Float>, int, std::vector<Float>> fixed_point(const Func& g, Float x0, Float abstol)
    {
        // vector to store intermediate x_i values
        std::vector<Float> xvec;
        std::vector<Float> rvec; // vector of rate approximations

        // do the first iteration outside the while loop
        xvec.push_back(g(x0));
        Float currtol = static_cast<Float>(std::abs(xvec[0] - x0));

        // number of iterations : we have already performed one
        auto i = 1;
        Float rate = NAN;
        rvec.push_back(rate);

        Float x_iminus1;
        Float x_i;
        Float x_iplus1;
        Float deltaxp1;
        while (currtol > abstol)
        {
            x_iminus1 = xvec[i - 1];
            x_i = g(x_iminus1);
            xvec.push_back(x_i); // xi = g(x_{i - 1})
            x_iplus1 = g(x_i);
            currtol = std::abs(x_i - x_iminus1);
            deltaxp1 = std::abs(x_iplus1 - x_i);

            if ((i - 2) > 0) {
                rate = std::log(deltaxp1 / currtol) / std::log(currtol / std::abs(x_iminus1 - xvec[i - 2]));
                rvec.push_back(rate);
            } else {
                rvec.push_back(NAN);
            }

            ++i;
        }

        return std::make_tuple(xvec, i, rvec);
    }

    template<typename T> void printElement(T t, const int& width, std::ostream& stream)
    {
        static const char separator = ' ';
        stream << std::left << std::setw(width) << std::setfill(separator) << t;
    }

    template<typename Func, typename Float>
    void test_fixed_point(const Func& g, Float x0, Float abstol,
                          const std::string& funcname = "g", const std::string& filename = "test_g.txt")
    {
        const int nameWidth     = 24;
        const int numWidth      = 25;

        std::ofstream file;
        file.open(filename.c_str(), std::ios::out | std::ios::app);
        file << std::scientific << std::setprecision(15);
        file << "Getting the fixed points of '" << funcname
            << "' given x_0 = " << x0 << " and abstol = " << abstol << std::endl;

        auto tuple = fixed_point(g, x0, abstol);

        auto xvec = std::get<0>(tuple);
        auto iters = std::get<1>(tuple);
        auto rvec = std::get<2>(tuple);

        printElement("i", nameWidth, file);
        printElement("x_i", nameWidth, file);
        printElement("|x_i - x_{i - 1}|", nameWidth, file);
        printElement("rate", nameWidth, file);
        file << '\n';

        for (auto i = 0; i < xvec.size(); ++i)
        {
            printElement(i, numWidth, file);
            printElement(xvec[i], numWidth, file);
            if ((i - 1) >= 0) {
                printElement(std::abs(xvec[i] - xvec[i - 1]), numWidth, file);
            }
            printElement(rvec[i], numWidth, file);
            file << '\n';
        }

        file << "END" << std::endl;
    }

    void test_fp(double x0, double abstol)
    {
        const auto g1 = [](double x) -> double {
            return (x * x + 2) / 3;
        };

        // will result in NaNs because the value under the square root
        // will become negative at some point.
        const auto g2 = [](double x) -> double {
            return std::sqrt(3 * x - 2);
        };

        const auto g3 = [](double x) -> double {
            return 3 - (2 / x);
        };

        const auto g4 = [](double x) -> double {
            return (x * x  - 2) / (2 * x - 3);
        };

        std::vector<std::function<double(double)>> vec {g1, g2, g3, g4};
        std::vector<std::string> filenames {"g1.txt", "g2.txt", "g3.txt", "g4.txt"};
        std::vector<std::string> funcnames {"g1", "g2", "g3", "g4"};

        for (auto i = 0; i < vec.size(); ++i) {
            fp::test_fixed_point(vec[i], x0, abstol, funcnames[i], filenames[i]);
        }
    }

    template<typename Func, typename Float>
    std::tuple<std::vector<Float>, int, std::vector<Float>> newton_method(const Func& f, Float x0, Float abstol)
    {
        // vector to store intermediate x_i values
        std::vector<Float> xvec;
        std::vector<Float> rvec; // vector of rate approximations

        // do the first iteration outside the while loop
        auto x1 = x0 - (f(x0) / derivative(f, x0));
        xvec.push_back(x1);
        Float currtol = static_cast<Float>(std::abs(xvec[0] - x0));

        // number of iterations : we have already performed one
        auto i = 1;
        Float rate = NAN;
        rvec.push_back(rate);

        Float x_iminus1;
        Float x_i;
        Float x_iplus1;
        Float deltaxp1;
        while (currtol > abstol)
        {
            x_iminus1 = xvec[i - 1];
            x_i = x_iminus1 - (f(x_iminus1) / derivative(f, x_iminus1));
            xvec.push_back(x_i);
            x_iplus1 = x_i - (f(x_i) / derivative(f, x_i));
            currtol = std::abs(x_i - x_iminus1);
            deltaxp1 = std::abs(x_iplus1 - x_i);

            if ((i - 2) > 0) {
                rate = std::log(deltaxp1 / currtol) / std::log(currtol / std::abs(x_iminus1 - xvec[i - 2]));
                rvec.push_back(rate);
            } else {
                rvec.push_back(NAN);
            }

            ++i;
        }

        return std::make_tuple(xvec, i, rvec);
    }

    template<typename Func, typename Float>
    void test_newton_method(const Func& f, Float x0, Float abstol,
                            const std::string& funcname = "f", const std::string& filename = "test_f.txt")
    {
        const int nameWidth     = 24;
        const int numWidth      = 25;

        std::ofstream file;
        file.open(filename.c_str(), std::ios::out | std::ios::app);
        file << std::scientific << std::setprecision(15);
        file << "Getting the fixed points of '" << funcname
        << "' given x_0 = " << x0 << " and abstol = " << abstol << std::endl;

        auto tuple = newton_method(f, x0, abstol);

        auto xvec = std::get<0>(tuple);
        auto iters = std::get<1>(tuple);
        auto rvec = std::get<2>(tuple);

        printElement("i", nameWidth, file);
        printElement("x_i", nameWidth, file);
        printElement("|x_i - x_{i - 1}|", nameWidth, file);
        printElement("rate", nameWidth, file);
        file << '\n';

        for (auto i = 0; i < xvec.size(); ++i)
        {
            printElement(i, numWidth, file);
            printElement(xvec[i], numWidth, file);
            if ((i - 1) >= 0) {
                printElement(std::abs(xvec[i] - xvec[i - 1]), numWidth, file);
            }
            printElement(rvec[i], numWidth, file);
            file << '\n';
        }

        file << "END" << std::endl;
    }

    namespace newton {
        // we can't use functors with the derivative function
        // so we have to stick to traditional functions
        double f1(double x)
        {
            return x * x - 3 * x + 2;
        }

        double f2(double x)
        {
            return x * x * x - 2 * x - 5;
        }

        double f3(double x)
        {
            return std::exp(-x) - x;
        }

        double f4(double x)
        {
            return std::sin(x) * x - 1;
        }

        double f5(double x)
        {
            return x * x * x - 3 * x * x + 3 * x - 1;
        }
    }

    void test_newton(double abstol)
    {
        using namespace newton; // for functions f1 to f5

        std::vector<double (*)(double)> vec {f1, f2, f3, f4, f5};
        std::vector<std::string> filenames {"f1.txt", "f2.txt", "f3.txt", "f4.txt", "f5.txt"};
        std::vector<std::string> funcnames {"f1", "f2", "f3", "f4", "f5"};
        std::vector<double> xnaughts {2.1, 2.5, 0.6, 0.9, 0.5};

        for (auto i = 0; i < vec.size(); ++i) {
            test_newton_method(*vec[i], xnaughts[i], abstol, funcnames[i], filenames[i]);
        }
    }

    template<typename Func, typename Float>
    std::tuple<std::vector<Float>,
            int,
            std::vector<Float>>
    secant_method(const Func& f, Float x0, Float x1, Float abstol)
    {
        // vector to store intermediate x_i values
        std::vector<Float> xvec;
        std::vector<Float> rvec; // vector of rate approximations

        // do the first iteration outside the while loop
        xvec.push_back(x1);
        auto x2 = x1 - f(x1) * ((x1 - x0) / (f(x1) - f(x0)));
        xvec.push_back(x2);
        Float currtol = static_cast<Float>(std::abs(xvec[0] - x1));

        // number of iterations : we have already performed one
        auto i = 2;
        Float rate = NAN;
        rvec.push_back(rate);

        Float x_iminus2;
        Float x_iminus1;
        Float x_i;
        Float x_iplus1;
        Float deltaxp1;
        while (currtol > abstol)
        {
            x_iminus2 = xvec[i - 2];
            x_iminus1 = xvec[i - 1];
            x_i = x_iminus1 - f(x_iminus1) * ((x_iminus1 - x_iminus2) / (f(x_iminus1) - f(x_iminus2)));
            xvec.push_back(x_i);
            x_iplus1 = x_i - f(x_i) * ((x_i - x_iminus1) / (f(x_i) - f(x_iminus1)));
            currtol = std::abs(x_i - x_iminus1);
            deltaxp1 = std::abs(x_iplus1 - x_i);

            if ((i - 2) > 0) {
                rate = std::log(deltaxp1 / currtol) / std::log(currtol / std::abs(x_iminus1 - xvec[i - 2]));
                rvec.push_back(rate);
            } else {
                rvec.push_back(NAN);
            }

            ++i;
        }

        return std::make_tuple(xvec, i, rvec);
    }

    template<typename Float, typename = std::enable_if<std::is_arithmetic<Float>::value>::type>
    Float midpoint(Float a, Float b)
    {
        return a + (b - a) / 2;
    }

    template<typename Float, typename = std::enable_if<std::is_arithmetic<Float>::value>::type>
    int sign(Float a)
    {
        return a > 0 ? 1 : -1;
    }

    template<typename Func, typename Float>
    Float
    bisection_method(const Func& f, Float a, Float b, Float abstol, int numiters)
    {
        auto n = 1;
        Float c;
        Float l = a;
        Float u = b;
        while (n <= numiters)
        {
            c = midpoint(l, u);
            if ((u - l) < abstol) {
                break;
            }
            if (sign(f(c)) = sign(f(l))) {
                l = c;
            } else {
                b = c;
            }
            n++;
        }

        return c;
    }
}<commit_msg>There was a bug in the if statement of bisection. Also added the secant method testing code. Maybe we can refactor all of this.<commit_after>#pragma once

#include <utility>
#include <vector>
#include <cmath>
#include <fstream>
#include <iomanip>

#include "derivative.hpp"

namespace fp {

    template<typename Func, typename Float>
    std::tuple<std::vector<Float>, int, std::vector<Float>> fixed_point(const Func& g, Float x0, Float abstol)
    {
        // vector to store intermediate x_i values
        std::vector<Float> xvec;
        std::vector<Float> rvec; // vector of rate approximations

        // do the first iteration outside the while loop
        xvec.push_back(g(x0));
        Float currtol = static_cast<Float>(std::abs(xvec[0] - x0));

        // number of iterations : we have already performed one
        auto i = 1;
        Float rate = NAN;
        rvec.push_back(rate);

        Float x_iminus1;
        Float x_i;
        Float x_iplus1;
        Float deltaxp1;
        while (currtol > abstol)
        {
            x_iminus1 = xvec[i - 1];
            x_i = g(x_iminus1);
            xvec.push_back(x_i); // xi = g(x_{i - 1})
            x_iplus1 = g(x_i);
            currtol = std::abs(x_i - x_iminus1);
            deltaxp1 = std::abs(x_iplus1 - x_i);

            if ((i - 2) > 0) {
                rate = std::log(deltaxp1 / currtol) / std::log(currtol / std::abs(x_iminus1 - xvec[i - 2]));
                rvec.push_back(rate);
            } else {
                rvec.push_back(NAN);
            }

            ++i;
        }

        return std::make_tuple(xvec, i, rvec);
    }

    template<typename T> void printElement(T t, const int& width, std::ostream& stream)
    {
        static const char separator = ' ';
        stream << std::left << std::setw(width) << std::setfill(separator) << t;
    }

    template<typename Func, typename Float>
    void test_fixed_point(const Func& g, Float x0, Float abstol,
                          const std::string& funcname = "g", const std::string& filename = "test_g.txt")
    {
        const int nameWidth     = 24;
        const int numWidth      = 25;

        std::ofstream file;
        file.open(filename.c_str(), std::ios::out | std::ios::app);
        file << std::scientific << std::setprecision(15);
        file << "Getting the fixed points of '" << funcname
            << "' given x_0 = " << x0 << " and abstol = " << abstol << std::endl;

        auto tuple = fixed_point(g, x0, abstol);

        auto xvec = std::get<0>(tuple);
        auto iters = std::get<1>(tuple);
        auto rvec = std::get<2>(tuple);

        printElement("i", nameWidth, file);
        printElement("x_i", nameWidth, file);
        printElement("|x_i - x_{i - 1}|", nameWidth, file);
        printElement("rate", nameWidth, file);
        file << '\n';

        for (auto i = 0; i < xvec.size(); ++i)
        {
            printElement(i, numWidth, file);
            printElement(xvec[i], numWidth, file);
            if ((i - 1) >= 0) {
                printElement(std::abs(xvec[i] - xvec[i - 1]), numWidth, file);
            }
            printElement(rvec[i], numWidth, file);
            file << '\n';
        }

        file << "END" << std::endl;
    }

    void test_fp(double x0, double abstol)
    {
        const auto g1 = [](double x) -> double {
            return (x * x + 2) / 3;
        };

        // will result in NaNs because the value under the square root
        // will become negative at some point.
        const auto g2 = [](double x) -> double {
            return std::sqrt(3 * x - 2);
        };

        const auto g3 = [](double x) -> double {
            return 3 - (2 / x);
        };

        const auto g4 = [](double x) -> double {
            return (x * x  - 2) / (2 * x - 3);
        };

        std::vector<std::function<double(double)>> vec {g1, g2, g3, g4};
        std::vector<std::string> filenames {"g1.txt", "g2.txt", "g3.txt", "g4.txt"};
        std::vector<std::string> funcnames {"g1", "g2", "g3", "g4"};

        for (auto i = 0; i < vec.size(); ++i) {
            fp::test_fixed_point(vec[i], x0, abstol, funcnames[i], filenames[i]);
        }
    }

    template<typename Func, typename Float>
    std::tuple<std::vector<Float>, int, std::vector<Float>> newton_method(const Func& f, Float x0, Float abstol)
    {
        // vector to store intermediate x_i values
        std::vector<Float> xvec;
        std::vector<Float> rvec; // vector of rate approximations

        // do the first iteration outside the while loop
        auto x1 = x0 - (f(x0) / derivative(f, x0));
        xvec.push_back(x1);
        Float currtol = static_cast<Float>(std::abs(xvec[0] - x0));

        // number of iterations : we have already performed one
        auto i = 1;
        Float rate = NAN;
        rvec.push_back(rate);

        Float x_iminus1;
        Float x_i;
        Float x_iplus1;
        Float deltaxp1;
        while (currtol > abstol)
        {
            x_iminus1 = xvec[i - 1];
            x_i = x_iminus1 - (f(x_iminus1) / derivative(f, x_iminus1));
            xvec.push_back(x_i);
            x_iplus1 = x_i - (f(x_i) / derivative(f, x_i));
            currtol = std::abs(x_i - x_iminus1);
            deltaxp1 = std::abs(x_iplus1 - x_i);

            if ((i - 2) > 0) {
                rate = std::log(deltaxp1 / currtol) / std::log(currtol / std::abs(x_iminus1 - xvec[i - 2]));
                rvec.push_back(rate);
            } else {
                rvec.push_back(NAN);
            }

            ++i;
        }

        return std::make_tuple(xvec, i, rvec);
    }

    template<typename Func, typename Float>
    void test_newton_method(const Func& f, Float x0, Float abstol,
                            const std::string& funcname = "f", const std::string& filename = "test_f.txt")
    {
        const int nameWidth     = 24;
        const int numWidth      = 25;

        std::ofstream file;
        file.open(filename.c_str(), std::ios::out | std::ios::app);
        file << std::scientific << std::setprecision(15);
        file << "Getting the roots of '" << funcname
        << "' given x_0 = " << x0 << " and abstol = " << abstol << std::endl;

        auto tuple = newton_method(f, x0, abstol);

        auto xvec = std::get<0>(tuple);
        auto iters = std::get<1>(tuple);
        auto rvec = std::get<2>(tuple);

        printElement("i", nameWidth, file);
        printElement("x_i", nameWidth, file);
        printElement("|x_i - x_{i - 1}|", nameWidth, file);
        printElement("rate", nameWidth, file);
        file << '\n';

        for (auto i = 0; i < xvec.size(); ++i)
        {
            printElement(i, numWidth, file);
            printElement(xvec[i], numWidth, file);
            if ((i - 1) >= 0) {
                printElement(std::abs(xvec[i] - xvec[i - 1]), numWidth, file);
            }
            printElement(rvec[i], numWidth, file);
            file << '\n';
        }

        file << "END" << std::endl;
    }

    namespace newton {
        // we can't use functors with the derivative function
        // so we have to stick to traditional functions
        double f1(double x)
        {
            return x * x - 3 * x + 2;
        }

        double f2(double x)
        {
            return x * x * x - 2 * x - 5;
        }

        double f3(double x)
        {
            return std::exp(-x) - x;
        }

        double f4(double x)
        {
            return std::sin(x) * x - 1;
        }

        double f5(double x)
        {
            return x * x * x - 3 * x * x + 3 * x - 1;
        }
    }

    void test_newton(double abstol)
    {
        using namespace newton; // for functions f1 to f5

        std::vector<double (*)(double)> vec {f1, f2, f3, f4, f5};
        std::vector<std::string> filenames {"f1.txt", "f2.txt", "f3.txt", "f4.txt", "f5.txt"};
        std::vector<std::string> funcnames {"f1", "f2", "f3", "f4", "f5"};
        std::vector<double> xnaughts {2.1, 2.5, 0.6, 0.9, 0.5};

        for (auto i = 0; i < vec.size(); ++i) {
            test_newton_method(*vec[i], xnaughts[i], abstol, funcnames[i], filenames[i]);
        }
    }

    template<typename Func, typename Float>
    std::tuple<std::vector<Float>,
            int,
            std::vector<Float>>
    secant_method(const Func& f, Float x0, Float x1, Float abstol)
    {
        // vector to store intermediate x_i values
        std::vector<Float> xvec;
        std::vector<Float> rvec; // vector of rate approximations

        // do the first iteration outside the while loop
        xvec.push_back(x1);
        auto x2 = x1 - f(x1) * ((x1 - x0) / (f(x1) - f(x0)));
        xvec.push_back(x2);
        Float currtol = static_cast<Float>(std::abs(xvec[0] - x1));

        // number of iterations : we have already performed one
        auto i = 2;
        Float rate = NAN;
        rvec.push_back(rate);

        Float x_iminus2;
        Float x_iminus1;
        Float x_i;
        Float x_iplus1;
        Float deltaxp1;
        while (currtol > abstol)
        {
            x_iminus2 = xvec[i - 2];
            x_iminus1 = xvec[i - 1];
            x_i = x_iminus1 - f(x_iminus1) * ((x_iminus1 - x_iminus2) / (f(x_iminus1) - f(x_iminus2)));
            xvec.push_back(x_i);
            x_iplus1 = x_i - f(x_i) * ((x_i - x_iminus1) / (f(x_i) - f(x_iminus1)));
            currtol = std::abs(x_i - x_iminus1);
            deltaxp1 = std::abs(x_iplus1 - x_i);

            if ((i - 2) > 0) {
                rate = std::log(deltaxp1 / currtol) / std::log(currtol / std::abs(x_iminus1 - xvec[i - 2]));
                rvec.push_back(rate);
            } else {
                rvec.push_back(NAN);
            }

            ++i;
        }

        return std::make_tuple(xvec, i, rvec);
    }

    template<typename Func, typename Float>
    void test_secant_method(const Func& f, Float x0, Float x1, Float abstol,
                            const std::string& funcname = "f", const std::string& filename = "test_f.txt")
    {
        const int nameWidth     = 24;
        const int numWidth      = 25;

        std::ofstream file;
        file.open(filename.c_str(), std::ios::out | std::ios::app);
        file << std::scientific << std::setprecision(15);
        file << "Getting the roots of '" << funcname
        << "' given x_0 = " << x0 << ", x_1 = " << x1 << " and abstol = " << abstol << std::endl;

        auto tuple = secant_method(f, x0, x1, abstol);

        auto xvec = std::get<0>(tuple);
        auto iters = std::get<1>(tuple);
        auto rvec = std::get<2>(tuple);

        printElement("i", nameWidth, file);
        printElement("x_i", nameWidth, file);
        printElement("|x_i - x_{i - 1}|", nameWidth, file);
        printElement("rate", nameWidth, file);
        file << '\n';

        for (auto i = 0; i < xvec.size(); ++i)
        {
            printElement(i, numWidth, file);
            printElement(xvec[i], numWidth, file);
            if ((i - 1) >= 0) {
                printElement(std::abs(xvec[i] - xvec[i - 1]), numWidth, file);
            }
            printElement(rvec[i], numWidth, file);
            file << '\n';
        }

        file << "END" << std::endl;
    }

    template<typename Float, typename = std::enable_if<std::is_arithmetic<Float>::value>::type>
    Float midpoint(Float a, Float b)
    {
        return a + (b - a) / 2;
    }

    template<typename Float, typename = std::enable_if<std::is_arithmetic<Float>::value>::type>
    int sign(Float a)
    {
        return a > 0 ? 1 : -1;
    }

    template<typename Func, typename Float>
    Float
    bisection_method(const Func& f, Float a, Float b, Float abstol, int numiters)
    {
        auto n = 1;
        Float c;
        Float l = a;
        Float u = b;
        while (n <= numiters)
        {
            c = midpoint(l, u);
            if ((u - l) < abstol) {
                break;
            }
            if (sign(f(c)) == sign(f(l))) {
                l = c;
            } else {
                b = c;
            }
            n++;
        }

        return c;
    }
}<|endoftext|>


<commit_before>#include "mapgeneratorwindow.h"
#include "ui_mapgeneratorwindow.h"

#include <QFileDialog>
#include <QValidator>

#include <JoshMath.h>

MapGeneratorWindow::MapGeneratorWindow(QWidget *parent)
	: QMainWindow(parent)
	, ui(new Ui::MapGeneratorWindow)
{
    ui->setupUi(this);
}

MapGeneratorWindow::~MapGeneratorWindow()
{
    delete ui;
}

void MapGeneratorWindow::init()
{
	// popupate the selectable input map combo box (this might be refactored out later)
	QStringList inputMapTypes;
	inputMapTypes.push_back("Diffuse Map");
	inputMapTypes.push_back("Height Map");

	ui->comboBox_inputMapType->addItems(inputMapTypes);

	ui->comboBox_inputMapType->setCurrentIndex(0);

	QStringList outputMapTypes;
	outputMapTypes.push_back("Normal Map");
	outputMapTypes.push_back("Edge Map");

	ui->comboBox_->addItems(outputMapTypes);
	ui->comboBox_->setCurrentIndex(1);

	// connect ui object to correct methods
	connect(ui->actionSet_Input_Map, &QAction::triggered, this, &MapGeneratorWindow::onOpenMap);
	connect(ui->pushButton_generateMap, &QPushButton::pressed, this, &MapGeneratorWindow::onGenerateMapButtonPressed);
	connect(ui->actionSave_Output_Map, &QAction::triggered, this, &MapGeneratorWindow::onSaveOutputMap);

	// disable the generate button (gets re enabled once an input map is provided)
	ui->pushButton_generateMap->setDisabled(true);

	// add QValidator objects for the
	ui->lineEdit_bumpAmp->setValidator(new QDoubleValidator());
	ui->lineEdit_edgeMapSensivity->setValidator(new QIntValidator(0, 255 * 3));
}

void MapGeneratorWindow::onOpenMap()
{
	// just deal with image files
	QString inputFileName = QFileDialog::getOpenFileName(this, tr("Select an Image file"), QString(""), tr("Image files (*.bmp;*.jpg;*.png)"));

	if (inputFileName == QString())
	{
		// no file has been selected
		return;
	}

	QPixmap imagePixelMap(inputFileName);

	ui->label_inputMap->setPixmap(imagePixelMap);

	// enable the generate button
	ui->pushButton_generateMap->setDisabled(false);
}

void MapGeneratorWindow::onSaveOutputMap()
{
	// make sure that theres a map to save, if not return

	const QPixmap * outputImage = ui->label_outputMap->pixmap();

	if (outputImage)
	{
		QString saveFileStr = QFileDialog::getSaveFileName(this, tr("Save output"), "", tr("Images (*.png)"));
		if (saveFileStr != QString())
		{
			// save the file
			outputImage->save(saveFileStr, "png");
		}
	}
}

void MapGeneratorWindow::onGenerateMapButtonPressed()
{
	/*
	1. check the input and output combo boxes are for the correct map type
	2. check that the map generation controls aren't values that will crash the program
	3. once validation has been passed call the correct generation method
	*/

	if (!validateInputs())
	{
		return;
	}

	// clear the output label pixel map
	QPixmap defaultMap(10, 10);
	ui->label_outputMap->setPixmap(defaultMap);

	if (ui->comboBox_->currentText().toStdString() == "Normal Map")
	{
		float ampVal = 1.0f;
		if (ui->lineEdit_bumpAmp->text().toStdString() != "")
		{
			ampVal = ui->lineEdit_bumpAmp->text().toFloat();
		}
		generateNormalMap(ampVal);
	}
	else if (ui->comboBox_->currentText().toStdString() == "Edge Map")
	{
		int sensitivityVal = 50;
		if (ui->lineEdit_edgeMapSensivity->text().toStdString() != "")
		{
			sensitivityVal = ui->lineEdit_edgeMapSensivity->text().toInt();
		}
		generateEdgeMap(sensitivityVal);
	}
}

bool MapGeneratorWindow::validateInputs()
{
	if (!validateInputMapCorrectForOutput())
	{
		return false;
	}

	// add additional validation here if needed

	return true;
}

bool MapGeneratorWindow::validateInputMapCorrectForOutput()
{
	// if diffuse map, then edge map
	// if height map, then normal map

	if (ui->comboBox_inputMapType->currentText().toStdString() == "Diffuse Map")
	{
		if (ui->comboBox_->currentText().toStdString() == "Edge Map")
		{
			return true;
		}
	}
	else if (ui->comboBox_inputMapType->currentText().toStdString() == "Height Map")
	{

		if (ui->comboBox_->currentText().toStdString() == "Normal Map")
		{
			return true;
		}
		else if (ui->comboBox_->currentText().toStdString() == "Edge Map")
		{
			return true;
		}
	}

	return false;
}

void MapGeneratorWindow::generateEdgeMap(int sensitivity)
{
	// clear the current output map
	ui->label_outputMap->clear();

	const QPixmap * inputPixelMap = ui->label_inputMap->pixmap();

	const QImage originalImage = inputPixelMap->toImage();

	QImage generatedMap(originalImage);

	int originalImageWidth = originalImage.width(),
		originalImageHeight = originalImage.height();

	QRgb primaryColour = qRgb(0, 0, 0);
	QRgb edgeColour = qRgb(255, 255, 255);

	for (size_t i = 0; i < originalImageWidth; ++i)
	{
		for (size_t j = 0; j < originalImageHeight; ++j)
		{
			generatedMap.setPixelColor(i, j, primaryColour);
		}
	}

	// refactor to use the matrix approach later

	// now run the edge detection step

	// vertical scan
	for (int x = 0; x < originalImageWidth; ++x)
	{
		for (int y = 1; y < originalImageHeight; ++y)
		{
			// if it's an edge set the pixel to the edge colour
			const QRgb lastPx = originalImage.pixel(x, y - 1);
			const QRgb currentPx = originalImage.pixel(x, y);

			int diff = difference(lastPx, currentPx);

			if (diff > sensitivity)
			{
				generatedMap.setPixelColor(x, y, edgeColour);
			}
		}
	}

	// horisontal scan
	for (int y = 0; y < originalImageHeight; ++y)
	{
		for (int x = 1; x < originalImageWidth; ++x)
		{
			// if it's an edge set the pixel to the edge colour
			const QRgb lastPx = originalImage.pixel(x - 1, y);
			const QRgb currentPx = originalImage.pixel(x, y);

			int diff = difference(lastPx, currentPx);

			if (diff > sensitivity)
			{
				generatedMap.setPixelColor(x, y, edgeColour);
			}
		}
	}

	QPixmap outputPixelMap = QPixmap::fromImage(generatedMap);
	ui->label_outputMap->setPixmap(outputPixelMap);
}

void MapGeneratorWindow::generateNormalMap(float amplertude)
{
	const QPixmap * inputPixelMap = ui->label_inputMap->pixmap();

	const QImage originalImage = inputPixelMap->toImage();

	QImage generatedMap(originalImage);

	int originalImageWidth = originalImage.width(),
		originalImageHeight = originalImage.height();

	int halfWayWidth = originalImageWidth / 2;
	int halfWayHeight = originalImageHeight / 2;

	QRgb primaryColour = qRgb(0, 0, 0);
	QRgb secondaryColour = qRgb(255, 255, 255);

	for (size_t i = 0; i < originalImageWidth; ++i)
	{
		for (size_t j = 0; j < originalImageHeight; ++j)
		{
			bool pastHalfWayPointX = i > halfWayWidth;
			bool pastHalfWayPointY = j > halfWayHeight;

			bool usePrimaryColour = pastHalfWayPointX ^ pastHalfWayPointY;

			if (usePrimaryColour)
			{
				generatedMap.setPixelColor(i, j, primaryColour);
			}
			else
			{
				generatedMap.setPixelColor(i, j, secondaryColour);
			}

		}
	}

	QPixmap outputPixelMap = QPixmap::fromImage(generatedMap);
	ui->label_outputMap->setPixmap(outputPixelMap);
}

inline unsigned int MapGeneratorWindow::difference(const QRgb a, const QRgb b)
{
	int aRed = qRed(a);
	int aGreen = qGreen(a);
	int aBlue = qBlue(a);

	int bRed = qRed(b);
	int bGreen = qGreen(b);
	int bBlue = qBlue(b);

	int diff = 0;
	diff += abs(aRed - bRed);
	diff += abs(aGreen - bGreen);
	diff += abs(aBlue- bBlue);
	return diff;
}<commit_msg>Partial progress in normal map generator<commit_after>#include "mapgeneratorwindow.h"
#include "ui_mapgeneratorwindow.h"

#include <QFileDialog>
#include <QValidator>

#include <JoshMath.h>

MapGeneratorWindow::MapGeneratorWindow(QWidget *parent)
	: QMainWindow(parent)
	, ui(new Ui::MapGeneratorWindow)
{
    ui->setupUi(this);
}

MapGeneratorWindow::~MapGeneratorWindow()
{
    delete ui;
}

void MapGeneratorWindow::init()
{
	// popupate the selectable input map combo box (this might be refactored out later)
	QStringList inputMapTypes;
	inputMapTypes.push_back("Diffuse Map");
	inputMapTypes.push_back("Height Map");

	ui->comboBox_inputMapType->addItems(inputMapTypes);

	ui->comboBox_inputMapType->setCurrentIndex(0);

	QStringList outputMapTypes;
	outputMapTypes.push_back("Normal Map");
	outputMapTypes.push_back("Edge Map");

	ui->comboBox_->addItems(outputMapTypes);
	ui->comboBox_->setCurrentIndex(1);

	// connect ui object to correct methods
	connect(ui->actionSet_Input_Map, &QAction::triggered, this, &MapGeneratorWindow::onOpenMap);
	connect(ui->pushButton_generateMap, &QPushButton::pressed, this, &MapGeneratorWindow::onGenerateMapButtonPressed);
	connect(ui->actionSave_Output_Map, &QAction::triggered, this, &MapGeneratorWindow::onSaveOutputMap);

	// disable the generate button (gets re enabled once an input map is provided)
	ui->pushButton_generateMap->setDisabled(true);

	// add QValidator objects for the
	ui->lineEdit_bumpAmp->setValidator(new QDoubleValidator());
	ui->lineEdit_edgeMapSensivity->setValidator(new QIntValidator(0, 255 * 3));
}

void MapGeneratorWindow::onOpenMap()
{
	// just deal with image files
	QString inputFileName = QFileDialog::getOpenFileName(this, tr("Select an Image file"), QString(""), tr("Image files (*.bmp;*.jpg;*.png)"));

	if (inputFileName == QString())
	{
		// no file has been selected
		return;
	}

	QPixmap imagePixelMap(inputFileName);

	ui->label_inputMap->setPixmap(imagePixelMap);

	// enable the generate button
	ui->pushButton_generateMap->setDisabled(false);
}

void MapGeneratorWindow::onSaveOutputMap()
{
	// make sure that theres a map to save, if not return

	const QPixmap * outputImage = ui->label_outputMap->pixmap();

	if (outputImage)
	{
		QString saveFileStr = QFileDialog::getSaveFileName(this, tr("Save output"), "", tr("Images (*.png)"));
		if (saveFileStr != QString())
		{
			// save the file
			outputImage->save(saveFileStr, "png");
		}
	}
}

void MapGeneratorWindow::onGenerateMapButtonPressed()
{
	/*
	1. check the input and output combo boxes are for the correct map type
	2. check that the map generation controls aren't values that will crash the program
	3. once validation has been passed call the correct generation method
	*/

	if (!validateInputs())
	{
		return;
	}

	// clear the output label pixel map
	QPixmap defaultMap(10, 10);
	ui->label_outputMap->setPixmap(defaultMap);

	if (ui->comboBox_->currentText().toStdString() == "Normal Map")
	{
		float ampVal = 1.0f;
		if (ui->lineEdit_bumpAmp->text().toStdString() != "")
		{
			ampVal = ui->lineEdit_bumpAmp->text().toFloat();
		}
		generateNormalMap(ampVal);
	}
	else if (ui->comboBox_->currentText().toStdString() == "Edge Map")
	{
		int sensitivityVal = 50;
		if (ui->lineEdit_edgeMapSensivity->text().toStdString() != "")
		{
			sensitivityVal = ui->lineEdit_edgeMapSensivity->text().toInt();
		}
		generateEdgeMap(sensitivityVal);
	}
}

bool MapGeneratorWindow::validateInputs()
{
	if (!validateInputMapCorrectForOutput())
	{
		return false;
	}

	// add additional validation here if needed

	return true;
}

bool MapGeneratorWindow::validateInputMapCorrectForOutput()
{
	// if diffuse map, then edge map
	// if height map, then normal map

	if (ui->comboBox_inputMapType->currentText().toStdString() == "Diffuse Map")
	{
		if (ui->comboBox_->currentText().toStdString() == "Edge Map")
		{
			return true;
		}
	}
	else if (ui->comboBox_inputMapType->currentText().toStdString() == "Height Map")
	{

		if (ui->comboBox_->currentText().toStdString() == "Normal Map")
		{
			return true;
		}
		else if (ui->comboBox_->currentText().toStdString() == "Edge Map")
		{
			return true;
		}
	}

	return false;
}

void MapGeneratorWindow::generateEdgeMap(int sensitivity)
{
	// clear the current output map
	ui->label_outputMap->clear();

	const QPixmap * inputPixelMap = ui->label_inputMap->pixmap();

	const QImage originalImage = inputPixelMap->toImage();

	QImage generatedMap(originalImage);

	int originalImageWidth = originalImage.width(),
		originalImageHeight = originalImage.height();

	QRgb primaryColour = qRgb(0, 0, 0);
	QRgb edgeColour = qRgb(255, 255, 255);

	for (size_t i = 0; i < originalImageWidth; ++i)
	{
		for (size_t j = 0; j < originalImageHeight; ++j)
		{
			generatedMap.setPixelColor(i, j, primaryColour);
		}
	}

	// refactor to use the matrix approach later

	// now run the edge detection step

	// vertical scan
	for (int x = 0; x < originalImageWidth; ++x)
	{
		for (int y = 1; y < originalImageHeight; ++y)
		{
			// if it's an edge set the pixel to the edge colour
			const QRgb lastPx = originalImage.pixel(x, y - 1);
			const QRgb currentPx = originalImage.pixel(x, y);

			int diff = difference(lastPx, currentPx);

			if (diff > sensitivity)
			{
				generatedMap.setPixelColor(x, y, edgeColour);
			}
		}
	}

	// horisontal scan
	for (int y = 0; y < originalImageHeight; ++y)
	{
		for (int x = 1; x < originalImageWidth; ++x)
		{
			// if it's an edge set the pixel to the edge colour
			const QRgb lastPx = originalImage.pixel(x - 1, y);
			const QRgb currentPx = originalImage.pixel(x, y);

			int diff = difference(lastPx, currentPx);

			if (diff > sensitivity)
			{
				generatedMap.setPixelColor(x, y, edgeColour);
			}
		}
	}

	QPixmap outputPixelMap = QPixmap::fromImage(generatedMap);
	ui->label_outputMap->setPixmap(outputPixelMap);
}

void MapGeneratorWindow::generateNormalMap(float amplertude)
{
	const QPixmap * inputPixelMap = ui->label_inputMap->pixmap();

	const QImage originalImage = inputPixelMap->toImage();

	QImage generatedMap(originalImage);

	int originalImageWidth = originalImage.width(),
		originalImageHeight = originalImage.height();

	const float imageAspectRatio = (float)originalImageWidth / (float)originalImageHeight;

	float heightPxLeftOfCurrent = 0.0f;
	float heightPxRightOfCurrent = 0.0f;
	float heightPxUpOfCurrent = 0.0f;
	float heightPxDownOfCurrent = 0.0f;

	for (int pxPosX = 0; pxPosX < originalImageWidth; ++pxPosX)
	{
		for (int pxPosY = 0; pxPosY < originalImageHeight; ++pxPosY)
		{
			// 0 everything, the edges will assume 0.0
			float heightPxLeftOfCurrent = 0.0f;
			float heightPxRightOfCurrent = 0.0f;
			float heightPxUpOfCurrent = 0.0f;
			float heightPxDownOfCurrent = 0.0f;

			// pick up here from the first commit dev branch, main.cpp, generateBumpMap(), ln 129 +
		}
	}

	QPixmap outputPixelMap = QPixmap::fromImage(generatedMap);
	ui->label_outputMap->setPixmap(outputPixelMap);
}

inline unsigned int MapGeneratorWindow::difference(const QRgb a, const QRgb b)
{
	int aRed = qRed(a);
	int aGreen = qGreen(a);
	int aBlue = qBlue(a);

	int bRed = qRed(b);
	int bGreen = qGreen(b);
	int bBlue = qBlue(b);

	int diff = 0;
	diff += abs(aRed - bRed);
	diff += abs(aGreen - bGreen);
	diff += abs(aBlue- bBlue);
	return diff;
}<|endoftext|>


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

#include <Arduino.h>
#include "Solenoid.h"
#include "App.h"

// Give time for the disk to fall out of the RFID sensor field
#define SOLENOID_WAITING_TIME 1000 // msec

void Solenoid::begin() {
    off();
    pinMode(_impulsePin, OUTPUT);
    _state = SOLENOID_IDLE;
    _sensorState = NO_CARD;
}

void Solenoid::on() {
    digitalWrite(_impulsePin, LOW);
    _sensorState = NO_CARD; // see in tick to find out why this is here.
}

void Solenoid::off() {
    digitalWrite(_impulsePin, HIGH);
}

void Solenoid::fire(long t) {
    _timestamp = t;
    on();
}

void Solenoid::release(long t) {
    _timestamp = t;
    off();
    _led.off();
}

void Solenoid::tick() {
    long now = millis();
    // Read sensor state
    enum rfidSensorStatus newSensorState = _sensor.rfidSensorStatus();
    // If we have a card, so we save this in the _sensorState attribute.
    // We will receive this information only once, and it might arrive
    // during a "FROZEN" state, so we have to save it. We will put it
    // back to NO_CARD only when we pull the solenoid.
    if (newSensorState == VALID_CARD || newSensorState == INVALID_CARD) {
        _sensorState = newSensorState;
    }

    switch (_state) {
    case SOLENOID_IDLE:
        if (app.emergency) {
            fire(now);
            _state = SOLENOID_FIRED;
            _led.green();
        } else if (_sensorState == VALID_CARD) {
            _led.green();
            _timestamp = now;
            _state = SOLENOID_FROZEN;
        } else if (_sensorState == INVALID_CARD) {
            _led.red();
            _timestamp = now;
            _state = SOLENOID_FROZEN;
        } else { // Idle and no reason to change.
            off();
            _led.off();
        }
        break;

    case SOLENOID_FROZEN:
        if (now - _timestamp > app.DF) {
            fire(now);
            _state = SOLENOID_FIRED;
            // I decided to not clear the LED here. It will stay
            // a little bit longer and will be cleared in the next state.
        } break;

    case SOLENOID_FIRED:
        if (now - _timestamp > app.DI) {
            release(now);
            _state = SOLENOID_WAITING;
        } break;

    case SOLENOID_WAITING:
        if (now - _timestamp > SOLENOID_WAITING_TIME) {
            _state = SOLENOID_IDLE;
        } break;

    default: {
        _state = SOLENOID_IDLE;
        break;
    }
    }
};

int Solenoid::selfCheck0() {
    _led.red();
    on();
    delay(200);
    return 0;
}

int Solenoid::selfCheck1() {
    _led.green();
    off();
    delay(200);
    return 0;
}

int Solenoid::selfCheck2() {
    _led.off();
    return 0;
}
<commit_msg>Change: improve RFID - Solenoid interaction<commit_after>/****************************************************************************
 * Copyright 2016 BlueMasters
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include <Arduino.h>
#include "Solenoid.h"
#include "App.h"

// Give time for the disk to fall out of the RFID sensor field
#define SOLENOID_WAITING_TIME 1000 // msec

void Solenoid::begin() {
    off();
    pinMode(_impulsePin, OUTPUT);
    _state = SOLENOID_IDLE;
    _sensorState = NO_CARD;
}

void Solenoid::on() {
    digitalWrite(_impulsePin, LOW);
}

void Solenoid::off() {
    digitalWrite(_impulsePin, HIGH);
}

void Solenoid::fire(long t) {
    _timestamp = t;
    on();
}

void Solenoid::release(long t) {
    _timestamp = t;
    off();
    _led.off();
}

void Solenoid::tick() {
    long now = millis();
    // Read sensor state
    enum rfidSensorStatus newSensorState = _sensor.rfidSensorStatus();
    // If we have a card, so we save this in the _sensorState attribute.
    // We will receive this information only once, and it might arrive
    // during a "FROZEN" state, so we have to save it.
    if (newSensorState == VALID_CARD || newSensorState == INVALID_CARD) {
        _sensorState = newSensorState;
    }

    switch (_state) {
    case SOLENOID_IDLE:
        if (app.emergency) {
            fire(now);
            _state = SOLENOID_FIRED;
            _led.green();
        } else if (_sensorState == VALID_CARD) {
            _led.green();
            _timestamp = now;
            _state = SOLENOID_FROZEN;
            _sensorState = NO_CARD;
        } else if (_sensorState == INVALID_CARD) {
            _led.red();
            _timestamp = now;
            _state = SOLENOID_FROZEN;
            _sensorState = NO_CARD;
        } else { // Idle and no reason to change.
            off();
            _led.off();
        }
        break;

    case SOLENOID_FROZEN:
        if (now - _timestamp > app.DF) {
            fire(now);
            _state = SOLENOID_FIRED;
            // I decided to not clear the LED here. It will stay
            // a little bit longer and will be cleared in the next state.
        } break;

    case SOLENOID_FIRED:
        if (now - _timestamp > app.DI) {
            release(now);
            _state = SOLENOID_WAITING;
        } break;

    case SOLENOID_WAITING:
        if (now - _timestamp > SOLENOID_WAITING_TIME) {
            _state = SOLENOID_IDLE;
        } break;

    default: {
        _state = SOLENOID_IDLE;
        break;
    }
    }
};

int Solenoid::selfCheck0() {
    _led.red();
    on();
    delay(200);
    return 0;
}

int Solenoid::selfCheck1() {
    _led.green();
    off();
    delay(200);
    return 0;
}

int Solenoid::selfCheck2() {
    _led.off();
    return 0;
}
<|endoftext|>


<commit_before>//===--- StringMap.cpp - String Hash table map implementation -------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Chris Lattner and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the StringMap class.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/StringMap.h"
#include <cassert>
using namespace llvm;

StringMapImpl::StringMapImpl(unsigned InitSize, unsigned itemSize) {
  ItemSize = itemSize;

  // If a size is specified, initialize the table with that many buckets.
  if (InitSize) {
    init(InitSize);
    return;
  }

  // Otherwise, initialize it with zero buckets to avoid the allocation.
  TheTable = 0;
  NumBuckets = 0;
  NumItems = 0;
  NumTombstones = 0;
}

void StringMapImpl::init(unsigned InitSize) {
  assert((InitSize & (InitSize-1)) == 0 &&
         "Init Size must be a power of 2 or zero!");
  NumBuckets = InitSize ? InitSize : 16;
  NumItems = 0;
  NumTombstones = 0;

  TheTable = (ItemBucket*)calloc(NumBuckets+1, sizeof(ItemBucket));

  // Allocate one extra bucket, set it to look filled so the iterators stop at
  // end.
  TheTable[NumBuckets].Item = (StringMapEntryBase*)2;
}

/// HashString - Compute a hash code for the specified string.
///
static unsigned HashString(const char *Start, const char *End) {
  // Bernstein hash function.
  unsigned int Result = 0;
  // TODO: investigate whether a modified bernstein hash function performs
  // better: http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx
  //   X*33+c -> X*33^c
  while (Start != End)
    Result = Result * 33 + *Start++;
  Result = Result + (Result >> 5);
  return Result;
}

/// LookupBucketFor - Look up the bucket that the specified string should end
/// up in.  If it already exists as a key in the map, the Item pointer for the
/// specified bucket will be non-null.  Otherwise, it will be null.  In either
/// case, the FullHashValue field of the bucket will be set to the hash value
/// of the string.
unsigned StringMapImpl::LookupBucketFor(const char *NameStart,
                                        const char *NameEnd) {
  unsigned HTSize = NumBuckets;
  if (HTSize == 0) {  // Hash table unallocated so far?
    init(16);
    HTSize = NumBuckets;
  }
  unsigned FullHashValue = HashString(NameStart, NameEnd);
  unsigned BucketNo = FullHashValue & (HTSize-1);

  unsigned ProbeAmt = 1;
  int FirstTombstone = -1;
  while (1) {
    ItemBucket &Bucket = TheTable[BucketNo];
    StringMapEntryBase *BucketItem = Bucket.Item;
    // If we found an empty bucket, this key isn't in the table yet, return it.
    if (BucketItem == 0) {
      // If we found a tombstone, we want to reuse the tombstone instead of an
      // empty bucket.  This reduces probing.
      if (FirstTombstone != -1) {
        TheTable[FirstTombstone].FullHashValue = FullHashValue;
        return FirstTombstone;
      }

      Bucket.FullHashValue = FullHashValue;
      return BucketNo;
    }

    if (BucketItem == getTombstoneVal()) {
      // Skip over tombstones.  However, remember the first one we see.
      if (FirstTombstone == -1) FirstTombstone = BucketNo;
    } else if (Bucket.FullHashValue == FullHashValue) {
      // If the full hash value matches, check deeply for a match.  The common
      // case here is that we are only looking at the buckets (for item info
      // being non-null and for the full hash value) not at the items.  This
      // is important for cache locality.

      // Do the comparison like this because NameStart isn't necessarily
      // null-terminated!
      char *ItemStr = (char*)BucketItem+ItemSize;
      unsigned ItemStrLen = BucketItem->getKeyLength();
      if (unsigned(NameEnd-NameStart) == ItemStrLen &&
          memcmp(ItemStr, NameStart, ItemStrLen) == 0) {
        // We found a match!
        return BucketNo;
      }
    }

    // Okay, we didn't find the item.  Probe to the next bucket.
    BucketNo = (BucketNo+ProbeAmt) & (HTSize-1);

    // Use quadratic probing, it has fewer clumping artifacts than linear
    // probing and has good cache behavior in the common case.
    ++ProbeAmt;
  }
}

/// FindKey - Look up the bucket that contains the specified key. If it exists
/// in the map, return the bucket number of the key.  Otherwise return -1.
/// This does not modify the map.
int StringMapImpl::FindKey(const char *KeyStart, const char *KeyEnd) const {
  unsigned HTSize = NumBuckets;
  if (HTSize == 0) return -1;  // Really empty table?
  unsigned FullHashValue = HashString(KeyStart, KeyEnd);
  unsigned BucketNo = FullHashValue & (HTSize-1);

  unsigned ProbeAmt = 1;
  while (1) {
    ItemBucket &Bucket = TheTable[BucketNo];
    StringMapEntryBase *BucketItem = Bucket.Item;
    // If we found an empty bucket, this key isn't in the table yet, return.
    if (BucketItem == 0)
      return -1;

    if (BucketItem == getTombstoneVal()) {
      // Ignore tombstones.
    } else if (Bucket.FullHashValue == FullHashValue) {
      // If the full hash value matches, check deeply for a match.  The common
      // case here is that we are only looking at the buckets (for item info
      // being non-null and for the full hash value) not at the items.  This
      // is important for cache locality.

      // Do the comparison like this because NameStart isn't necessarily
      // null-terminated!
      char *ItemStr = (char*)BucketItem+ItemSize;
      unsigned ItemStrLen = BucketItem->getKeyLength();
      if (unsigned(KeyEnd-KeyStart) == ItemStrLen &&
          memcmp(ItemStr, KeyStart, ItemStrLen) == 0) {
        // We found a match!
        return BucketNo;
      }
    }

    // Okay, we didn't find the item.  Probe to the next bucket.
    BucketNo = (BucketNo+ProbeAmt) & (HTSize-1);

    // Use quadratic probing, it has fewer clumping artifacts than linear
    // probing and has good cache behavior in the common case.
    ++ProbeAmt;
  }
}

/// RemoveKey - Remove the specified StringMapEntry from the table, but do not
/// delete it.  This aborts if the value isn't in the table.
void StringMapImpl::RemoveKey(StringMapEntryBase *V) {
  const char *VStr = (char*)V + ItemSize;
  StringMapEntryBase *V2 = RemoveKey(VStr, VStr+V->getKeyLength());
  V2 = V2;
  assert(V == V2 && "Didn't find key?");
}

/// RemoveKey - Remove the StringMapEntry for the specified key from the
/// table, returning it.  If the key is not in the table, this returns null.
StringMapEntryBase *StringMapImpl::RemoveKey(const char *KeyStart,
                                             const char *KeyEnd) {
  int Bucket = FindKey(KeyStart, KeyEnd);
  if (Bucket == -1) return 0;

  StringMapEntryBase *Result = TheTable[Bucket].Item;
  TheTable[Bucket].Item = getTombstoneVal();
  --NumItems;
  ++NumTombstones;
  return Result;
}

/// RehashTable - Grow the table, redistributing values into the buckets with
/// the appropriate mod-of-hashtable-size.
void StringMapImpl::RehashTable() {
  unsigned NewSize = NumBuckets*2;
  // Allocate one extra bucket which will always be non-empty.  This allows the
  // iterators to stop at end.
  ItemBucket *NewTableArray =(ItemBucket*)calloc(NewSize+1, sizeof(ItemBucket));
  NewTableArray[NewSize].Item = (StringMapEntryBase*)2;

  // Rehash all the items into their new buckets.  Luckily :) we already have
  // the hash values available, so we don't have to rehash any strings.
  for (ItemBucket *IB = TheTable, *E = TheTable+NumBuckets; IB != E; ++IB) {
    if (IB->Item && IB->Item != getTombstoneVal()) {
      // Fast case, bucket available.
      unsigned FullHash = IB->FullHashValue;
      unsigned NewBucket = FullHash & (NewSize-1);
      if (NewTableArray[NewBucket].Item == 0) {
        NewTableArray[FullHash & (NewSize-1)].Item = IB->Item;
        NewTableArray[FullHash & (NewSize-1)].FullHashValue = FullHash;
        continue;
      }

      // Otherwise probe for a spot.
      unsigned ProbeSize = 1;
      do {
        NewBucket = (NewBucket + ProbeSize++) & (NewSize-1);
      } while (NewTableArray[NewBucket].Item);

      // Finally found a slot.  Fill it in.
      NewTableArray[NewBucket].Item = IB->Item;
      NewTableArray[NewBucket].FullHashValue = FullHash;
    }
  }

  delete[] TheTable;

  TheTable = NewTableArray;
  NumBuckets = NewSize;
}
<commit_msg>stringmap memory managed with malloc now<commit_after>//===--- StringMap.cpp - String Hash table map implementation -------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by Chris Lattner and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the StringMap class.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/StringMap.h"
#include <cassert>
using namespace llvm;

StringMapImpl::StringMapImpl(unsigned InitSize, unsigned itemSize) {
  ItemSize = itemSize;

  // If a size is specified, initialize the table with that many buckets.
  if (InitSize) {
    init(InitSize);
    return;
  }

  // Otherwise, initialize it with zero buckets to avoid the allocation.
  TheTable = 0;
  NumBuckets = 0;
  NumItems = 0;
  NumTombstones = 0;
}

void StringMapImpl::init(unsigned InitSize) {
  assert((InitSize & (InitSize-1)) == 0 &&
         "Init Size must be a power of 2 or zero!");
  NumBuckets = InitSize ? InitSize : 16;
  NumItems = 0;
  NumTombstones = 0;

  TheTable = (ItemBucket*)calloc(NumBuckets+1, sizeof(ItemBucket));

  // Allocate one extra bucket, set it to look filled so the iterators stop at
  // end.
  TheTable[NumBuckets].Item = (StringMapEntryBase*)2;
}

/// HashString - Compute a hash code for the specified string.
///
static unsigned HashString(const char *Start, const char *End) {
  // Bernstein hash function.
  unsigned int Result = 0;
  // TODO: investigate whether a modified bernstein hash function performs
  // better: http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx
  //   X*33+c -> X*33^c
  while (Start != End)
    Result = Result * 33 + *Start++;
  Result = Result + (Result >> 5);
  return Result;
}

/// LookupBucketFor - Look up the bucket that the specified string should end
/// up in.  If it already exists as a key in the map, the Item pointer for the
/// specified bucket will be non-null.  Otherwise, it will be null.  In either
/// case, the FullHashValue field of the bucket will be set to the hash value
/// of the string.
unsigned StringMapImpl::LookupBucketFor(const char *NameStart,
                                        const char *NameEnd) {
  unsigned HTSize = NumBuckets;
  if (HTSize == 0) {  // Hash table unallocated so far?
    init(16);
    HTSize = NumBuckets;
  }
  unsigned FullHashValue = HashString(NameStart, NameEnd);
  unsigned BucketNo = FullHashValue & (HTSize-1);

  unsigned ProbeAmt = 1;
  int FirstTombstone = -1;
  while (1) {
    ItemBucket &Bucket = TheTable[BucketNo];
    StringMapEntryBase *BucketItem = Bucket.Item;
    // If we found an empty bucket, this key isn't in the table yet, return it.
    if (BucketItem == 0) {
      // If we found a tombstone, we want to reuse the tombstone instead of an
      // empty bucket.  This reduces probing.
      if (FirstTombstone != -1) {
        TheTable[FirstTombstone].FullHashValue = FullHashValue;
        return FirstTombstone;
      }

      Bucket.FullHashValue = FullHashValue;
      return BucketNo;
    }

    if (BucketItem == getTombstoneVal()) {
      // Skip over tombstones.  However, remember the first one we see.
      if (FirstTombstone == -1) FirstTombstone = BucketNo;
    } else if (Bucket.FullHashValue == FullHashValue) {
      // If the full hash value matches, check deeply for a match.  The common
      // case here is that we are only looking at the buckets (for item info
      // being non-null and for the full hash value) not at the items.  This
      // is important for cache locality.

      // Do the comparison like this because NameStart isn't necessarily
      // null-terminated!
      char *ItemStr = (char*)BucketItem+ItemSize;
      unsigned ItemStrLen = BucketItem->getKeyLength();
      if (unsigned(NameEnd-NameStart) == ItemStrLen &&
          memcmp(ItemStr, NameStart, ItemStrLen) == 0) {
        // We found a match!
        return BucketNo;
      }
    }

    // Okay, we didn't find the item.  Probe to the next bucket.
    BucketNo = (BucketNo+ProbeAmt) & (HTSize-1);

    // Use quadratic probing, it has fewer clumping artifacts than linear
    // probing and has good cache behavior in the common case.
    ++ProbeAmt;
  }
}

/// FindKey - Look up the bucket that contains the specified key. If it exists
/// in the map, return the bucket number of the key.  Otherwise return -1.
/// This does not modify the map.
int StringMapImpl::FindKey(const char *KeyStart, const char *KeyEnd) const {
  unsigned HTSize = NumBuckets;
  if (HTSize == 0) return -1;  // Really empty table?
  unsigned FullHashValue = HashString(KeyStart, KeyEnd);
  unsigned BucketNo = FullHashValue & (HTSize-1);

  unsigned ProbeAmt = 1;
  while (1) {
    ItemBucket &Bucket = TheTable[BucketNo];
    StringMapEntryBase *BucketItem = Bucket.Item;
    // If we found an empty bucket, this key isn't in the table yet, return.
    if (BucketItem == 0)
      return -1;

    if (BucketItem == getTombstoneVal()) {
      // Ignore tombstones.
    } else if (Bucket.FullHashValue == FullHashValue) {
      // If the full hash value matches, check deeply for a match.  The common
      // case here is that we are only looking at the buckets (for item info
      // being non-null and for the full hash value) not at the items.  This
      // is important for cache locality.

      // Do the comparison like this because NameStart isn't necessarily
      // null-terminated!
      char *ItemStr = (char*)BucketItem+ItemSize;
      unsigned ItemStrLen = BucketItem->getKeyLength();
      if (unsigned(KeyEnd-KeyStart) == ItemStrLen &&
          memcmp(ItemStr, KeyStart, ItemStrLen) == 0) {
        // We found a match!
        return BucketNo;
      }
    }

    // Okay, we didn't find the item.  Probe to the next bucket.
    BucketNo = (BucketNo+ProbeAmt) & (HTSize-1);

    // Use quadratic probing, it has fewer clumping artifacts than linear
    // probing and has good cache behavior in the common case.
    ++ProbeAmt;
  }
}

/// RemoveKey - Remove the specified StringMapEntry from the table, but do not
/// delete it.  This aborts if the value isn't in the table.
void StringMapImpl::RemoveKey(StringMapEntryBase *V) {
  const char *VStr = (char*)V + ItemSize;
  StringMapEntryBase *V2 = RemoveKey(VStr, VStr+V->getKeyLength());
  V2 = V2;
  assert(V == V2 && "Didn't find key?");
}

/// RemoveKey - Remove the StringMapEntry for the specified key from the
/// table, returning it.  If the key is not in the table, this returns null.
StringMapEntryBase *StringMapImpl::RemoveKey(const char *KeyStart,
                                             const char *KeyEnd) {
  int Bucket = FindKey(KeyStart, KeyEnd);
  if (Bucket == -1) return 0;

  StringMapEntryBase *Result = TheTable[Bucket].Item;
  TheTable[Bucket].Item = getTombstoneVal();
  --NumItems;
  ++NumTombstones;
  return Result;
}

/// RehashTable - Grow the table, redistributing values into the buckets with
/// the appropriate mod-of-hashtable-size.
void StringMapImpl::RehashTable() {
  unsigned NewSize = NumBuckets*2;
  // Allocate one extra bucket which will always be non-empty.  This allows the
  // iterators to stop at end.
  ItemBucket *NewTableArray =(ItemBucket*)calloc(NewSize+1, sizeof(ItemBucket));
  NewTableArray[NewSize].Item = (StringMapEntryBase*)2;

  // Rehash all the items into their new buckets.  Luckily :) we already have
  // the hash values available, so we don't have to rehash any strings.
  for (ItemBucket *IB = TheTable, *E = TheTable+NumBuckets; IB != E; ++IB) {
    if (IB->Item && IB->Item != getTombstoneVal()) {
      // Fast case, bucket available.
      unsigned FullHash = IB->FullHashValue;
      unsigned NewBucket = FullHash & (NewSize-1);
      if (NewTableArray[NewBucket].Item == 0) {
        NewTableArray[FullHash & (NewSize-1)].Item = IB->Item;
        NewTableArray[FullHash & (NewSize-1)].FullHashValue = FullHash;
        continue;
      }

      // Otherwise probe for a spot.
      unsigned ProbeSize = 1;
      do {
        NewBucket = (NewBucket + ProbeSize++) & (NewSize-1);
      } while (NewTableArray[NewBucket].Item);

      // Finally found a slot.  Fill it in.
      NewTableArray[NewBucket].Item = IB->Item;
      NewTableArray[NewBucket].FullHashValue = FullHash;
    }
  }

  free(TheTable);

  TheTable = NewTableArray;
  NumBuckets = NewSize;
}
<|endoftext|>