<commit_before>/* -*- coding: utf-8; mode: c++; tab-width: 3; indent-tabs-mode: nil -*-

Copyright 2010, 2011, 2012, 2013, 2014
Raffaello D. Di Napoli

This file is part of Abaclade.

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

Abaclade 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
Public License for more details.

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

#ifndef _ABACLADE_HXX_INTERNAL
   #error "Please #include <abaclade.hxx> instead of this file"
#endif

////////////////////////////////////////////////////////////////////////////////////////////////////
// abc::byteorder globals

// Define byte reordering functions.

#if defined(__GLIBC__)
   #include <byteswap.h> // bswap_*()
   #define ABC_HAVE_BSWAP
#else
   ABACLADE_SYM std::uint16_t bswap_16(std::uint16_t i);
   ABACLADE_SYM std::uint32_t bswap_32(std::uint32_t i);
   ABACLADE_SYM std::uint64_t bswap_64(std::uint64_t i);
#endif

namespace abc {
namespace byteorder {

//! Implementation of swap(), specialized by size in bytes of the argument. See swap().
template <std::size_t cb>
struct _swap_impl;

// Specialization for 1-byte integers.
template <>
struct _swap_impl<1> {
   typedef std::uint8_t type;

   type operator()(type i) {
      // No byte swapping on a single byte.
      return i;
   }
};

// Specialization for 2-byte integers.
template <>
struct _swap_impl<2> {
   typedef std::uint16_t type;

   type operator()(type i) {
      return bswap_16(i);
   }
};

// Specialization for 4-byte integers.
template <>
struct _swap_impl<4> {
   typedef std::uint32_t type;

   type operator()(type i) {
      return bswap_32(i);
   }
};

// Specialization for 8-byte integers.
template <>
struct _swap_impl<8> {
   typedef std::uint64_t type;

   type operator()(type i) {
      return bswap_64(i);
   }
};

/*! Unconditionally flips the byte order in a number. It’s only defined for types ranging in size
from 2 to 8 bytes.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order.
*/
template <typename I>
inline I swap(I i) {
   typedef _swap_impl<sizeof(I)> swap_impl;
   return I(swap_impl()(typename swap_impl::type(i)));
}

/*! Converts a number from host endianness to big endian.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order if the host is little endian.
*/
template <typename I>
inline I host_to_be(I i) {
#if ABC_HOST_LITTLE_ENDIAN
   return swap(i);
#else
   return i;
#endif
}

/*! Converts a number from host endianness to little endian.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order if the host is big endian.
*/
template <typename I>
inline I host_to_le(I i) {
#if ABC_HOST_LITTLE_ENDIAN
   return i;
#else
   return swap(i);
#endif
}

/*! Converts a number from big endian to host endianness.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order if the host is little endian.
*/
template <typename I>
inline I be_to_host(I i) {
#if ABC_HOST_LITTLE_ENDIAN
   return swap(i);
#else
   return i;
#endif
}

/*! Converts a number from little endian to host endianness.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order if the host is big endian.
*/
template <typename I>
inline I le_to_host(I i) {
#if ABC_HOST_LITTLE_ENDIAN
   return i;
#else
   return swap(i);
#endif
}

} //namespace byteorder
} //namespace abc

// Define compile-time counterparts to the above functions.
// These can all go away as soon as constexpr is available on all supported compilers.

/*! Unconditionally flips the byte order in a 16-bit number.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order.
*/
#define ABC_BYTEORDER_SWAP16(i) \
   ( \
      ((static_cast<std::uint16_t>(i) & 0xff00) >> 8) | \
      ((static_cast<std::uint16_t>(i) & 0x00ff) << 8) \
   )

/*! Unconditionally flips the byte order in a 32-bit number.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order.
*/
#define ABC_BYTEORDER_SWAP32(i) \
   ( \
      ((static_cast<std::uint32_t>(i) & 0xff000000) >> 24) | \
      ((static_cast<std::uint32_t>(i) & 0x00ff0000) >>  8) | \
      ((static_cast<std::uint32_t>(i) & 0x0000ff00) <<  8) | \
      ((static_cast<std::uint32_t>(i) & 0x000000ff) << 24) \
   )

/*! Unconditionally flips the byte order in a 64-bit number.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order.
*/
#define ABC_BYTEORDER_SWAP64(i) \
   ( \
      ((static_cast<std::uint64_t>(i) & 0xff00000000000000ull) >> 56) | \
      ((static_cast<std::uint64_t>(i) & 0x00ff000000000000ull) >> 40) | \
      ((static_cast<std::uint64_t>(i) & 0x0000ff0000000000ull) >> 24) | \
      ((static_cast<std::uint64_t>(i) & 0x000000ff00000000ull) >>  8) | \
      ((static_cast<std::uint64_t>(i) & 0x00000000ff000000ull) <<  8) | \
      ((static_cast<std::uint64_t>(i) & 0x0000000000ff0000ull) << 24) | \
      ((static_cast<std::uint64_t>(i) & 0x000000000000ff00ull) << 40) | \
      ((static_cast<std::uint64_t>(i) & 0x00000000000000ffull) << 56) \
   )

/*! Converts a 16-bit number from host endianness to big endian.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order if the host is little endian.
*/
#if ABC_HOST_LITTLE_ENDIAN
   #define ABC_BYTEORDER_HOSTTOBE16(i) ABC_BYTEORDER_SWAP16(i)
#else
   #define ABC_BYTEORDER_HOSTTOBE16(i) static_cast<std::uint16_t>(i)
#endif

/*! Converts a 32-bit number from host endianness to big endian.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order if the host is little endian.
*/
#if ABC_HOST_LITTLE_ENDIAN
   #define ABC_BYTEORDER_HOSTTOBE32(i) ABC_BYTEORDER_SWAP32(i)
#else
   #define ABC_BYTEORDER_HOSTTOBE32(i) static_cast<std::uint32_t>(i)
#endif

/*! Converts a 64-bit number from host endianness to big endian.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order if the host is little endian.
*/
#if ABC_HOST_LITTLE_ENDIAN
   #define ABC_BYTEORDER_HOSTTOBE64(i) ABC_BYTEORDER_SWAP64(i)
#else
   #define ABC_BYTEORDER_HOSTTOBE64(i) static_cast<std::uint64_t>(i)
#endif

/*! Converts a 16-bit number from host endianness to little endian.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order if the host is big endian.
*/
#if ABC_HOST_LITTLE_ENDIAN
   #define ABC_BYTEORDER_HOSTTOLE16(i) static_cast<std::uint16_t>(i)
#else
   #define ABC_BYTEORDER_HOSTTOLE16(i) ABC_BYTEORDER_SWAP16(i)
#endif

/*! Converts a 32-bit number from host endianness to little endian.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order if the host is big endian.
*/
#if ABC_HOST_LITTLE_ENDIAN
   #define ABC_BYTEORDER_HOSTTOLE32(i) static_cast<std::uint32_t>(i)
#else
   #define ABC_BYTEORDER_HOSTTOLE32(i) ABC_BYTEORDER_SWAP32(i)
#endif

/*! Converts a 64-bit number from host endianness to little endian.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order if the host is big endian.
*/
#if ABC_HOST_LITTLE_ENDIAN
   #define ABC_BYTEORDER_HOSTTOLE64(i) static_cast<std::uint64_t>(i)
#else
   #define ABC_BYTEORDER_HOSTTOLE64(i) ABC_BYTEORDER_SWAP64(i)
#endif

/*! Converts a 16-bit number from big endian to host endianness.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order if the host is little endian.
*/
#if ABC_HOST_LITTLE_ENDIAN
   #define ABC_BYTEORDER_BETOHOST16(i) ABC_BYTEORDER_SWAP16(i)
#else
   #define ABC_BYTEORDER_BETOHOST16(i) static_cast<std::uint16_t>(i)
#endif

/*! Converts a 32-bit number from big endian to host endianness.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order if the host is little endian.
*/
#if ABC_HOST_LITTLE_ENDIAN
   #define ABC_BYTEORDER_BETOHOST32(i) ABC_BYTEORDER_SWAP32(i)
#else
   #define ABC_BYTEORDER_BETOHOST32(i) static_cast<std::uint32_t>(i)
#endif

/*! Converts a 64-bit number from big endian to host endianness.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order if the host is little endian.
*/
#if ABC_HOST_LITTLE_ENDIAN
   #define ABC_BYTEORDER_BETOHOST64(i) ABC_BYTEORDER_SWAP64(i)
#else
   #define ABC_BYTEORDER_BETOHOST64(i) static_cast<std::uint64_t>(i)
#endif

/*! Converts a 16-bit number from little endian to host endianness.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order if the host is big endian.
*/
#if ABC_HOST_LITTLE_ENDIAN
   #define ABC_BYTEORDER_LETOHOST16(i) static_cast<std::uint16_t>(i)
#else
   #define ABC_BYTEORDER_LETOHOST16(i) ABC_BYTEORDER_SWAP16(i)
#endif

/*! Converts a 32-bit number from little endian to host endianness.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order if the host is big endian.
*/
#if ABC_HOST_LITTLE_ENDIAN
   #define ABC_BYTEORDER_LETOHOST32(i) static_cast<std::uint32_t>(i)
#else
   #define ABC_BYTEORDER_LETOHOST32(i) ABC_BYTEORDER_SWAP32(i)
#endif

/*! Converts a 64-bit number from little endian to host endianness.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order if the host is big endian.
*/
#if ABC_HOST_LITTLE_ENDIAN
   #define ABC_BYTEORDER_LETOHOST64(i) static_cast<std::uint64_t>(i)
#else
   #define ABC_BYTEORDER_LETOHOST64(i) ABC_BYTEORDER_SWAP64(i)
#endif

////////////////////////////////////////////////////////////////////////////////////////////////////
<commit_msg>Remove unused macros<commit_after>/* -*- coding: utf-8; mode: c++; tab-width: 3; indent-tabs-mode: nil -*-

Copyright 2010, 2011, 2012, 2013, 2014, 2015
Raffaello D. Di Napoli

This file is part of Abaclade.

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

Abaclade 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
Public License for more details.

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

#ifndef _ABACLADE_HXX_INTERNAL
   #error "Please #include <abaclade.hxx> instead of this file"
#endif

////////////////////////////////////////////////////////////////////////////////////////////////////
// abc::byteorder globals

// Define byte reordering functions.

#if defined(__GLIBC__)
   #include <byteswap.h> // bswap_*()
   #define ABC_HAVE_BSWAP
#else
   ABACLADE_SYM std::uint16_t bswap_16(std::uint16_t i);
   ABACLADE_SYM std::uint32_t bswap_32(std::uint32_t i);
   ABACLADE_SYM std::uint64_t bswap_64(std::uint64_t i);
#endif

namespace abc {
namespace byteorder {

//! Implementation of swap(), specialized by size in bytes of the argument. See swap().
template <std::size_t cb>
struct _swap_impl;

// Specialization for 1-byte integers.
template <>
struct _swap_impl<1> {
   typedef std::uint8_t type;

   type operator()(type i) {
      // No byte swapping on a single byte.
      return i;
   }
};

// Specialization for 2-byte integers.
template <>
struct _swap_impl<2> {
   typedef std::uint16_t type;

   type operator()(type i) {
      return bswap_16(i);
   }
};

// Specialization for 4-byte integers.
template <>
struct _swap_impl<4> {
   typedef std::uint32_t type;

   type operator()(type i) {
      return bswap_32(i);
   }
};

// Specialization for 8-byte integers.
template <>
struct _swap_impl<8> {
   typedef std::uint64_t type;

   type operator()(type i) {
      return bswap_64(i);
   }
};

/*! Unconditionally flips the byte order in a number. It’s only defined for types ranging in size
from 2 to 8 bytes.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order.
*/
template <typename I>
inline I swap(I i) {
   typedef _swap_impl<sizeof(I)> swap_impl;
   return I(swap_impl()(typename swap_impl::type(i)));
}

/*! Converts a number from host endianness to big endian.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order if the host is little endian.
*/
template <typename I>
inline I host_to_be(I i) {
#if ABC_HOST_LITTLE_ENDIAN
   return swap(i);
#else
   return i;
#endif
}

/*! Converts a number from host endianness to little endian.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order if the host is big endian.
*/
template <typename I>
inline I host_to_le(I i) {
#if ABC_HOST_LITTLE_ENDIAN
   return i;
#else
   return swap(i);
#endif
}

/*! Converts a number from big endian to host endianness.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order if the host is little endian.
*/
template <typename I>
inline I be_to_host(I i) {
#if ABC_HOST_LITTLE_ENDIAN
   return swap(i);
#else
   return i;
#endif
}

/*! Converts a number from little endian to host endianness.

@param i
   Source integer.
@return
   Integer with the same byte values as i, but in reverse order if the host is big endian.
*/
template <typename I>
inline I le_to_host(I i) {
#if ABC_HOST_LITTLE_ENDIAN
   return i;
#else
   return swap(i);
#endif
}

} //namespace byteorder
} //namespace abc

////////////////////////////////////////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before>//*******************************************************************
//
// License:  See top level LICENSE.txt file.
//
// AUTHOR: Jordi Inglada
//
// DESCRIPTION:
//
// SOFTWARE HISTORY:
//   23JAN2008  Jordi Inglada, CNES
//              Initial coding.
//
//*****************************************************************************

#include <ossim/projection/ossimTileMapModel.h>

RTTI_DEF1(ossimTileMapModel, "ossimTileMapModel", ossimSensorModel);

#include <ossim/base/ossimKeywordlist.h>
#include <ossim/base/ossimKeywordNames.h>
#include <stdio.h>

//***
// Define Trace flags for use within this file:
//***
#include <ossim/base/ossimTrace.h>
static ossimTrace traceExec  ("ossimTileMapModel:exec");
static ossimTrace traceDebug ("ossimTileMapModel:debug");

//*****************************************************************************
//  DEFAULT CONSTRUCTOR: ossimTileMapModel()
//
//*****************************************************************************
ossimTileMapModel::ossimTileMapModel()
   :
   ossimSensorModel(),
   qDepth (1)

{
   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::ossimTileMapModel: entering..." << std::endl;

//   initAdjustableParameters();

//    std::cout << "TileMapModel constructor" << std::endl;

   if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::ossimTileMapModel: returning..." << std::endl;
}

//*****************************************************************************
//  CONSTRUCTOR: ossimTileMapModel(kwl)
//
//  Constructs model from keywordlist geometry file
//
//*****************************************************************************
ossimTileMapModel::ossimTileMapModel(const ossimKeywordlist& geom_kwl)
   :
   ossimSensorModel(),
   qDepth (1)
{
   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::ossimTileMapModel(geom_kwl): entering..." << std::endl;

   //***
   // Parse keywordlist for geometry:
   //***
   loadState(geom_kwl);

   if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::ossimTileMapModel(geom_kwl): Exited..." << std::endl;
}

//*****************************************************************************
//  COPY CONSTRUCTOR:
//*****************************************************************************
ossimTileMapModel::ossimTileMapModel(const ossimTileMapModel& rhs)
   :
   ossimSensorModel   (rhs),
   qDepth (rhs.qDepth)
{
   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::ossimTileMapModel(rhs): entering..." << std::endl;

   //initAdjustableParameters();

   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::ossimTileMapModel(rhs): returning..." << std::endl;
}

//*****************************************************************************
//  METHOD: ossimTileMapModel::lineSampleHeightToWorld()
//
//  Performs the line/sample to groundpoint projection given an elevation.
//
//*****************************************************************************
void ossimTileMapModel::lineSampleToWorld(const ossimDpt& image_point,
                                                ossimGpt&       gpt) const
{
  lineSampleHeightToWorld(image_point, 0.0, gpt);
}
void ossimTileMapModel::lineSampleHeightToWorld(const ossimDpt& image_point,
                                                const double&   height,
                                                ossimGpt&       gpt) const
{
   if(!image_point.hasNans())
   {

   gpt.lon = image_point.samp/(pow(2.,static_cast<double>(qDepth))*256)*360.0-180.0;
   double y = image_point.line/(pow(2.,static_cast<double>(qDepth))*256);
   double ex = exp(4*M_PI*(y-0.5));
   gpt.lat = -180.0/M_PI*asin((ex-1)/(ex+1));
   }
   else
   {
      gpt.makeNan();
   }
  return;
}

void ossimTileMapModel::worldToLineSample(const ossimGpt& ground_point,
                                      ossimDpt&       img_pt) const
{
   // if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::worldToLineSample(): entering..." << std::endl;

   if(ground_point.isLatNan() || ground_point.isLonNan() )
   {
      img_pt.makeNan();
      return;
   }

   double x = (180.0 + ground_point.lon) / 360.0;
   double y = - ground_point.lat * M_PI / 180; // convert to radians
   y = 0.5 * log((1+sin(y)) / (1 - sin(y)));
   y *= 1.0/(2 * M_PI); // scale factor from radians to normalized
   y += 0.5; // and make y range from 0 - 1

   img_pt.samp = floor(x*pow(2.,static_cast<double>(qDepth))*256);

   img_pt.line = floor(y*pow(2.,static_cast<double>(qDepth))*256);

   return;
}

//*****************************************************************************
//  METHOD: ossimTileMapModel::print()
//
//  Formatted dump of data members.
//
//*****************************************************************************
std::ostream& ossimTileMapModel::print(std::ostream& os) const
{
   os << "\nDump of ossimTileMapModel object at "
      << hex << this << ":\n"
      << "\nTileMapModel -- Dump of all data members: "
      << "\n        theImageID: " << theImageID.chars()
      << "\n        theImageSize: " << theImageSize
      << "\n        theRefImgPt: " << theRefImgPt
      << "\n        theRefGndPt: " << theRefGndPt
      << "\n        theGSD.line: " << theGSD.line
      << "\n        theGSD.samp: " << theGSD.samp
      << "\n        qDepth: " << qDepth
      << endl;

   return ossimSensorModel::print(os);
}

//*****************************************************************************
//  METHOD: ossimTileMapModel::saveState()
//
//  Saves the model state to the KWL. This KWL also serves as a geometry file.
//
//*****************************************************************************
bool ossimTileMapModel::saveState(ossimKeywordlist& kwl,
                              const char* prefix) const
{
   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::saveState: entering..." << std::endl;

   kwl.add(prefix, ossimKeywordNames::TYPE_KW, TYPE_NAME(this));

   //***
   // Hand off to base class for common stuff:
   //***
   ossimSensorModel::saveState(kwl, prefix);

   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::saveState: returning..." << std::endl;
   return true;
}

//*****************************************************************************
//  METHOD: ossimTileMapModel::loadState()
//
//  Restores the model's state from the KWL. This KWL also serves as a
//  geometry file.
//
//*****************************************************************************
bool ossimTileMapModel::loadState(const ossimKeywordlist& kwl,
                                  const char* prefix)
{
   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::loadState: entering..." << std::endl;

   if (traceDebug())
   {
      ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::loadState:"
                                          << "\nInput kwl:  " << kwl
                                          << std::endl;
   }

   const char* value = NULL;
   const char* keyword =NULL;
   bool success;

   //***
   // Assure this keywordlist contains correct type info:
   //***
   value = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
   if (!value || (strcmp(value, TYPE_NAME(this))))
     {
       theErrorStatus = 1;
       return false;
     }

   //***
   // Pass on to the base-class for parsing first:
   //***
   success = ossimSensorModel::loadState(kwl, prefix);
   if (!success)
     {
       theErrorStatus++;
       return false;
     }

   updateModel();

   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::loadState: returning..." << std::endl;
   return true;
}

//*****************************************************************************
// STATIC METHOD: ossimTileMapModel::writeGeomTemplate
//
//  Writes a sample kwl to output stream.
//
//*****************************************************************************
void ossimTileMapModel::writeGeomTemplate(ostream& os)
{
   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::writeGeomTemplate: entering..." << std::endl;

   os <<
      "//**************************************************************\n"
      "// Template for TileMap model keywordlist\n"
      "//**************************************************************\n"
      << ossimKeywordNames::TYPE_KW << ": " << "ossimTileMapModel" << endl;

   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::writeGeomTemplate: returning..." << std::endl;
   return;
}
<commit_msg>ENH: better computation<commit_after>//*******************************************************************
//
// License:  See top level LICENSE.txt file.
//
// AUTHOR: Jordi Inglada
//
// DESCRIPTION:
//
// SOFTWARE HISTORY:
//   23JAN2008  Jordi Inglada, CNES
//              Initial coding.
//
//*****************************************************************************

#include <ossim/projection/ossimTileMapModel.h>

RTTI_DEF1(ossimTileMapModel, "ossimTileMapModel", ossimSensorModel);

#include <ossim/base/ossimKeywordlist.h>
#include <ossim/base/ossimKeywordNames.h>
#include <stdio.h>

//***
// Define Trace flags for use within this file:
//***
#include <ossim/base/ossimTrace.h>
static ossimTrace traceExec  ("ossimTileMapModel:exec");
static ossimTrace traceDebug ("ossimTileMapModel:debug");

//*****************************************************************************
//  DEFAULT CONSTRUCTOR: ossimTileMapModel()
//
//*****************************************************************************
ossimTileMapModel::ossimTileMapModel()
   :
   ossimSensorModel(),
   qDepth (1)

{
   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::ossimTileMapModel: entering..." << std::endl;

//   initAdjustableParameters();

//    std::cout << "TileMapModel constructor" << std::endl;

   if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::ossimTileMapModel: returning..." << std::endl;
}

//*****************************************************************************
//  CONSTRUCTOR: ossimTileMapModel(kwl)
//
//  Constructs model from keywordlist geometry file
//
//*****************************************************************************
ossimTileMapModel::ossimTileMapModel(const ossimKeywordlist& geom_kwl)
   :
   ossimSensorModel(),
   qDepth (1)
{
   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::ossimTileMapModel(geom_kwl): entering..." << std::endl;

   //***
   // Parse keywordlist for geometry:
   //***
   loadState(geom_kwl);

   if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::ossimTileMapModel(geom_kwl): Exited..." << std::endl;
}

//*****************************************************************************
//  COPY CONSTRUCTOR:
//*****************************************************************************
ossimTileMapModel::ossimTileMapModel(const ossimTileMapModel& rhs)
   :
   ossimSensorModel   (rhs),
   qDepth (rhs.qDepth)
{
   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::ossimTileMapModel(rhs): entering..." << std::endl;

   //initAdjustableParameters();

   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::ossimTileMapModel(rhs): returning..." << std::endl;
}

//*****************************************************************************
//  METHOD: ossimTileMapModel::lineSampleHeightToWorld()
//
//  Performs the line/sample to groundpoint projection given an elevation.
//
//*****************************************************************************
void ossimTileMapModel::lineSampleToWorld(const ossimDpt& image_point,
                                                ossimGpt&       gpt) const
{
  lineSampleHeightToWorld(image_point, 0.0, gpt);
}
void ossimTileMapModel::lineSampleHeightToWorld(const ossimDpt& image_point,
                                                const double&   height,
                                                ossimGpt&       gpt) const
{
  if(!image_point.hasNans())
  {
    gpt.lon = image_point.samp/((1 << qDepth) *256)*360.0-180.0;
    double y = image_point.line/((1 << qDepth)*256);
    double ex = exp(4*M_PI*(y-0.5));
    gpt.lat = -180.0/M_PI*asin((ex-1)/(ex+1));
  }
  else
  {
    gpt.makeNan();
  }
  return;
}

void ossimTileMapModel::worldToLineSample(const ossimGpt& ground_point,
                                      ossimDpt&       img_pt) const
{
   // if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::worldToLineSample(): entering..." << std::endl;

   if(ground_point.isLatNan() || ground_point.isLonNan() )
   {
      img_pt.makeNan();
      return;
   }

   double x = (180.0 + ground_point.lon) / 360.0;
   double y = - ground_point.lat * M_PI / 180; // convert to radians
   y = 0.5 * log((1+sin(y)) / (1 - sin(y)));
   y *= 1.0/(2 * M_PI); // scale factor from radians to normalized
   y += 0.5; // and make y range from 0 - 1

   img_pt.samp = floor(x*pow(2.,static_cast<double>(qDepth))*256);

   img_pt.line = floor(y*pow(2.,static_cast<double>(qDepth))*256);

   return;
}

//*****************************************************************************
//  METHOD: ossimTileMapModel::print()
//
//  Formatted dump of data members.
//
//*****************************************************************************
std::ostream& ossimTileMapModel::print(std::ostream& os) const
{
   os << "\nDump of ossimTileMapModel object at "
      << hex << this << ":\n"
      << "\nTileMapModel -- Dump of all data members: "
      << "\n        theImageID: " << theImageID.chars()
      << "\n        theImageSize: " << theImageSize
      << "\n        theRefImgPt: " << theRefImgPt
      << "\n        theRefGndPt: " << theRefGndPt
      << "\n        theGSD.line: " << theGSD.line
      << "\n        theGSD.samp: " << theGSD.samp
      << "\n        qDepth: " << qDepth
      << endl;

   return ossimSensorModel::print(os);
}

//*****************************************************************************
//  METHOD: ossimTileMapModel::saveState()
//
//  Saves the model state to the KWL. This KWL also serves as a geometry file.
//
//*****************************************************************************
bool ossimTileMapModel::saveState(ossimKeywordlist& kwl,
                              const char* prefix) const
{
   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::saveState: entering..." << std::endl;

   kwl.add(prefix, ossimKeywordNames::TYPE_KW, TYPE_NAME(this));

   //***
   // Hand off to base class for common stuff:
   //***
   ossimSensorModel::saveState(kwl, prefix);

   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::saveState: returning..." << std::endl;
   return true;
}

//*****************************************************************************
//  METHOD: ossimTileMapModel::loadState()
//
//  Restores the model's state from the KWL. This KWL also serves as a
//  geometry file.
//
//*****************************************************************************
bool ossimTileMapModel::loadState(const ossimKeywordlist& kwl,
                                  const char* prefix)
{
   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::loadState: entering..." << std::endl;

   if (traceDebug())
   {
      ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::loadState:"
                                          << "\nInput kwl:  " << kwl
                                          << std::endl;
   }

   const char* value = NULL;
   const char* keyword =NULL;
   bool success;

   //***
   // Assure this keywordlist contains correct type info:
   //***
   value = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
   if (!value || (strcmp(value, TYPE_NAME(this))))
     {
       theErrorStatus = 1;
       return false;
     }

   //***
   // Pass on to the base-class for parsing first:
   //***
   success = ossimSensorModel::loadState(kwl, prefix);
   if (!success)
     {
       theErrorStatus++;
       return false;
     }

   updateModel();

   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::loadState: returning..." << std::endl;
   return true;
}

//*****************************************************************************
// STATIC METHOD: ossimTileMapModel::writeGeomTemplate
//
//  Writes a sample kwl to output stream.
//
//*****************************************************************************
void ossimTileMapModel::writeGeomTemplate(ostream& os)
{
   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::writeGeomTemplate: entering..." << std::endl;

   os <<
      "//**************************************************************\n"
      "// Template for TileMap model keywordlist\n"
      "//**************************************************************\n"
      << ossimKeywordNames::TYPE_KW << ": " << "ossimTileMapModel" << endl;

   if (traceExec())  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimTileMapModel::writeGeomTemplate: returning..." << std::endl;
   return;
}
<|endoftext|>


<commit_before>/**
* \file
* Copyright 2014-2015 Benjamin Worpitz
*
* This file is part of alpaka.
*
* alpaka 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.
*
* alpaka 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 alpaka.
* If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <omp.h>

namespace alpaka
{
    namespace omp
    {
        //-----------------------------------------------------------------------------
        //! \return The device this object is bound to.
        //-----------------------------------------------------------------------------
        ALPAKA_FN_HOST auto getMaxOmpThreads()
        -> int
        {
            // HACK: ::omp_get_max_threads() does not return the real limit of the underlying OpenMP 2.0 runtime:
            // 'The omp_get_max_threads routine returns the value of the internal control variable, which is used to determine the number of threads that would form the new team,
            // if an active parallel region without a num_threads clause were to be encountered at that point in the program.'
            // How to do this correctly? Is there even a way to get the hard limit apart from omp_set_num_threads(high_value) -> omp_get_max_threads()?
            ::omp_set_num_threads(1024);
            return ::omp_get_max_threads();
        }
    }
}
<commit_msg>fix missing OMP_NUM_THREADS reset in getMaxOmpThreads<commit_after>/**
* \file
* Copyright 2014-2015 Benjamin Worpitz
*
* This file is part of alpaka.
*
* alpaka 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.
*
* alpaka 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 alpaka.
* If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <omp.h>

namespace alpaka
{
    namespace omp
    {
        //-----------------------------------------------------------------------------
        //! \return The maximum number of threads the OpenMP 2.0 runtime is capable of.
        //-----------------------------------------------------------------------------
        ALPAKA_FN_HOST auto getMaxOmpThreads()
        -> int
        {
            // NOTE: ::omp_get_max_threads() does not return the real limit of the underlying OpenMP 2.0 runtime at any time:
            // 'The omp_get_max_threads routine returns the value of the internal control variable, which is used to determine the number of threads that would form the new team,
            // if an active parallel region without a num_threads clause were to be encountered at that point in the program.'
            // How to do this correctly? Is there even a way to get the hard limit apart from omp_set_num_threads(high_value) -> omp_get_max_threads()?

            // Get the current thread number. This is OMP_NUM_THREADS if it has not been changed up to here.
            auto const maxThreadsOld(::omp_get_max_threads());

            ::omp_set_num_threads(1024);
            auto const maxThreadsReal(::omp_get_max_threads());

            // Reset the max threads.
            ::omp_set_num_threads(maxThreadsOld);

            return maxThreadsReal;
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>submit F.cpp to 'F - Candy Retribution' (jsc2019-qual) [C++14 (GCC 5.4.1)]<commit_after><|endoftext|>


<commit_before>/*
 * Copyright 2014-2021 CNRS INRIA
 */

#ifndef __eigenpy_quaternion_hpp__
#define __eigenpy_quaternion_hpp__

#include "eigenpy/eigenpy.hpp"

#include <Eigen/Core>
#include <Eigen/Geometry>

#include "eigenpy/exception.hpp"

namespace boost { namespace python { namespace converter {

  /// \brief Template specialization of rvalue_from_python_data
  template<typename Quaternion>
  struct rvalue_from_python_data<Eigen::QuaternionBase<Quaternion> const &>
  : rvalue_from_python_data_eigen<Quaternion const &>
  {
    EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(Quaternion const &)
  };

  template <class Quaternion>
  struct implicit<Quaternion, Eigen::QuaternionBase<Quaternion> >
  {
    typedef Quaternion Source;
    typedef Eigen::QuaternionBase<Quaternion> Target;

    static void* convertible(PyObject* obj)
    {
      // Find a converter which can produce a Source instance from
      // obj. The user has told us that Source can be converted to
      // Target, and instantiating construct() below, ensures that
      // at compile-time.
      return implicit_rvalue_convertible_from_python(obj, registered<Source>::converters)
      ? obj : 0;
    }

    static void construct(PyObject* obj, rvalue_from_python_stage1_data* data)
    {
      void* storage = ((rvalue_from_python_storage<Target>*)data)->storage.bytes;

      arg_from_python<Source> get_source(obj);
      bool convertible = get_source.convertible();
      BOOST_VERIFY(convertible);

      new (storage) Source(get_source());

      // record successful construction
      data->convertible = storage;
    }
  };

}}} // namespace boost::python::converter

namespace eigenpy
{

  class ExceptionIndex : public Exception
  {
  public:
    ExceptionIndex(int index,int imin,int imax) : Exception("")
    {
      std::ostringstream oss; oss << "Index " << index << " out of range " << imin << ".."<< imax <<".";
      message = oss.str();
    }
  };

  namespace bp = boost::python;

  template<typename QuaternionDerived> class QuaternionVisitor;

  template<typename Scalar, int Options>
  struct call< Eigen::Quaternion<Scalar,Options> >
  {
    typedef Eigen::Quaternion<Scalar,Options> Quaternion;
    static inline void expose()
    {
      QuaternionVisitor<Quaternion>::expose();
    }

    static inline bool isApprox(const Quaternion & self, const Quaternion & other,
                                const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision())
    {
      return self.isApprox(other,prec);
    }
  };

  template<typename Quaternion>
  class QuaternionVisitor
  :  public bp::def_visitor< QuaternionVisitor<Quaternion> >
  {
    typedef Eigen::QuaternionBase<Quaternion> QuaternionBase;

    typedef typename QuaternionBase::Scalar Scalar;
    typedef typename Quaternion::Coefficients Coefficients;
    typedef typename QuaternionBase::Vector3 Vector3;
    typedef Coefficients Vector4;
    typedef typename QuaternionBase::Matrix3 Matrix3;

    typedef typename QuaternionBase::AngleAxisType AngleAxis;

    BOOST_PYTHON_FUNCTION_OVERLOADS(isApproxQuaternion_overload,call<Quaternion>::isApprox,2,3)

  public:

    template<class PyClass>
    void visit(PyClass& cl) const
    {
      cl
      .def(bp::init<>(bp::arg("self"),"Default constructor")[bp::return_value_policy<bp::return_by_value>()])
      .def(bp::init<Matrix3>((bp::arg("self"),bp::arg("R")),
                             "Initialize from rotation matrix.\n"
                             "\tR : a rotation matrix 3x3.")[bp::return_value_policy<bp::return_by_value>()])
      .def(bp::init<AngleAxis>((bp::arg("self"),bp::arg("aa")),
                               "Initialize from an angle axis.\n"
                               "\taa: angle axis object."))
      .def(bp::init<Quaternion>((bp::arg("self"),bp::arg("quat")),
                                "Copy constructor.\n"
                                "\tquat: a quaternion.")[bp::return_value_policy<bp::return_by_value>()])
      .def("__init__",bp::make_constructor(&QuaternionVisitor::FromTwoVectors,
                                           bp::default_call_policies(),
                                           (bp::arg("u"),bp::arg("v"))),
           "Initialize from two vectors u and v")
      .def("__init__",bp::make_constructor(&QuaternionVisitor::FromOneVector,
                                           bp::default_call_policies(),
                                           (bp::arg("vec4"))),
           "Initialize from a vector 4D.\n"
           "\tvec4 : a 4D vector representing quaternion coefficients in the order xyzw.")
      .def(bp::init<Scalar,Scalar,Scalar,Scalar>
           ((bp::arg("self"),bp::arg("w"),bp::arg("x"),bp::arg("y"),bp::arg("z")),
            "Initialize from coefficients.\n\n"
            "... note:: The order of coefficients is *w*, *x*, *y*, *z*. "
            "The [] operator numbers them differently, 0...4 for *x* *y* *z* *w*!"))

      .add_property("x",
                    &QuaternionVisitor::getCoeff<0>,
                    &QuaternionVisitor::setCoeff<0>,"The x coefficient.")
      .add_property("y",
                    &QuaternionVisitor::getCoeff<1>,
                    &QuaternionVisitor::setCoeff<1>,"The y coefficient.")
      .add_property("z",
                    &QuaternionVisitor::getCoeff<2>,
                    &QuaternionVisitor::setCoeff<2>,"The z coefficient.")
      .add_property("w",
                    &QuaternionVisitor::getCoeff<3>,
                    &QuaternionVisitor::setCoeff<3>,"The w coefficient.")

      .def("isApprox",
           &call<Quaternion>::isApprox,
           isApproxQuaternion_overload(bp::args("self","other","prec"),
                                       "Returns true if *this is approximately equal to other, within the precision determined by prec."))

      /* --- Methods --- */
      .def("coeffs",(const Vector4 & (Quaternion::*)()const)&Quaternion::coeffs,
           bp::arg("self"),
           "Returns a vector of the coefficients (x,y,z,w)",
           bp::return_internal_reference<>())
      .def("matrix",&Quaternion::matrix,
           bp::arg("self"),
           "Returns an equivalent 3x3 rotation matrix. Similar to toRotationMatrix.")
      .def("toRotationMatrix",&Quaternion::toRotationMatrix,
//           bp::arg("self"), // Bug in Boost.Python
           "Returns an equivalent 3x3 rotation matrix.")

      .def("setFromTwoVectors",&setFromTwoVectors,((bp::arg("self"),bp::arg("a"),bp::arg("b"))),
           "Set *this to be the quaternion which transforms a into b through a rotation."
           ,bp::return_self<>())
      .def("conjugate",&Quaternion::conjugate,
           bp::arg("self"),
           "Returns the conjugated quaternion.\n"
           "The conjugate of a quaternion represents the opposite rotation.")
      .def("inverse",&Quaternion::inverse,
           bp::arg("self"),
           "Returns the quaternion describing the inverse rotation.")
      .def("setIdentity",&Quaternion::setIdentity,
           bp::arg("self"),
           "Set *this to the idendity rotation.",bp::return_self<>())
      .def("norm",&Quaternion::norm,
           bp::arg("self"),
           "Returns the norm of the quaternion's coefficients.")
      .def("normalize",&Quaternion::normalize,
           bp::arg("self"),
           "Normalizes the quaternion *this.")
      .def("normalized",&Quaternion::normalized,
           bp::arg("self"),
           "Returns a normalized copy of *this.")
      .def("squaredNorm",&Quaternion::squaredNorm,
           bp::arg("self"),
           "Returns the squared norm of the quaternion's coefficients.")
      .def("dot",&Quaternion::template dot<Quaternion>,
           (bp::arg("self"),bp::arg("other")),
           "Returns the dot product of *this with an other Quaternion.\n"
           "Geometrically speaking, the dot product of two unit quaternions corresponds to the cosine of half the angle between the two rotations.")
      .def("_transformVector",&Quaternion::_transformVector,
           (bp::arg("self"),bp::arg("vector")),
           "Rotation of a vector by a quaternion.")
      .def("vec",&vec,
           bp::arg("self"),
           "Returns a vector expression of the imaginary part (x,y,z).")
      .def("angularDistance",
//           (bp::arg("self"),bp::arg("other")), // Bug in Boost.Python
           &Quaternion::template angularDistance<Quaternion>,
           "Returns the angle (in radian) between two rotations.")
      .def("slerp",&slerp,bp::args("self","t","other"),
           "Returns the spherical linear interpolation between the two quaternions *this and other at the parameter t in [0;1].")

      /* --- Operators --- */
      .def(bp::self * bp::self)
      .def(bp::self *= bp::self)
      .def(bp::self * bp::other<Vector3>())
      .def("__eq__",&QuaternionVisitor::__eq__)
      .def("__ne__",&QuaternionVisitor::__ne__)
      .def("__abs__",&Quaternion::norm)
      .def("__len__",&QuaternionVisitor::__len__).staticmethod("__len__")
      .def("__setitem__",&QuaternionVisitor::__setitem__)
      .def("__getitem__",&QuaternionVisitor::__getitem__)
      .def("assign",&assign<Quaternion>,
           bp::args("self","quat"),
           "Set *this from an quaternion quat and returns a reference to *this.",
           bp::return_self<>())
      .def("assign",(Quaternion & (Quaternion::*)(const AngleAxis &))&Quaternion::operator=,
           bp::args("self","aa"),
           "Set *this from an angle-axis aa and returns a reference to *this.",
           bp::return_self<>())
      .def("__str__",&print)
      .def("__repr__",&print)

//      .def("FromTwoVectors",&Quaternion::template FromTwoVectors<Vector3,Vector3>,
//           bp::args("a","b"),
//           "Returns the quaternion which transform a into b through a rotation.")
      .def("FromTwoVectors",&FromTwoVectors,
           bp::args("a","b"),
           "Returns the quaternion which transforms a into b through a rotation.",
           bp::return_value_policy<bp::manage_new_object>())
      .staticmethod("FromTwoVectors")
      .def("Identity",&Identity,
           "Returns a quaternion representing an identity rotation.",
           bp::return_value_policy<bp::manage_new_object>())
      .staticmethod("Identity")
      ;
    }
  private:

    template<int i>
    static void setCoeff(Quaternion & self, Scalar value) { self.coeffs()[i] = value; }

    template<int i>
    static Scalar getCoeff(Quaternion & self) { return self.coeffs()[i]; }

    static Quaternion & setFromTwoVectors(Quaternion & self, const Vector3 & a, const Vector3 & b)
    { return self.setFromTwoVectors(a,b); }

    template<typename OtherQuat>
    static Quaternion & assign(Quaternion & self, const OtherQuat & quat)
    { return self = quat; }

    static Quaternion* Identity()
    {
      Quaternion* q(new Quaternion); q->setIdentity();
      return q;
    }

    static Quaternion* FromTwoVectors(const Vector3& u, const Vector3& v)
    {
      Quaternion* q(new Quaternion); q->setFromTwoVectors(u,v);
      return q;
    }

    static Quaternion* FromOneVector(const Vector4& v)
    {
      Quaternion* q(new Quaternion(v));
      return q;
    }

    static bool __eq__(const Quaternion & u, const Quaternion & v)
    {
      return u.coeffs() == v.coeffs();
    }

    static bool __ne__(const Quaternion& u, const Quaternion& v)
    {
      return !__eq__(u,v);
    }

    static Scalar __getitem__(const Quaternion & self, int idx)
    {
      if((idx<0) || (idx>=4)) throw eigenpy::ExceptionIndex(idx,0,3);
      return self.coeffs()[idx];
    }

    static void __setitem__(Quaternion& self, int idx, const Scalar value)
    {
      if((idx<0) || (idx>=4)) throw eigenpy::ExceptionIndex(idx,0,3);
      self.coeffs()[idx] = value;
    }

    static int __len__() {  return 4;  }
    static Vector3 vec(const Quaternion & self) { return self.vec(); }

    static std::string print(const Quaternion & self)
    {
      std::stringstream ss;
      ss << "(x,y,z,w) = " << self.coeffs().transpose() << std::endl;

      return ss.str();
    }

    static Quaternion slerp(const Quaternion & self, const Scalar t, const Quaternion & other)
    { return self.slerp(t,other); }

  public:

    static void expose()
    {
      bp::class_<Quaternion>("Quaternion",
                             "Quaternion representing rotation.\n\n"
                             "Supported operations "
                             "('q is a Quaternion, 'v' is a Vector3): "
                             "'q*q' (rotation composition), "
                             "'q*=q', "
                             "'q*v' (rotating 'v' by 'q'), "
                             "'q==q', 'q!=q', 'q[0..3]'.",
                             bp::no_init)
      .def(QuaternionVisitor<Quaternion>());

      // Cast to Eigen::QuaternionBase and vice-versa
      bp::implicitly_convertible<Quaternion,QuaternionBase >();
//      bp::implicitly_convertible<QuaternionBase,Quaternion >();
    }

  };

} // namespace eigenpy

#endif // ifndef __eigenpy_quaternion_hpp__
<commit_msg>geometry: fix default constructor<commit_after>/*
 * Copyright 2014-2021 CNRS INRIA
 */

#ifndef __eigenpy_quaternion_hpp__
#define __eigenpy_quaternion_hpp__

#include "eigenpy/eigenpy.hpp"

#include <Eigen/Core>
#include <Eigen/Geometry>

#include "eigenpy/exception.hpp"

namespace boost { namespace python { namespace converter {

  /// \brief Template specialization of rvalue_from_python_data
  template<typename Quaternion>
  struct rvalue_from_python_data<Eigen::QuaternionBase<Quaternion> const &>
  : rvalue_from_python_data_eigen<Quaternion const &>
  {
    EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(Quaternion const &)
  };

  template <class Quaternion>
  struct implicit<Quaternion, Eigen::QuaternionBase<Quaternion> >
  {
    typedef Quaternion Source;
    typedef Eigen::QuaternionBase<Quaternion> Target;

    static void* convertible(PyObject* obj)
    {
      // Find a converter which can produce a Source instance from
      // obj. The user has told us that Source can be converted to
      // Target, and instantiating construct() below, ensures that
      // at compile-time.
      return implicit_rvalue_convertible_from_python(obj, registered<Source>::converters)
      ? obj : 0;
    }

    static void construct(PyObject* obj, rvalue_from_python_stage1_data* data)
    {
      void* storage = ((rvalue_from_python_storage<Target>*)data)->storage.bytes;

      arg_from_python<Source> get_source(obj);
      bool convertible = get_source.convertible();
      BOOST_VERIFY(convertible);

      new (storage) Source(get_source());

      // record successful construction
      data->convertible = storage;
    }
  };

}}} // namespace boost::python::converter

namespace eigenpy
{

  class ExceptionIndex : public Exception
  {
  public:
    ExceptionIndex(int index,int imin,int imax) : Exception("")
    {
      std::ostringstream oss; oss << "Index " << index << " out of range " << imin << ".."<< imax <<".";
      message = oss.str();
    }
  };

  namespace bp = boost::python;

  template<typename QuaternionDerived> class QuaternionVisitor;

  template<typename Scalar, int Options>
  struct call< Eigen::Quaternion<Scalar,Options> >
  {
    typedef Eigen::Quaternion<Scalar,Options> Quaternion;
    static inline void expose()
    {
      QuaternionVisitor<Quaternion>::expose();
    }

    static inline bool isApprox(const Quaternion & self, const Quaternion & other,
                                const Scalar & prec = Eigen::NumTraits<Scalar>::dummy_precision())
    {
      return self.isApprox(other,prec);
    }
  };

  template<typename Quaternion>
  class QuaternionVisitor
  :  public bp::def_visitor< QuaternionVisitor<Quaternion> >
  {
    typedef Eigen::QuaternionBase<Quaternion> QuaternionBase;

    typedef typename QuaternionBase::Scalar Scalar;
    typedef typename Quaternion::Coefficients Coefficients;
    typedef typename QuaternionBase::Vector3 Vector3;
    typedef Coefficients Vector4;
    typedef typename QuaternionBase::Matrix3 Matrix3;

    typedef typename QuaternionBase::AngleAxisType AngleAxis;

    BOOST_PYTHON_FUNCTION_OVERLOADS(isApproxQuaternion_overload,call<Quaternion>::isApprox,2,3)

  public:

    template<class PyClass>
    void visit(PyClass& cl) const
    {
      cl
      .def(bp::init<Matrix3>((bp::arg("self"),bp::arg("R")),
                             "Initialize from rotation matrix.\n"
                             "\tR : a rotation matrix 3x3.")[bp::return_value_policy<bp::return_by_value>()])
      .def(bp::init<AngleAxis>((bp::arg("self"),bp::arg("aa")),
                               "Initialize from an angle axis.\n"
                               "\taa: angle axis object."))
      .def(bp::init<Quaternion>((bp::arg("self"),bp::arg("quat")),
                                "Copy constructor.\n"
                                "\tquat: a quaternion.")[bp::return_value_policy<bp::return_by_value>()])
      .def("__init__",bp::make_constructor(&QuaternionVisitor::FromTwoVectors,
                                           bp::default_call_policies(),
                                           (bp::arg("u"),bp::arg("v"))),
           "Initialize from two vectors u and v")
      .def("__init__",bp::make_constructor(&QuaternionVisitor::FromOneVector,
                                           bp::default_call_policies(),
                                           (bp::arg("vec4"))),
           "Initialize from a vector 4D.\n"
           "\tvec4 : a 4D vector representing quaternion coefficients in the order xyzw.")
      .def("__init__",bp::make_constructor(&QuaternionVisitor::DefaultConstructor),
           "Default constructor")
      .def(bp::init<Scalar,Scalar,Scalar,Scalar>
           ((bp::arg("self"),bp::arg("w"),bp::arg("x"),bp::arg("y"),bp::arg("z")),
            "Initialize from coefficients.\n\n"
            "... note:: The order of coefficients is *w*, *x*, *y*, *z*. "
            "The [] operator numbers them differently, 0...4 for *x* *y* *z* *w*!"))

      .add_property("x",
                    &QuaternionVisitor::getCoeff<0>,
                    &QuaternionVisitor::setCoeff<0>,"The x coefficient.")
      .add_property("y",
                    &QuaternionVisitor::getCoeff<1>,
                    &QuaternionVisitor::setCoeff<1>,"The y coefficient.")
      .add_property("z",
                    &QuaternionVisitor::getCoeff<2>,
                    &QuaternionVisitor::setCoeff<2>,"The z coefficient.")
      .add_property("w",
                    &QuaternionVisitor::getCoeff<3>,
                    &QuaternionVisitor::setCoeff<3>,"The w coefficient.")

      .def("isApprox",
           &call<Quaternion>::isApprox,
           isApproxQuaternion_overload(bp::args("self","other","prec"),
                                       "Returns true if *this is approximately equal to other, within the precision determined by prec."))

      /* --- Methods --- */
      .def("coeffs",(const Vector4 & (Quaternion::*)()const)&Quaternion::coeffs,
           bp::arg("self"),
           "Returns a vector of the coefficients (x,y,z,w)",
           bp::return_internal_reference<>())
      .def("matrix",&Quaternion::matrix,
           bp::arg("self"),
           "Returns an equivalent 3x3 rotation matrix. Similar to toRotationMatrix.")
      .def("toRotationMatrix",&Quaternion::toRotationMatrix,
//           bp::arg("self"), // Bug in Boost.Python
           "Returns an equivalent 3x3 rotation matrix.")

      .def("setFromTwoVectors",&setFromTwoVectors,((bp::arg("self"),bp::arg("a"),bp::arg("b"))),
           "Set *this to be the quaternion which transforms a into b through a rotation."
           ,bp::return_self<>())
      .def("conjugate",&Quaternion::conjugate,
           bp::arg("self"),
           "Returns the conjugated quaternion.\n"
           "The conjugate of a quaternion represents the opposite rotation.")
      .def("inverse",&Quaternion::inverse,
           bp::arg("self"),
           "Returns the quaternion describing the inverse rotation.")
      .def("setIdentity",&Quaternion::setIdentity,
           bp::arg("self"),
           "Set *this to the idendity rotation.",bp::return_self<>())
      .def("norm",&Quaternion::norm,
           bp::arg("self"),
           "Returns the norm of the quaternion's coefficients.")
      .def("normalize",&Quaternion::normalize,
           bp::arg("self"),
           "Normalizes the quaternion *this.")
      .def("normalized",&Quaternion::normalized,
           bp::arg("self"),
           "Returns a normalized copy of *this.")
      .def("squaredNorm",&Quaternion::squaredNorm,
           bp::arg("self"),
           "Returns the squared norm of the quaternion's coefficients.")
      .def("dot",&Quaternion::template dot<Quaternion>,
           (bp::arg("self"),bp::arg("other")),
           "Returns the dot product of *this with an other Quaternion.\n"
           "Geometrically speaking, the dot product of two unit quaternions corresponds to the cosine of half the angle between the two rotations.")
      .def("_transformVector",&Quaternion::_transformVector,
           (bp::arg("self"),bp::arg("vector")),
           "Rotation of a vector by a quaternion.")
      .def("vec",&vec,
           bp::arg("self"),
           "Returns a vector expression of the imaginary part (x,y,z).")
      .def("angularDistance",
//           (bp::arg("self"),bp::arg("other")), // Bug in Boost.Python
           &Quaternion::template angularDistance<Quaternion>,
           "Returns the angle (in radian) between two rotations.")
      .def("slerp",&slerp,bp::args("self","t","other"),
           "Returns the spherical linear interpolation between the two quaternions *this and other at the parameter t in [0;1].")

      /* --- Operators --- */
      .def(bp::self * bp::self)
      .def(bp::self *= bp::self)
      .def(bp::self * bp::other<Vector3>())
      .def("__eq__",&QuaternionVisitor::__eq__)
      .def("__ne__",&QuaternionVisitor::__ne__)
      .def("__abs__",&Quaternion::norm)
      .def("__len__",&QuaternionVisitor::__len__).staticmethod("__len__")
      .def("__setitem__",&QuaternionVisitor::__setitem__)
      .def("__getitem__",&QuaternionVisitor::__getitem__)
      .def("assign",&assign<Quaternion>,
           bp::args("self","quat"),
           "Set *this from an quaternion quat and returns a reference to *this.",
           bp::return_self<>())
      .def("assign",(Quaternion & (Quaternion::*)(const AngleAxis &))&Quaternion::operator=,
           bp::args("self","aa"),
           "Set *this from an angle-axis aa and returns a reference to *this.",
           bp::return_self<>())
      .def("__str__",&print)
      .def("__repr__",&print)

//      .def("FromTwoVectors",&Quaternion::template FromTwoVectors<Vector3,Vector3>,
//           bp::args("a","b"),
//           "Returns the quaternion which transform a into b through a rotation.")
      .def("FromTwoVectors",&FromTwoVectors,
           bp::args("a","b"),
           "Returns the quaternion which transforms a into b through a rotation.",
           bp::return_value_policy<bp::manage_new_object>())
      .staticmethod("FromTwoVectors")
      .def("Identity",&Identity,
           "Returns a quaternion representing an identity rotation.",
           bp::return_value_policy<bp::manage_new_object>())
      .staticmethod("Identity")
      ;
    }
  private:

    template<int i>
    static void setCoeff(Quaternion & self, Scalar value) { self.coeffs()[i] = value; }

    template<int i>
    static Scalar getCoeff(Quaternion & self) { return self.coeffs()[i]; }

    static Quaternion & setFromTwoVectors(Quaternion & self, const Vector3 & a, const Vector3 & b)
    { return self.setFromTwoVectors(a,b); }

    template<typename OtherQuat>
    static Quaternion & assign(Quaternion & self, const OtherQuat & quat)
    { return self = quat; }

    static Quaternion* Identity()
    {
      Quaternion* q(new Quaternion); q->setIdentity();
      return q;
    }

    static Quaternion* FromTwoVectors(const Vector3& u, const Vector3& v)
    {
      Quaternion* q(new Quaternion); q->setFromTwoVectors(u,v);
      return q;
    }

    static Quaternion* DefaultConstructor()
    {
      return new Quaternion;
    }

    static Quaternion* FromOneVector(const Vector4& v)
    {
      Quaternion* q(new Quaternion(v));
      return q;
    }

    static bool __eq__(const Quaternion & u, const Quaternion & v)
    {
      return u.coeffs() == v.coeffs();
    }

    static bool __ne__(const Quaternion& u, const Quaternion& v)
    {
      return !__eq__(u,v);
    }

    static Scalar __getitem__(const Quaternion & self, int idx)
    {
      if((idx<0) || (idx>=4)) throw eigenpy::ExceptionIndex(idx,0,3);
      return self.coeffs()[idx];
    }

    static void __setitem__(Quaternion& self, int idx, const Scalar value)
    {
      if((idx<0) || (idx>=4)) throw eigenpy::ExceptionIndex(idx,0,3);
      self.coeffs()[idx] = value;
    }

    static int __len__() {  return 4;  }
    static Vector3 vec(const Quaternion & self) { return self.vec(); }

    static std::string print(const Quaternion & self)
    {
      std::stringstream ss;
      ss << "(x,y,z,w) = " << self.coeffs().transpose() << std::endl;

      return ss.str();
    }

    static Quaternion slerp(const Quaternion & self, const Scalar t, const Quaternion & other)
    { return self.slerp(t,other); }

  public:

    static void expose()
    {
      bp::class_<Quaternion>("Quaternion",
                             "Quaternion representing rotation.\n\n"
                             "Supported operations "
                             "('q is a Quaternion, 'v' is a Vector3): "
                             "'q*q' (rotation composition), "
                             "'q*=q', "
                             "'q*v' (rotating 'v' by 'q'), "
                             "'q==q', 'q!=q', 'q[0..3]'.",
                             bp::no_init)
      .def(QuaternionVisitor<Quaternion>());

      // Cast to Eigen::QuaternionBase and vice-versa
      bp::implicitly_convertible<Quaternion,QuaternionBase >();
//      bp::implicitly_convertible<QuaternionBase,Quaternion >();
    }

  };

} // namespace eigenpy

#endif // ifndef __eigenpy_quaternion_hpp__
<|endoftext|>


<commit_before>#pragma once
#include <string>

#include <stlw/result.hpp>
#include <game/game.hpp>

// TODO: remove this, THIS is the game loop code and this is sdl specific.
// TODO: from cpp
#include <engine/window/sdl_window.hpp>
#include <engine/gfx/shader.hpp>
#include <stlw/type_ctors.hpp>

namespace game
{
namespace boomhs
{

auto log_error = [](auto const line)
    {
      GLenum err = GL_NO_ERROR;
      while((err = glGetError()) != GL_NO_ERROR) {
        std::cerr << "GL error! '" << std::hex << err << "' line #" << std::to_string(line) << std::endl;
        return;
      }
      std::string error = SDL_GetError();
      if (error != "") {
        std::cout << "SLD Error : " << error << std::endl;
        SDL_ClearError();
      }
    };

struct boomhs_game
{
  using window_type = ::engine::window::window;

  boomhs_game() = delete;

  static bool
  process_event(SDL_Event &event)
  {
    log_error(__LINE__);
    return event.type == SDL_QUIT;
  }

  static decltype(auto)
  loop_once(window_type &window)
  {
    SDL_Event event;
    bool quit = false;
    while (0 != SDL_PollEvent(&event)) {
      quit = process_event(event);
    }

    // don't quit
    return quit;
  }

  static void
  render(window_type &window, GLuint const program_id, GLuint const VAO, GLuint const VBO)
  {
    // Render
    log_error(__LINE__);
    glClear(GL_COLOR_BUFFER_BIT);
    log_error(__LINE__);

    uint32_t ticks = SDL_GetTicks(), lastticks = 0;
    ticks = SDL_GetTicks();
    if ( ((ticks*10-lastticks*10)) < 167 ) {
      SDL_Delay( (167-((ticks*10-lastticks*10)))/10 );
      log_error(__LINE__);
    }
    lastticks = SDL_GetTicks();
    log_error(__LINE__);

    /////////////////////////////////////////////////////////////////////////////////

    // Draw our first triangle
    glUseProgram(program_id);
    log_error(__LINE__);

    char buffer[2096];
    int actual_length = 0;
    glGetProgramInfoLog(program_id, 2096, &actual_length, buffer);
    if (0 < actual_length) {
      std::cerr << "log: '" << std::to_string(buffer[0]) << "'\n";
    }

    log_error(__LINE__);
    glBindVertexArray(VAO);
    log_error(__LINE__);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    log_error(__LINE__);
    glBindVertexArray(0);
    log_error(__LINE__);

    // Update window with OpenGL rendering
    SDL_GL_SwapWindow(window.raw());
    log_error(__LINE__);
    SDL_Delay(20);
    log_error(__LINE__);
}

  static stlw::result<stlw::empty_type, std::string>
  game_loop(window_type &&window)
  {
    bool quit = false;

    // Set up vertex data (and buffer(s)) and attribute pointers
    constexpr GLfloat W = 1.0f;
    constexpr GLfloat vertices[] = {
      -0.5f, -0.5f, 0.0f, W,
      0.5f, -0.5f, 0.0f, W,
      0.0f,  0.5f, 0.0f, W
    };
    GLuint VBO, VAO;
    glGenVertexArrays(1, &VAO);
    ON_SCOPE_EXIT([&]() { glDeleteVertexArrays(1, &VAO); });

    glGenBuffers(1, &VBO);
    ON_SCOPE_EXIT([&]() { glDeleteBuffers(1, &VBO); });

    // Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).
    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0); // Unbind when we are done with this scope automatically.

    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    //auto const data = get_data();
    // Create and compile our GLSL program from the shaders
    // TODO: decide if it's the game loop's responsibility to load the shaders (I'm guessing not)
    auto const expected_program = engine::gfx::load_shaders("shader.vert", "shader.frag");
    if (! expected_program) {
      std::cerr << "expected_program is error '" << expected_program.error() << "'\n";
      quit = true;
    }
    GLuint const program_id = *expected_program;
    ON_SCOPE_EXIT([&]() { glDeleteProgram(program_id); });

    while (! quit) {
      quit = loop_once(window);
      render(window, program_id, VAO, VBO);
    }
    return stlw::make_empty();
  }
};

struct policy
{
  policy() = delete;
  using game_type = boomhs_game;

  DEFINE_STATIC_WRAPPER_FUNCTION(game_loop, game_type::game_loop);
};

} // ns boomhs
} // ns game
<commit_msg>More cleanup inside boomhs<commit_after>#pragma once
#include <string>

#include <stlw/result.hpp>
#include <game/game.hpp>

// TODO: remove this, THIS is the game loop code and this is sdl specific.
// TODO: from cpp
#include <engine/window/sdl_window.hpp>
#include <engine/gfx/shader.hpp>
#include <stlw/type_ctors.hpp>

namespace game
{
namespace boomhs
{

auto log_error = [](auto const line)
    {
      GLenum err = GL_NO_ERROR;
      while((err = glGetError()) != GL_NO_ERROR) {
        std::cerr << "GL error! '" << std::hex << err << "' line #" << std::to_string(line) << std::endl;
        return;
      }
      std::string error = SDL_GetError();
      if (error != "") {
        std::cout << "SLD Error : " << error << std::endl;
        SDL_ClearError();
      }
    };

struct boomhs_game
{
  using window_type = ::engine::window::window;

  boomhs_game() = delete;

  static bool
  process_event(SDL_Event &event)
  {
    log_error(__LINE__);
    return event.type == SDL_QUIT;
  }

  static decltype(auto)
  loop_once(window_type &window)
  {
    SDL_Event event;
    bool quit = false;
    while (0 != SDL_PollEvent(&event)) {
      quit = process_event(event);
    }

    // don't quit
    return quit;
  }

  static void
  render(window_type &window, GLuint const program_id, GLuint const VAO)
  {
    // Render
    log_error(__LINE__);
    glClear(GL_COLOR_BUFFER_BIT);
    log_error(__LINE__);

    uint32_t ticks = SDL_GetTicks(), lastticks = 0;
    ticks = SDL_GetTicks();
    if ( ((ticks*10-lastticks*10)) < 167 ) {
      SDL_Delay( (167-((ticks*10-lastticks*10)))/10 );
      log_error(__LINE__);
    }
    lastticks = SDL_GetTicks();
    log_error(__LINE__);

    /////////////////////////////////////////////////////////////////////////////////

    // Draw our first triangle
    glUseProgram(program_id);
    log_error(__LINE__);

    char buffer[2096];
    int actual_length = 0;
    glGetProgramInfoLog(program_id, 2096, &actual_length, buffer);
    if (0 < actual_length) {
      std::cerr << "log: '" << std::to_string(buffer[0]) << "'\n";
    }

    log_error(__LINE__);
    glBindVertexArray(VAO);
    log_error(__LINE__);

    glDrawArrays(GL_TRIANGLES, 0, 3);
    log_error(__LINE__);
    glBindVertexArray(0);
    log_error(__LINE__);

    // Update window with OpenGL rendering
    SDL_GL_SwapWindow(window.raw());
    log_error(__LINE__);
    SDL_Delay(20);
    log_error(__LINE__);
  }

  static stlw::result<stlw::empty_type, std::string>
  game_loop(window_type &&window)
  {
    // Set up vertex data (and buffer(s)) and attribute pointers
    constexpr GLfloat W = 1.0f;
    constexpr GLfloat vertices[] = {
      -0.5f, -0.5f, 0.0f, W,
      0.5f, -0.5f, 0.0f, W,
      0.0f,  0.5f, 0.0f, W
    };

    GLuint VBO, VAO;
    glGenVertexArrays(1, &VAO);
    ON_SCOPE_EXIT([&]() { glDeleteVertexArrays(1, &VAO); });

    glGenBuffers(1, &VBO);
    ON_SCOPE_EXIT([&]() { glDeleteBuffers(1, &VBO); });

    auto const send_vertices_gpu = [](auto const& vbo, auto const& vertices)
    {
      // Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).
      glBindBuffer(GL_ARRAY_BUFFER, vbo);
      glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

      glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), static_cast<GLvoid*>(nullptr));

      glBindBuffer(GL_ARRAY_BUFFER, 0);
      glBindVertexArray(0); // Unbind when we are done with this scope automatically.
    };
    glBindVertexArray(VAO);
    glEnableVertexAttribArray(0);

    send_vertices_gpu(VBO, vertices);

    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    // TODO: decide if it's the game loop's responsibility to load the shaders (I'm guessing not)
    DO_MONAD(GLuint const program_id, engine::gfx::load_shaders("shader.vert", "shader.frag"));
    ON_SCOPE_EXIT([&]() { glDeleteProgram(program_id); });

    bool quit = false;
    while (! quit) {
      quit = loop_once(window);
      render(window, program_id, VAO);
    }
    return stlw::make_empty();
  }
};

struct policy
{
  policy() = delete;
  using game_type = boomhs_game;

  DEFINE_STATIC_WRAPPER_FUNCTION(game_loop, game_type::game_loop);
};

} // ns boomhs
} // ns game
<|endoftext|>


<commit_before>/*

Copyright (c) 2003, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_VERSION_HPP_INCLUDED
#define TORRENT_VERSION_HPP_INCLUDED

#define LIBTORRENT_VERSION_MAJOR 0
#define LIBTORRENT_VERSION_MINOR 13

#define LIBTORRENT_VERSION "0.13.0.0"

#endif
<commit_msg>bumped version number<commit_after>/*

Copyright (c) 2003, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_VERSION_HPP_INCLUDED
#define TORRENT_VERSION_HPP_INCLUDED

#define LIBTORRENT_VERSION_MAJOR 0
#define LIBTORRENT_VERSION_MINOR 14

#define LIBTORRENT_VERSION "0.14.0.0"

#endif
<|endoftext|>


<commit_before><commit_msg>[ci skip] [WIP] feat(improve-tool): Export implemented cards by ability<commit_after><|endoftext|>


<commit_before>#include "HotKeys.h"

#ifdef TARGET_LINUX
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/X.h>
#include <GL/glx.h>

bool getModifierSelection(){
	return getModifierShiftPressed();
}

//COMMAND on OS X, CTRL on Windows
//----------------------------------------
bool getModifierShortcutKeyPressed(){
	return getModifierPressed(MODIFIER_KEY_CTRL);
}

bool getModifierPressed(ModifierKey mod){
	unsigned int t = 0;

	//return false;
	Display* disp = glXGetCurrentDisplay();
	char key_map_stat[32];
	XQueryKeymap(disp, key_map_stat);

	if ((MODIFIER_KEY_ALT & mod) == MODIFIER_KEY_ALT){
		const KeyCode alt_l = XKeysymToKeycode(disp,XK_Alt_L);
		const KeyCode alt_r = XKeysymToKeycode(disp,XK_Alt_R);

		return (((key_map_stat[alt_l >> 3] >> (alt_l & 7)) & 1)
			  ||((key_map_stat[alt_r >> 3] >> (alt_r & 7)) & 1));
	}

	if ((MODIFIER_KEY_CTRL & mod) == MODIFIER_KEY_CTRL){
		const KeyCode control_l = XKeysymToKeycode(disp,XK_Control_L);
		const KeyCode control_r = XKeysymToKeycode(disp,XK_Control_R);

		return (((key_map_stat[control_l >> 3] >> (control_l & 7)) & 1)
			  ||((key_map_stat[control_r >> 3] >> (control_r & 7)) & 1));
	}

	if((MODIFIER_KEY_SHIFT & mod) == MODIFIER_KEY_SHIFT ){
		const KeyCode shift_l = XKeysymToKeycode(disp,XK_Shift_L);
		const KeyCode shift_r = XKeysymToKeycode(disp,XK_Shift_R);

		return (((key_map_stat[shift_l >> 3] >> (shift_l & 7)) & 1)
			  ||((key_map_stat[shift_r >> 3] >> (shift_r & 7)) & 1));
	}

	if ((MODIFIER_KEY_SPECIAL  & mod) == MODIFIER_KEY_SPECIAL){
		const KeyCode control_l = XKeysymToKeycode(disp,XK_Super_L);
		const KeyCode control_r = XKeysymToKeycode(disp,XK_Super_R);

		return (((key_map_stat[control_l >> 3] >> (control_l & 7)) & 1)
			  ||((key_map_stat[control_r >> 3] >> (control_r & 7)) & 1));
	}

	return false;
}

#endif
<commit_msg>fixing hotkeys for linux64<commit_after>#include "HotKeys.h"

#if defined(TARGET_LINUX) || defined(OF_TARGET_LINUX64)
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/X.h>
#include <GL/glx.h>

bool getModifierSelection(){
	return getModifierShiftPressed();
}

//COMMAND on OS X, CTRL on Windows
//----------------------------------------
bool getModifierShortcutKeyPressed(){
	return getModifierPressed(MODIFIER_KEY_CTRL);
}

bool getModifierPressed(ModifierKey mod){
	unsigned int t = 0;

	//return false;
	Display* disp = glXGetCurrentDisplay();
	char key_map_stat[32];
	XQueryKeymap(disp, key_map_stat);

	if ((MODIFIER_KEY_ALT & mod) == MODIFIER_KEY_ALT){
		const KeyCode alt_l = XKeysymToKeycode(disp,XK_Alt_L);
		const KeyCode alt_r = XKeysymToKeycode(disp,XK_Alt_R);

		return (((key_map_stat[alt_l >> 3] >> (alt_l & 7)) & 1)
			  ||((key_map_stat[alt_r >> 3] >> (alt_r & 7)) & 1));
	}

	if ((MODIFIER_KEY_CTRL & mod) == MODIFIER_KEY_CTRL){
		const KeyCode control_l = XKeysymToKeycode(disp,XK_Control_L);
		const KeyCode control_r = XKeysymToKeycode(disp,XK_Control_R);

		return (((key_map_stat[control_l >> 3] >> (control_l & 7)) & 1)
			  ||((key_map_stat[control_r >> 3] >> (control_r & 7)) & 1));
	}

	if((MODIFIER_KEY_SHIFT & mod) == MODIFIER_KEY_SHIFT ){
		const KeyCode shift_l = XKeysymToKeycode(disp,XK_Shift_L);
		const KeyCode shift_r = XKeysymToKeycode(disp,XK_Shift_R);

		return (((key_map_stat[shift_l >> 3] >> (shift_l & 7)) & 1)
			  ||((key_map_stat[shift_r >> 3] >> (shift_r & 7)) & 1));
	}

	if ((MODIFIER_KEY_SPECIAL  & mod) == MODIFIER_KEY_SPECIAL){
		const KeyCode control_l = XKeysymToKeycode(disp,XK_Super_L);
		const KeyCode control_r = XKeysymToKeycode(disp,XK_Super_R);

		return (((key_map_stat[control_l >> 3] >> (control_l & 7)) & 1)
			  ||((key_map_stat[control_r >> 3] >> (control_r & 7)) & 1));
	}

	return false;
}

#endif
<|endoftext|>


<commit_before>#include <hermit/task_remapper.hpp>
#include <unistd.h>

int main() {
  hermit::task_remapper sched( 1 );
  auto foo = sched.post( [](){ std::cout << "foo" << std::endl; }, boost::posix_time::milliseconds(200) );
  auto bar = sched.post( [](){ std::cout << "bar" << std::endl; }, boost::posix_time::milliseconds(300) );
  sleep( 5 );
}

<commit_msg>shared_ptrの中身が突然消える謎現象追跡中<commit_after>#include <hermit/task_remapper.hpp>
#include <unistd.h>
#include <boost/optional.hpp>

hermit::poller hoge( hermit::task_remapper &sched ) {
  return sched.post( [](){ std::cout << "foo" << std::endl; }, boost::posix_time::milliseconds(200) );
}

int main() {
  hermit::task_remapper sched( 1 );
  boost::optional< hermit::poller > foo = hoge( sched );
  sleep( 1 );
  foo = boost::optional< hermit::poller >();
  sleep( 1 );
}

<|endoftext|>


<commit_before>#include "nlt_store.hpp"
#include <terark/int_vector.hpp>
#include <terark/fast_zip_blob_store.hpp>
#include <typeinfo>
#include <float.h>

namespace terark { namespace db { namespace dfadb {

TERARK_DB_REGISTER_STORE("nlt", NestLoudsTrieStore);

NestLoudsTrieStore::NestLoudsTrieStore(const Schema& schema) {
}
NestLoudsTrieStore::~NestLoudsTrieStore() {
}

llong NestLoudsTrieStore::dataStorageSize() const {
	return m_store->mem_size();
}

llong NestLoudsTrieStore::dataInflateSize() const {
	return m_store->total_data_size();
}

llong NestLoudsTrieStore::numDataRows() const {
	return m_store->num_records();
}

void NestLoudsTrieStore::getValueAppend(llong id, valvec<byte>* val, DbContext* ctx) const {
	m_store->get_record_append(size_t(id), val);
}

StoreIterator* NestLoudsTrieStore::createStoreIterForward(DbContext*) const {
	return nullptr; // not needed
}

StoreIterator* NestLoudsTrieStore::createStoreIterBackward(DbContext*) const {
	return nullptr; // not needed
}

template<class Class>
static
Class* doBuild(const NestLoudsTrieConfig& conf,
			   const Schema& schema, SortableStrVec& strVec) {
	std::unique_ptr<Class> trie(new Class());
	trie->build_from(strVec, conf);
	return trie.release();
}

static
void initConfigFromSchema(NestLoudsTrieConfig& conf, const Schema& schema) {
	conf.initFromEnv();
	if (schema.m_sufarrMinFreq) {
		conf.saFragMinFreq = (byte_t)schema.m_sufarrMinFreq;
	}
	if (schema.m_minFragLen) {
		conf.minFragLen = schema.m_minFragLen;
	}
	if (schema.m_maxFragLen) {
		conf.maxFragLen = schema.m_maxFragLen;
	}
	if (schema.m_nltDelims.size()) {
		conf.setBestDelims(schema.m_nltDelims.c_str());
	}
	conf.nestLevel = schema.m_nltNestLevel;
}

static
BlobStore* nltBuild(const Schema& schema, SortableStrVec& strVec) {
	NestLoudsTrieConfig conf;
	initConfigFromSchema(conf, schema);
	switch (schema.m_rankSelectClass) {
	case -256:
		return doBuild<NestLoudsTrieBlobStore_IL>(conf, schema, strVec);
	case +256:
		return doBuild<NestLoudsTrieBlobStore_SE>(conf, schema, strVec);
	case +512:
		return doBuild<NestLoudsTrieBlobStore_SE_512>(conf, schema, strVec);
	default:
		fprintf(stderr, "WARN: invalid schema(%s).rs = %d, use default: se_512\n"
					  , schema.m_name.c_str(), schema.m_rankSelectClass);
		return doBuild<NestLoudsTrieBlobStore_SE_512>(conf, schema, strVec);
	}
}

void NestLoudsTrieStore::build(const Schema& schema, SortableStrVec& strVec) {
	if (schema.m_dictZipSampleRatio > 0) {
		std::unique_ptr<DictZipBlobStore> zds(new DictZipBlobStore());
		zds->build_none_local_match(strVec, schema.m_dictZipSampleRatio);
		m_store.reset(zds.release());
	}
	else if (schema.m_useFastZip) {
		std::unique_ptr<FastZipBlobStore> fzds(new FastZipBlobStore());
		NestLoudsTrieConfig  conf;
		initConfigFromSchema(conf, schema);
		fzds->build_from(strVec, conf);
		m_store.reset(fzds.release());
	}
	else {
		m_store.reset(nltBuild(schema, strVec));
	}
}

void
NestLoudsTrieStore::build_by_iter(const Schema& schema, PathRef fpath,
								  StoreIterator& iter,
								  const bm_uint_t* isDel,
								  const febitvec* isPurged) {
	std::unique_ptr<DictZipBlobStore> zds(new DictZipBlobStore());
	std::unique_ptr<DictZipBlobStore::ZipBuilder> builder(zds->createZipBuilder());
	double sampleRatio = schema.m_dictZipSampleRatio > FLT_EPSILON
					   ? schema.m_dictZipSampleRatio : 0.05;
	valvec<byte> rec;
	auto emptyCheckProtect = [&](size_t sampled) {
	//	TERARK_RT_assert(sampled > 0, std::logic_error);
		if (0 == sampled) {
			if (rec.empty())
				builder->addSample("Hello World!"); // for fallback
			else
				builder->addSample(rec);
		}
	};
	if (NULL == isPurged || isPurged->size() == 0) {
		llong recId;
		size_t sampled = 0;
		while (iter.increment(&recId, &rec)) {
			if (NULL == isDel || !terark_bit_test(isDel, recId)) {
				if (rand() < RAND_MAX * sampleRatio ) {
					builder->addSample(rec);
					sampled++;
				}
			}
		}
		emptyCheckProtect(sampled);
		builder->prepare(recId + 1, fpath.string());
		iter.reset();
		while (iter.increment(&recId, &rec)) {
			if (NULL == isDel || !terark_bit_test(isDel, recId)) {
				builder->addRecord(rec);
			}
		}
	}
	else {
		assert(NULL != isDel);
		llong  newPhysicId = 0;
		llong  physicId = 0;
		size_t logicNum = isPurged->size();
		size_t sampled = 0;
		const bm_uint_t* isPurgedptr = isPurged->bldata();
		for (size_t logicId = 0; logicId < logicNum; ++logicId) {
			if (!terark_bit_test(isPurgedptr, logicId)) {
				if (!terark_bit_test(isDel, logicId)) {
					bool hasData = iter.seekExact(physicId, &rec);
					TERARK_RT_assert(hasData, std::logic_error);
				//	if (hasData && rec.empty()) {
				//		hasData = false;
				//	}
					if (rand() < RAND_MAX * sampleRatio) {
						builder->addSample(rec);
						sampled++;
					}
					newPhysicId++;
				}
				physicId++;
			}
		}
		emptyCheckProtect(sampled);
		builder->prepare(newPhysicId, fpath.string());
		iter.reset();
		physicId = 0;
		for (size_t logicId = 0; logicId < logicNum; ++logicId) {
			if (!terark_bit_test(isPurgedptr, logicId)) {
				bool hasData = iter.increment(&physicId, &rec);
				TERARK_RT_assert(hasData, std::logic_error);
				if (!terark_bit_test(isDel, logicId)) {
					builder->addRecord(rec);
				}
				physicId++;
			}
		}
	}
	zds->completeBuild(*builder);
	m_store.reset(zds.release());
}

void NestLoudsTrieStore::load(PathRef path) {
	std::string fpath = fstring(path.string()).endsWith(".nlt")
					  ? path.string()
					  : path.string() + ".nlt";
	m_store.reset(BlobStore::load_from(fpath));
}

void NestLoudsTrieStore::save(PathRef path) const {
	std::string fpath = fstring(path.string()).endsWith(".nlt")
						? path.string()
						: path.string() + ".nlt";
	if (BaseDFA* dfa = dynamic_cast<BaseDFA*>(&*m_store)) {
		dfa->save_mmap(fpath.c_str());
	}
	else if (auto zds = dynamic_cast<FastZipBlobStore*>(&*m_store)) {
		zds->save_mmap(fpath);
	}
	else if (auto zds = dynamic_cast<DictZipBlobStore*>(&*m_store)) {
		zds->save_mmap(fpath);
	}
	else {
		THROW_STD(invalid_argument, "Unexpected");
	}
}

}}} // namespace terark::db::dfadb
<commit_msg>reduce memory usage in parallel data compressing<commit_after>#include "nlt_store.hpp"
#include <terark/int_vector.hpp>
#include <terark/fast_zip_blob_store.hpp>
#include <typeinfo>
#include <float.h>
#include <mutex>

namespace terark { namespace db { namespace dfadb {

TERARK_DB_REGISTER_STORE("nlt", NestLoudsTrieStore);

NestLoudsTrieStore::NestLoudsTrieStore(const Schema& schema) {
}
NestLoudsTrieStore::~NestLoudsTrieStore() {
}

llong NestLoudsTrieStore::dataStorageSize() const {
	return m_store->mem_size();
}

llong NestLoudsTrieStore::dataInflateSize() const {
	return m_store->total_data_size();
}

llong NestLoudsTrieStore::numDataRows() const {
	return m_store->num_records();
}

void NestLoudsTrieStore::getValueAppend(llong id, valvec<byte>* val, DbContext* ctx) const {
	m_store->get_record_append(size_t(id), val);
}

StoreIterator* NestLoudsTrieStore::createStoreIterForward(DbContext*) const {
	return nullptr; // not needed
}

StoreIterator* NestLoudsTrieStore::createStoreIterBackward(DbContext*) const {
	return nullptr; // not needed
}

template<class Class>
static
Class* doBuild(const NestLoudsTrieConfig& conf,
			   const Schema& schema, SortableStrVec& strVec) {
	std::unique_ptr<Class> trie(new Class());
	trie->build_from(strVec, conf);
	return trie.release();
}

static
void initConfigFromSchema(NestLoudsTrieConfig& conf, const Schema& schema) {
	conf.initFromEnv();
	if (schema.m_sufarrMinFreq) {
		conf.saFragMinFreq = (byte_t)schema.m_sufarrMinFreq;
	}
	if (schema.m_minFragLen) {
		conf.minFragLen = schema.m_minFragLen;
	}
	if (schema.m_maxFragLen) {
		conf.maxFragLen = schema.m_maxFragLen;
	}
	if (schema.m_nltDelims.size()) {
		conf.setBestDelims(schema.m_nltDelims.c_str());
	}
	conf.nestLevel = schema.m_nltNestLevel;
}

static
BlobStore* nltBuild(const Schema& schema, SortableStrVec& strVec) {
	NestLoudsTrieConfig conf;
	initConfigFromSchema(conf, schema);
	switch (schema.m_rankSelectClass) {
	case -256:
		return doBuild<NestLoudsTrieBlobStore_IL>(conf, schema, strVec);
	case +256:
		return doBuild<NestLoudsTrieBlobStore_SE>(conf, schema, strVec);
	case +512:
		return doBuild<NestLoudsTrieBlobStore_SE_512>(conf, schema, strVec);
	default:
		fprintf(stderr, "WARN: invalid schema(%s).rs = %d, use default: se_512\n"
					  , schema.m_name.c_str(), schema.m_rankSelectClass);
		return doBuild<NestLoudsTrieBlobStore_SE_512>(conf, schema, strVec);
	}
}

void NestLoudsTrieStore::build(const Schema& schema, SortableStrVec& strVec) {
	if (schema.m_dictZipSampleRatio > 0) {
		std::unique_ptr<DictZipBlobStore> zds(new DictZipBlobStore());
		zds->build_none_local_match(strVec, schema.m_dictZipSampleRatio);
		m_store.reset(zds.release());
	}
	else if (schema.m_useFastZip) {
		std::unique_ptr<FastZipBlobStore> fzds(new FastZipBlobStore());
		NestLoudsTrieConfig  conf;
		initConfigFromSchema(conf, schema);
		fzds->build_from(strVec, conf);
		m_store.reset(fzds.release());
	}
	else {
		m_store.reset(nltBuild(schema, strVec));
	}
}

void
NestLoudsTrieStore::build_by_iter(const Schema& schema, PathRef fpath,
								  StoreIterator& iter,
								  const bm_uint_t* isDel,
								  const febitvec* isPurged) {
	std::unique_ptr<DictZipBlobStore> zds(new DictZipBlobStore());
	std::unique_ptr<DictZipBlobStore::ZipBuilder> builder(zds->createZipBuilder());
	double sampleRatio = schema.m_dictZipSampleRatio > FLT_EPSILON
					   ? schema.m_dictZipSampleRatio : 0.05;

	// 1. sample memory usage = inputBytes*sampleRatio, and will
	//    linear scan the input data
	// 2. builder->prepare() will build the suffix array and cache
	//    for suffix array, and this is all in-memery computing,
	//    the memory usage is about 5*inputBytes*sampleRatio, after
	//    `prepare` finished, the total memory usage is about
	//    6*inputBytes*sampleRatio
	// 3. builder->addRecord() will send the records into compressing
	//    pipeline, records will be compressed parallel, this will
	//    take a long time, the total memory during compressing is
	//    6*inputBytes*sampleRatio, plus few additional working memory
	// 4. using lock, the concurrent large memory using durations in
	//    multi threads are serialized, then the peak memory usage
	//    is reduced
	static std::mutex reduceMemMutex;
	// the lock will be hold for a long time, maybe several minutes
	std::unique_lock<std::mutex> lock(reduceMemMutex, std::defer_lock);

	valvec<byte> rec;
	auto emptyCheckProtect = [&](size_t sampled) {
	//	TERARK_RT_assert(sampled > 0, std::logic_error);
		if (0 == sampled) {
			if (rec.empty())
				builder->addSample("Hello World!"); // for fallback
			else
				builder->addSample(rec);
		}
	};
	if (NULL == isPurged || isPurged->size() == 0) {
		llong recId;
		size_t sampled = 0;
		while (iter.increment(&recId, &rec)) {
			if (NULL == isDel || !terark_bit_test(isDel, recId)) {
				if (rand() < RAND_MAX * sampleRatio ) {
					builder->addSample(rec);
					sampled++;
				}
			}
		}
		emptyCheckProtect(sampled);
		lock.lock(); // start lock
		builder->prepare(recId + 1, fpath.string());
		iter.reset();
		while (iter.increment(&recId, &rec)) {
			if (NULL == isDel || !terark_bit_test(isDel, recId)) {
				builder->addRecord(rec);
			}
		}
	}
	else {
		assert(NULL != isDel);
		llong  newPhysicId = 0;
		llong  physicId = 0;
		size_t logicNum = isPurged->size();
		size_t sampled = 0;
		const bm_uint_t* isPurgedptr = isPurged->bldata();
		for (size_t logicId = 0; logicId < logicNum; ++logicId) {
			if (!terark_bit_test(isPurgedptr, logicId)) {
				if (!terark_bit_test(isDel, logicId)) {
					bool hasData = iter.seekExact(physicId, &rec);
					TERARK_RT_assert(hasData, std::logic_error);
				//	if (hasData && rec.empty()) {
				//		hasData = false;
				//	}
					if (rand() < RAND_MAX * sampleRatio) {
						builder->addSample(rec);
						sampled++;
					}
					newPhysicId++;
				}
				physicId++;
			}
		}
		emptyCheckProtect(sampled);
		lock.lock(); // start lock
		builder->prepare(newPhysicId, fpath.string());
		iter.reset();
		physicId = 0;
		for (size_t logicId = 0; logicId < logicNum; ++logicId) {
			if (!terark_bit_test(isPurgedptr, logicId)) {
				bool hasData = iter.increment(&physicId, &rec);
				TERARK_RT_assert(hasData, std::logic_error);
				if (!terark_bit_test(isDel, logicId)) {
					builder->addRecord(rec);
				}
				physicId++;
			}
		}
	}
	zds->completeBuild(*builder);
	builder.reset(); // explicit destory builder
	lock.unlock();   // explicit unlock
	m_store.reset(zds.release());
}

void NestLoudsTrieStore::load(PathRef path) {
	std::string fpath = fstring(path.string()).endsWith(".nlt")
					  ? path.string()
					  : path.string() + ".nlt";
	m_store.reset(BlobStore::load_from(fpath));
}

void NestLoudsTrieStore::save(PathRef path) const {
	std::string fpath = fstring(path.string()).endsWith(".nlt")
						? path.string()
						: path.string() + ".nlt";
	if (BaseDFA* dfa = dynamic_cast<BaseDFA*>(&*m_store)) {
		dfa->save_mmap(fpath.c_str());
	}
	else if (auto zds = dynamic_cast<FastZipBlobStore*>(&*m_store)) {
		zds->save_mmap(fpath);
	}
	else if (auto zds = dynamic_cast<DictZipBlobStore*>(&*m_store)) {
		zds->save_mmap(fpath);
	}
	else {
		THROW_STD(invalid_argument, "Unexpected");
	}
}

}}} // namespace terark::db::dfadb
<|endoftext|>


<commit_before><commit_msg>Add strStr solution.<commit_after><|endoftext|>


<commit_before>/* /~\_.-~-._,--.._
  |                ~-.._
   |     .     .        \
   |                    /
   |     --....,       | \
   /                      \
  |                        |
  |                        \
  /                         |
  \_.-._  __...___.._______/
        ~~                   */

#pragma once

#include <fstream>
#include <sstream>
#include <string>
#include <utility>

#include <tdpi/tdpi.h>

namespace tppi {
    namespace detail {
        enum class shader_type : GLenum {
            vertex = GL_VERTEX_SHADER,
            fragment = GL_FRAGMENT_SHADER
        };

        template<shader_type S>
        class shader {
        public:
            shader(const std::string& shader_source) : shader_handle(0), compile_status(GL_FALSE) {
                shader_handle = glCreateShader(static_cast<GLenum>(S));

                const char* shader_source_c_str = shader_source.c_str();

                glShaderSource(shader_handle, 1, &shader_source_c_str, nullptr);
                glCompileShader(shader_handle);

                glGetShaderiv(shader_handle, GL_COMPILE_STATUS, &compile_status);

                GLint log_length = 0;
                glGetShaderiv(shader_handle, GL_INFO_LOG_LENGTH, &log_length);

                if (log_length > 1) {
                    info_log_.reserve(log_length);
                    glGetShaderInfoLog(shader_handle, log_length, &log_length, &info_log_[0]);
                }
            }

            shader(shader<S>&& other) noexcept : shader_handle(other.shader_handle), compile_status(other.compile_status), info_log_(std::move(other.info_log_)) {
                other.shader_handle = 0;
                other.compile_status = GL_FALSE;
            }

            ~shader() {
                glDeleteShader(shader_handle);
            }

            operator bool() const noexcept {
                return compile_status == GL_TRUE;
            }

            operator GLuint() const noexcept {
                return shader_handle;
            }

            const std::string& info_log() const noexcept {
                return info_log_;
            }
        private:
            GLuint shader_handle;

            int compile_status;
            std::string info_log_;
        };

        using vertex_shader = shader<shader_type::vertex>;
        using fragment_shader = shader<shader_type::fragment>;

        template<shader_type S>
        shader<S> shader_from_file(const std::string& path) {
            return shader<S>(static_cast<std::stringstream*>(&operator<<(std::stringstream(), std::ifstream(source).rdbuf()))->str());
        }
    }
}
<commit_msg>Improve and make shader.hpp#shader_from_file compile<commit_after>/* /~\_.-~-._,--.._
  |                ~-.._
   |     .     .        \
   |                    /
   |     --....,       | \
   /                      \
  |                        |
  |                        \
  /                         |
  \_.-._  __...___.._______/
        ~~                   */

#pragma once

#include <fstream>
#include <sstream>
#include <string>
#include <utility>

#include <tdpi/tdpi.h>

namespace tppi {
    namespace detail {
        enum class shader_type : GLenum {
            vertex = GL_VERTEX_SHADER,
            fragment = GL_FRAGMENT_SHADER
        };

        template<shader_type S>
        class shader {
        public:
            shader(const std::string& shader_source) : shader_handle(0), compile_status(GL_FALSE) {
                shader_handle = glCreateShader(static_cast<GLenum>(S));

                const char* shader_source_c_str = shader_source.c_str();

                glShaderSource(shader_handle, 1, &shader_source_c_str, nullptr);
                glCompileShader(shader_handle);

                glGetShaderiv(shader_handle, GL_COMPILE_STATUS, &compile_status);

                GLint log_length = 0;
                glGetShaderiv(shader_handle, GL_INFO_LOG_LENGTH, &log_length);

                if (log_length > 1) {
                    info_log_.reserve(log_length);
                    glGetShaderInfoLog(shader_handle, log_length, &log_length, &info_log_[0]);
                }
            }

            shader(shader<S>&& other) noexcept : shader_handle(other.shader_handle), compile_status(other.compile_status), info_log_(std::move(other.info_log_)) {
                other.shader_handle = 0;
                other.compile_status = GL_FALSE;
            }

            ~shader() {
                glDeleteShader(shader_handle);
            }

            operator bool() const noexcept {
                return compile_status == GL_TRUE;
            }

            operator GLuint() const noexcept {
                return shader_handle;
            }

            const std::string& info_log() const noexcept {
                return info_log_;
            }
        private:
            GLuint shader_handle;

            int compile_status;
            std::string info_log_;
        };

        using vertex_shader = shader<shader_type::vertex>;
        using fragment_shader = shader<shader_type::fragment>;

        template<shader_type S>
        shader<S> shader_from_file(const std::string& path) {
            return shader<S>(static_cast<std::stringstream&>(std::stringstream() << std::ifstream(path).rdbuf()).str());
        }
    }
}
<|endoftext|>