<commit_before>// ========================================================================== //
// This file is part of DO-CV, a basic set of libraries in C++ for computer
// vision.
//
// Copyright (C) 2013 David Ok <david.ok8@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at http://mozilla.org/MPL/2.0/.
// ========================================================================== //

#ifndef DO_SARA_CORE_IMAGE_OPERATIONS_HPP
#define DO_SARA_CORE_IMAGE_OPERATIONS_HPP

#include <DO/Sara/Core/Image/Image.hpp>
#include <DO/Sara/Core/Pixel/SmartColorConversion.hpp>
#include <DO/Sara/Core/Pixel/PixelTraits.hpp>

namespace DO { namespace Sara {

  //! \ingroup Image
  //! @{

  //! @{
  //! \brief Find min and max values of the image.
  template <typename T, int N>
  inline void find_min_max(T& min, T& max, const Image<T, N>& src)
  {
    const auto *src_first = src.begin();
    const auto *src_last = src.end();
    min = *std::min_element(src_first, src_last);
    max = *std::max_element(src_first, src_last);
  }

  template <typename T, int N, typename ColorSpace>
  void find_min_max(Pixel<T, ColorSpace>& min,
                    Pixel<T, ColorSpace>& max,
                    const Image<Pixel<T, ColorSpace>, N>& src)
  {
    const auto *src_first = src.begin();
    const auto *src_last = src.end();

    min = *src_first;
    max = *src_first;

    for ( ; src_first != src_last; ++src_first)
    {
      min = min.cwiseMin(*src_first);
      max = max.cwiseMax(*src_first);
    }
  }
  //! @}

  //! @}

} /* namespace Sara */
} /* namespace DO */

// Generic color conversion of images.
namespace DO { namespace Sara {

  //! \ingroup Image
  //! @{

  //! \brief Convert color of image.
  template <typename T, typename U, int N>
  void convert(const Image<T, N>& src, Image<U, N>& dst)
  {
    if (dst.sizes() != src.sizes())
      dst.resize(src.sizes());

    const auto *src_first = src.data();
    const auto *src_last = src.end();

    U *dst_first = dst.data();

    for ( ; src_first != src_last; ++src_first, ++dst_first)
      smart_convert_color(*src_first, *dst_first);
  }

  //! @}

} /* namespace Sara */
} /* namespace DO */

// Image rescaling functions
namespace DO { namespace Sara {

  //! \ingroup Image
  //! @{

  //! @{
  //! \brief Rescale color values.
  template <typename T, int N>
  inline Image<T, N> color_rescale(const Image<T, N>& src,
                                   const T& a = PixelTraits<T>::min(),
                                   const T& b = PixelTraits<T>::max())
  {
    static_assert(
      !std::numeric_limits<T>::is_integer,
      "Color rescaling is not directly applicable on integer types");

    const auto *src_first = src.begin();
    const auto *src_last = src.end();

    auto min = *std::min_element(src_first, src_last);
    auto max = *std::max_element(src_first, src_last);

    if (min == max)
    {
      std::cout << "Warning: cannot rescale image! min == max" << std::endl;
      std::cout << "No rescaling will be performed" << std::endl;
      return src;
    }

    Image<T, N> dst{ src.sizes() };
    T *dst_first = dst.begin();
    for ( ; src_first != src_last; ++src_first, ++dst_first)
      *dst_first = a + (b-a)*(*src_first-min)/(max-min);

    return dst;
  }

  template <typename T, typename ColorSpace, int N>
  inline Image<Pixel<T, ColorSpace>, N> color_rescale(
    const Image<Pixel<T, ColorSpace>, N>& src,
    const Pixel<T, ColorSpace>& a = PixelTraits<Pixel<T, ColorSpace> >::min(),
    const Pixel<T, ColorSpace>& b = PixelTraits<Pixel<T, ColorSpace> >::max())
  {
    static_assert(
      !std::numeric_limits<T>::is_integer,
      "Color rescale is not directly applicable on integral types");

    Image<Pixel<T, ColorSpace>, N> dst{ src.sizes() };

    const auto *src_first = src.data();
    const auto *src_last = src_first + src.size();
    auto *dst_first  = dst.data();

    auto min = *src_first;
    auto max = *src_first;
    for ( ; src_first != src_last; ++src_first)
    {
      min = min.cwiseMin(*src_first);
      max = max.cwiseMax(*src_first);
    }

    if (min == max)
      throw std::runtime_error{ "Error: cannot rescale image! min == max" };

    for (src_first = src.data(); src_first != src_last;
      ++src_first, ++dst_first)
      *dst_first = a + (*src_first-min).cwiseProduct(b-a).
      cwiseQuotient(max-min);

    return dst;
  }

  template <typename T, int N>
  struct ColorRescale
  {
    typedef Image<T, N> ReturnType;

    ColorRescale(const Image<T, N>& src)
      : src_(src)
    {
    }

    ReturnType operator()() const
    {
      return color_rescale(src_);
    }

    const Image<T, N>& src_;
  };
  //! @}

  //! @}

} /* namespace Sara */
} /* namespace DO */

#endif /* DO_SARA_CORE_IMAGE_OPERATIONS_HPP */
<commit_msg>MAINT: don't throw if `min == max`.<commit_after>// ========================================================================== //
// This file is part of DO-CV, a basic set of libraries in C++ for computer
// vision.
//
// Copyright (C) 2013 David Ok <david.ok8@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at http://mozilla.org/MPL/2.0/.
// ========================================================================== //

#ifndef DO_SARA_CORE_IMAGE_OPERATIONS_HPP
#define DO_SARA_CORE_IMAGE_OPERATIONS_HPP

#include <DO/Sara/Core/Image/Image.hpp>
#include <DO/Sara/Core/Pixel/SmartColorConversion.hpp>
#include <DO/Sara/Core/Pixel/PixelTraits.hpp>

namespace DO { namespace Sara {

  //! \ingroup Image
  //! @{

  //! @{
  //! \brief Find min and max values of the image.
  template <typename T, int N>
  inline void find_min_max(T& min, T& max, const Image<T, N>& src)
  {
    const auto *src_first = src.begin();
    const auto *src_last = src.end();
    min = *std::min_element(src_first, src_last);
    max = *std::max_element(src_first, src_last);
  }

  template <typename T, int N, typename ColorSpace>
  void find_min_max(Pixel<T, ColorSpace>& min,
                    Pixel<T, ColorSpace>& max,
                    const Image<Pixel<T, ColorSpace>, N>& src)
  {
    const auto *src_first = src.begin();
    const auto *src_last = src.end();

    min = *src_first;
    max = *src_first;

    for ( ; src_first != src_last; ++src_first)
    {
      min = min.cwiseMin(*src_first);
      max = max.cwiseMax(*src_first);
    }
  }
  //! @}

  //! @}

} /* namespace Sara */
} /* namespace DO */

// Generic color conversion of images.
namespace DO { namespace Sara {

  //! \ingroup Image
  //! @{

  //! \brief Convert color of image.
  template <typename T, typename U, int N>
  void convert(const Image<T, N>& src, Image<U, N>& dst)
  {
    if (dst.sizes() != src.sizes())
      dst.resize(src.sizes());

    const auto *src_first = src.data();
    const auto *src_last = src.end();

    U *dst_first = dst.data();

    for ( ; src_first != src_last; ++src_first, ++dst_first)
      smart_convert_color(*src_first, *dst_first);
  }

  //! @}

} /* namespace Sara */
} /* namespace DO */

// Image rescaling functions
namespace DO { namespace Sara {

  //! \ingroup Image
  //! @{

  //! @{
  //! \brief Rescale color values.
  template <typename T, int N>
  inline Image<T, N> color_rescale(const Image<T, N>& src,
                                   const T& a = PixelTraits<T>::min(),
                                   const T& b = PixelTraits<T>::max())
  {
    static_assert(
      !std::numeric_limits<T>::is_integer,
      "Color rescaling is not directly applicable on integer types");

    const auto *src_first = src.begin();
    const auto *src_last = src.end();

    auto min = *std::min_element(src_first, src_last);
    auto max = *std::max_element(src_first, src_last);

    if (min == max)
    {
      std::cout << "Warning: cannot rescale image! min == max" << std::endl;
      std::cout << "No rescaling will be performed" << std::endl;
      return src;
    }

    Image<T, N> dst{ src.sizes() };
    T *dst_first = dst.begin();
    for ( ; src_first != src_last; ++src_first, ++dst_first)
      *dst_first = a + (b-a)*(*src_first-min)/(max-min);

    return dst;
  }

  template <typename T, typename ColorSpace, int N>
  inline Image<Pixel<T, ColorSpace>, N> color_rescale(
    const Image<Pixel<T, ColorSpace>, N>& src,
    const Pixel<T, ColorSpace>& a = PixelTraits<Pixel<T, ColorSpace> >::min(),
    const Pixel<T, ColorSpace>& b = PixelTraits<Pixel<T, ColorSpace> >::max())
  {
    static_assert(
      !std::numeric_limits<T>::is_integer,
      "Color rescale is not directly applicable on integral types");

    Image<Pixel<T, ColorSpace>, N> dst{ src.sizes() };

    const auto *src_first = src.data();
    const auto *src_last = src_first + src.size();
    auto *dst_first  = dst.data();

    auto min = *src_first;
    auto max = *src_first;
    for ( ; src_first != src_last; ++src_first)
    {
      min = min.cwiseMin(*src_first);
      max = max.cwiseMax(*src_first);
    }

    if (min == max)
    {
      std::cout << "Warning: cannot rescale image! min == max" << std::endl;
      std::cout << "No rescaling will be performed" << std::endl;
      return src;
    }

    for (src_first = src.data(); src_first != src_last;
      ++src_first, ++dst_first)
      *dst_first = a + (*src_first-min).cwiseProduct(b-a).
      cwiseQuotient(max-min);

    return dst;
  }

  template <typename T, int N>
  struct ColorRescale
  {
    typedef Image<T, N> ReturnType;

    ColorRescale(const Image<T, N>& src)
      : src_(src)
    {
    }

    ReturnType operator()() const
    {
      return color_rescale(src_);
    }

    const Image<T, N>& src_;
  };
  //! @}

  //! @}

} /* namespace Sara */
} /* namespace DO */

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


<commit_before>/**
 * @file
 * json.hxx
 *
 * @brief json structure to build json with application specific stats.
 */

#pragma once

#include <cmath>
#include <cstdio>
#include <ctime>
#include <time.h>
#include <vector>

// RapidJSON includes (required)
#include <rapidjson/document.h>
#include <rapidjson/filewritestream.h>
#include <rapidjson/prettywriter.h>

#include <gunrock/error.hxx>
#include <gunrock/util/gitsha1.hxx>

namespace gunrock {
namespace io {

/**
 * @brief json data structure to build output a json to stdout or a file.
 */
class json {
  std::string _time_str;
  std::string _application_name;

  // json filename and file (rw, open)
  std::string _filename;
  std::FILE* _file;

  // RapidJSON setup for writing json
  typedef rapidjson::StringBuffer buffer_t;
  typedef rapidjson::PrettyWriter<rapidjson::StringBuffer> writer_t;
  typedef rapidjson::Document document_t;
  typedef rapidjson::Value value_t;

  buffer_t* _stream;
  writer_t* _writer;
  document_t* _document;

 public:
  /**
   * @brief info default constructor
   */
  info()
      : _time_str(""),
        _application_name(""),
        _filename(""),
        _stream(nullptr),
        _writer(nullptr),
        _file(nullptr),
        _document(nullptr) {}

  info(std::string application, std::string filename)
      : _time_str(""),
        _application_name(application),
        _filename(filename),
        _stream(nullptr),
        _writer(nullptr),
        _file(nullptr),
        _document(nullptr) {
    init();
  }

  ~info() {
    _time_str = "";
    _application_name = "";
    _filename = "";

    delete _stream;
    _stream = nullptr;

    delete _writer;
    _writer = nullptr;

    delete _document;
    _document = nullptr;
  }

  /**
   * @brief Initialization process for info.
   *
   * @param[in] application_name application name.
   * @param[in] args Command line arguments.
   */
  void init_base(std::string application_name) {
    // To keep things uniform, convert application name to lower case
    std::transform(application_name.begin(), application_name.end(),
                   application_name.begin(), ::tolower);

    this->_application_name = application_name;

    // Get time (with milliseconds accuracy). We use time with ms as a filename
    // identifier to keep every run named differently. Milliseconds accuracy is
    // important because some runs may execute within a single second and will
    // overwrite each other as a single filename.
    time_t now = time(NULL);

    long ms;   // Milliseconds
    time_t s;  // Seconds
    struct timespec spec;

    clock_gettime(CLOCK_REALTIME, &spec);

    s = spec.tv_sec;
    ms = round(spec.tv_nsec / 1.0e6);  // Convert nanoseconds to milliseconds
    if (ms > 999) {
      ++s;
      ms = 0;
    }

    std::string time_s = std::string(ctime(&now));
    std::string time_ms = std::to_string(ms);

    this->_time_str = time_s;  // Used within json
    std::string time_str_filename = time_s.substr(0, time_s.size() - 5) +
                                    time_ms + ' ' +
                                    time_s.substr(time_s.length() - 5);
  }

  /**
   * @brief Initialization process for Info.
   */
  void init() {
    init_base(_application_name);
    _document = new document_t();
    _document->SetObject();

    // Use a StringBuffer to hold the file data. This requires we manually
    // fputs the data from the stream to a file, but it's unlikely we would
    // ever write incomplete files. With a FileWriteStream, rapidjson will
    // decide to start writing whenever the buffer we provide is full
    _stream = new buffer_t();
    _writer = new writer_t(*stream);

    // Write the initial copy of the file with an invalid json-integrity
    /*
     * @todo ... SetBaseInfo(_application_name, false);
     */

    // Traverse the document for writing events
    if (stream != NULL) {
      _document->Accept(*writer);
      assert(writer->IsComplete());
    }
    if (_filename != "") {
      _file = std::fopen(_filename.c_str(), "w");
      std::fputs(_stream->GetString(), _file);
      std::fclose(_file);
    }

    // We now start over with a new stream and writer. We can't reuse them.
    // We also reset the document and rewrite our initial data - this time
    // without the invalid time.
    delete _stream;
    delete _writer;

    _stream = new buffer_t();
    _writer = new writer_t(*_stream);

    _document->SetObject();
    /*
     * @todo do stuff...
     */
  }

  // Get values from the json document.
  // get <start>
  template <typename T>
  value_t get_val(const T& val) {
    return value_t(val);
  }

  value_t get_val(const std::string& str) {
    if (_document == NULL)
      return value_t();
    else {
      return value_t(str, _document->GetAllocator());
    }
  }

  value_t get_val(char* const str) {
    if (_document == NULL)
      return value_t();
    else {
      return value_t(str, _document->GetAllocator());
    }
  }
  // get <end>

  // Set values and type support.
  // set <start>
  template <typename T>
  void set_bool(std::string name, const T& val, value_t& json_object) {
    std::cerr << "Attempt to set_val with unknown type for key \"" << name
              << std::endl;
  }

  void set_bool(std::string name, const bool& val, value_t& json_object) {
    if (_document != NULL) {
      value_t key(name, _document->GetAllocator());
      json_object.AddMember(key, val, _document->GetAllocator());
    }
  }

  template <typename T>
  void set_int(std::string name, const T& val, value_t& json_object) {
    std::cerr << "Attempt to set_val with unknown type for key \"" << name
              << std::endl;
  }

  void set_int(std::string name, const int& val, value_t& json_object) {
    if (_document != NULL) {
      value_t key(name, _document->GetAllocator());
      json_object.AddMember(key, val, _document->GetAllocator());
    }
  }

  template <typename T>
  void set_uint(std::string name, const T& val, value_t& json_object) {
    std::cerr << "Attempt to set_val with unknown type for key \"" << name
              << std::endl;
  }

  void set_uint(std::string name,
                const unsigned int& val,
                value_t& json_object) {
    if (_document != NULL) {
      value_t key(name, _document->GetAllocator());
      json_object.AddMember(key, val, _document->GetAllocator());
    }
  }

  template <typename T>
  void set_int64(std::string name, const T& val, value_t& json_object) {
    std::cerr << "writing unknown type for key \"" << name << std::endl;
  }

  void set_int64(std::string name, const int64_t& val, value_t& json_object) {
    if (_document != NULL) {
      value_t key(name, _document->GetAllocator());
      json_object.AddMember(key, val, _document->GetAllocator());
    }
  }

  template <typename T>
  void set_uint64(std::string name, const T& val, value_t& json_object) {
    std::cerr << "writing unknown type for key \"" << name << std::endl;
  }

  void set_uint64(std::string name, const uint64_t& val, value_t& json_object) {
    if (_document != NULL) {
      value_t key(name, _document->GetAllocator());
      json_object.AddMember(key, val, _document->GetAllocator());
    }
  }

  template <typename T>
  void set_double(std::string name, const T& val, value_t& json_object) {
    std::cerr << "writing unknown type for key \"" << name << std::endl;
  }

  void set_double(std::string name, const float& val, value_t& json_object) {
    if (_document != NULL) {
      value_t key(name, _document->GetAllocator());

      // Doubles and floats have an edge case. INF and NAN are valid values for
      // a double, but JSON doesn't allow them in the official spec. Some json
      // formats still allow them. We have to choose a behavior here, so let's
      // output the value as a string
      if (std::isinf(val) || std::isnan(val)) {
        value_t null_val(rapidjson::kNullType);
        json_object.AddMember(key, null_val, _document->GetAllocator());
      } else {
        json_object.AddMember(key, val, _document->GetAllocator());
      }
    }
  }

  void set_double(std::string name, const double& val, value_t& json_object) {
    if (_document != NULL) {
      value_t key(name, _document->GetAllocator());

      if (std::isinf(val) || std::isnan(val)) {
        value_t null_val(rapidjson::kNullType);
        json_object.AddMember(key, null_val, _document->GetAllocator());
      } else {
        json_object.AddMember(key, val, _document->GetAllocator());
      }
    }
  }

  // Attach a key with name, "name" and value "val" to the JSON object
  // "json_object"
  template <typename T>
  void set_val(std::string name, const T& val, value_t& json_object) {
    if (_document == NULL)
      return;

    auto tidx = std::type_index(typeid(T));

    // TODO: Use constexpr if for this instead of the runtime check
    // Then we won't need the filler functions above for a generic
    // template parameter T
    if (tidx == std::type_index(typeid(bool)))
      set_bool(name, val, json_object);
    else if (tidx == std::type_index(typeid(char)) ||
             tidx == std::type_index(typeid(signed char)) ||
             tidx == std::type_index(typeid(short)) ||
             tidx == std::type_index(typeid(int)))
      set_int(name, val, json_object);
    else if (tidx == std::type_index(typeid(unsigned char)) ||
             tidx == std::type_index(typeid(unsigned short)) ||
             tidx == std::type_index(typeid(unsigned int)))
      set_uint(name, val, json_object);
    else if (tidx == std::type_index(typeid(long)) ||
             tidx == std::type_index(typeid(long long)))
      set_int64(name, val, json_object);
    else if (tidx == std::type_index(typeid(unsigned long)) ||
             tidx == std::type_index(typeid(unsigned long long)))
      set_uint64(name, val, json_object);
    else if (tidx == std::type_index(typeid(float)) ||
             tidx == std::type_index(typeid(double)) ||
             tidx == std::type_index(typeid(long double)))
      set_double(name, val, json_object);
    else {
      std::ostringstream ostr;
      ostr << val;
      std::string str = ostr.str();

      value_t key(name, _document->GetAllocator());
      json_object.AddMember(key, str, _document->GetAllocator());
    }
  }

  template <typename T>
  void set_val(std::string name,
               const std::vector<T>& vec,
               value_t& json_object) {
    /*
     * @todo update parameters to support "ALWAYS_ARRAY" type currently using a
     * hack to make sure tag is always an array in JSON. This is also required
     * for fields such as srcs, process-times, etc.
     */
    if (_document == NULL)
      return;

    if (vec.size() == 1 && (name.compare("tag") != 0)) {
      set_val(name, vec.front(), json_object);
    } else {
      value_t arr(rapidjson::kArrayType);
      for (const T& i : vec) {
        value_t val = get_val(i);

        arr.PushBack(val, _document->GetAllocator());
      }

      value_t key(name, _document->GetAllocator());
      json_object.AddMember(key, arr, _document->GetAllocator());
    }
  }

  template <typename T>
  void set_val(std::string name,
               const std::vector<std::pair<T, T>>& vec,
               value_t& json_object) {
    if (_document == NULL)
      return;

    value_t key(name, _document->GetAllocator());

    value_t child_object(rapidjson::kObjectType);
    for (auto it = vec.begin(); it != vec.end(); ++it) {
      set_val(it->first.c_str(), it->second, child_object);
    }

    json_object.AddMember(key, child_object, _document->GetAllocator());
  }

  template <typename T>
  void set_val(std::string name, const T& val) {
    if (_document == NULL)
      return;

    set_val(name, val, *_document);
  }
  // set <end>

};  // class json

}  // namespace io
}  // namespace gunrock<commit_msg>No need for this json.<commit_after><|endoftext|>


<commit_before>//
//  inpal_algorithm.hpp
//  Inverse Palindrome Library
//
//  Created by Bryan Triana on 7/22/16.
//  Copyright © 2016 Inverse Palindrome. All rights reserved.
//

#ifndef inpal_algorithm_hpp
#define inpal_algorithm_hpp

#include <cstdlib>
#include <string>

namespace inpal
{
   namespace algorithm
    {
        std::size_t modulo(std::size_t a, std::size_t b, std::size_t c);
        std::size_t mulmod(std::size_t a, std::size_t b, std::size_t c);
        bool pal_test(std::size_t num);
    }
}

#endif /* inpal_algorithm_hpp */

<commit_msg>implemented pollard rho for prime factorization<commit_after>//
//  inpal_algorithm.hpp
//  Inverse Palindrome Library
//
//  Created by Bryan Triana on 7/22/16.
//  Copyright © 2016 Inverse Palindrome. All rights reserved.
//

#ifndef inpal_algorithm_hpp
#define inpal_algorithm_hpp

#include <cstdlib>
#include <string>
#include <vector>

namespace inpal
{
   namespace algorithm
    {
        std::size_t gcd(std::size_t a, std::size_t b);
        std::size_t modulo(std::size_t a, std::size_t b, std::size_t c);
        std::size_t mulmod(std::size_t a, std::size_t b, std::size_t c);
        std::size_t pollard_rho(std::size_t num);
        std::vector<std::size_t> trial_division(std::size_t num);
        bool pal_test(std::size_t num);

    }
}

#endif /* inpal_algorithm_hpp */

<|endoftext|>


<commit_before>/*
	Copyright (C) 2004-2005 Cory Nelson

	This software is provided 'as-is', without any express or implied
	warranty.  In no event will the authors be held liable for any damages
	arising from the use of this software.

	Permission is granted to anyone to use this software for any purpose,
	including commercial applications, and to alter it and redistribute it
	freely, subject to the following restrictions:

	1. The origin of this software must not be misrepresented; you must not
		claim that you wrote the original software. If you use this software
		in a product, an acknowledgment in the product documentation would be
		appreciated but is not required.
	2. Altered source versions must be plainly marked as such, and must not be
		misrepresented as being the original software.
	3. This notice may not be removed or altered from any source distribution.
*/

// namespaces added by Arvid Norberg

#ifndef __UTF8_H__
#define __UTF8_H__

#include <string>
#include <iterator>
#include <stdexcept>

namespace libtorrent {
namespace detail {

template<typename InputIterator>
wchar_t decode_utf8_mb(InputIterator &iter, InputIterator last)
{
	if(iter==last) throw std::runtime_error("incomplete UTF-8 sequence");
	if(((*iter)&0xC0)!=0x80) throw std::runtime_error("invalid UTF-8 sequence");

	return (wchar_t)((*iter++)&0x3F);
}

template<typename InputIterator>
wchar_t decode_utf8(InputIterator &iter, InputIterator last)
{
	wchar_t ret;

	if(((*iter)&0x80) == 0) {
		ret=*iter++;
	}
	else if(((*iter)&0x20) == 0) {
		ret=(
			(((wchar_t)((*iter++)&0x1F)) << 6) |
			decode_utf8_mb(iter, last)
		);
	}
	else if(((*iter)&0x10) == 0) {
		ret=(
			(((wchar_t)((*iter++)&0x0F)) << 12) |
			(decode_utf8_mb(iter, last) << 6) |
			decode_utf8_mb(iter, last)
		);
	}
	else throw std::runtime_error("UTF-8 not convertable to UTF-16");

	return ret;
}

template<typename InputIterator, typename OutputIterator>
OutputIterator utf8_wchar(InputIterator first, InputIterator last, OutputIterator dest)
{
	for(; first!=last; ++dest)
		*dest=decode_utf8(first, last);
	return dest;
}

template<typename InputIterator, typename OutputIterator>
void encode_wchar(InputIterator iter, OutputIterator &dest)
{
	if(*iter <= 0x007F)
	{
		*dest=(char)*iter;
		++dest;
	}
	else if(*iter <= 0x07FF)
	{
		*dest = (char)(
			0xC0 |
			((*iter & 0x07C0) >> 6)
		);
		++dest;

		*dest = (char)(
			0x80 |
			(*iter & 0x003F)
		);
		++dest;
	}
	else if(*iter <= 0xFFFF)
	{
		*dest = (char)(
			0xE0 |
			((*iter & 0xF000) >> 12)
		);
		++dest;

		*dest = (char)(
			0x80 |
			((*iter & 0x0FC0) >> 6)
		);
		++dest;

		*dest = (char)(
			0x80 |
			(*iter & 0x003F)
		);
		++dest;
	}
}

template<typename InputIterator, typename OutputIterator>
OutputIterator wchar_utf8(InputIterator first, InputIterator last, OutputIterator dest)
{
	for(; first!=last; ++first)
		encode_wchar(first, dest);
	return dest;
}

}

void utf8_wchar(const std::string &utf8, std::wstring &wide)
{
	wide.clear();
	detail::utf8_wchar(utf8.begin(), utf8.end(), std::insert_iterator<std::wstring>(wide, wide.end()));
}

std::wstring utf8_wchar(const std::string &str)
{
	std::wstring ret;
	utf8_wchar(str, ret);
	return ret;
}

void wchar_utf8(const std::wstring &wide, std::string &utf8)
{
	utf8.clear();
	detail::wchar_utf8(wide.begin(), wide.end(), std::insert_iterator<std::string>(utf8, utf8.end()));
}

std::string wchar_utf8(const std::wstring &str)
{
	std::string ret;
	wchar_utf8(str, ret);
	return ret;
}

}

#endif
<commit_msg>fixed non-inlined functions<commit_after>/*
	Copyright (C) 2004-2005 Cory Nelson

	This software is provided 'as-is', without any express or implied
	warranty.  In no event will the authors be held liable for any damages
	arising from the use of this software.

	Permission is granted to anyone to use this software for any purpose,
	including commercial applications, and to alter it and redistribute it
	freely, subject to the following restrictions:

	1. The origin of this software must not be misrepresented; you must not
		claim that you wrote the original software. If you use this software
		in a product, an acknowledgment in the product documentation would be
		appreciated but is not required.
	2. Altered source versions must be plainly marked as such, and must not be
		misrepresented as being the original software.
	3. This notice may not be removed or altered from any source distribution.
*/

// namespaces added by Arvid Norberg

#ifndef __UTF8_H__
#define __UTF8_H__

#include <string>
#include <iterator>
#include <stdexcept>

namespace libtorrent {
namespace detail {

template<typename InputIterator>
wchar_t decode_utf8_mb(InputIterator &iter, InputIterator last)
{
	if(iter==last) throw std::runtime_error("incomplete UTF-8 sequence");
	if(((*iter)&0xC0)!=0x80) throw std::runtime_error("invalid UTF-8 sequence");

	return (wchar_t)((*iter++)&0x3F);
}

template<typename InputIterator>
wchar_t decode_utf8(InputIterator &iter, InputIterator last)
{
	wchar_t ret;

	if(((*iter)&0x80) == 0) {
		ret=*iter++;
	}
	else if(((*iter)&0x20) == 0) {
		ret=(
			(((wchar_t)((*iter++)&0x1F)) << 6) |
			decode_utf8_mb(iter, last)
		);
	}
	else if(((*iter)&0x10) == 0) {
		ret=(
			(((wchar_t)((*iter++)&0x0F)) << 12) |
			(decode_utf8_mb(iter, last) << 6) |
			decode_utf8_mb(iter, last)
		);
	}
	else throw std::runtime_error("UTF-8 not convertable to UTF-16");

	return ret;
}

template<typename InputIterator, typename OutputIterator>
OutputIterator utf8_wchar(InputIterator first, InputIterator last, OutputIterator dest)
{
	for(; first!=last; ++dest)
		*dest=decode_utf8(first, last);
	return dest;
}

template<typename InputIterator, typename OutputIterator>
void encode_wchar(InputIterator iter, OutputIterator &dest)
{
	if(*iter <= 0x007F)
	{
		*dest=(char)*iter;
		++dest;
	}
	else if(*iter <= 0x07FF)
	{
		*dest = (char)(
			0xC0 |
			((*iter & 0x07C0) >> 6)
		);
		++dest;

		*dest = (char)(
			0x80 |
			(*iter & 0x003F)
		);
		++dest;
	}
	else if(*iter <= 0xFFFF)
	{
		*dest = (char)(
			0xE0 |
			((*iter & 0xF000) >> 12)
		);
		++dest;

		*dest = (char)(
			0x80 |
			((*iter & 0x0FC0) >> 6)
		);
		++dest;

		*dest = (char)(
			0x80 |
			(*iter & 0x003F)
		);
		++dest;
	}
}

template<typename InputIterator, typename OutputIterator>
OutputIterator wchar_utf8(InputIterator first, InputIterator last, OutputIterator dest)
{
	for(; first!=last; ++first)
		encode_wchar(first, dest);
	return dest;
}

}

inline void utf8_wchar(const std::string &utf8, std::wstring &wide)
{
	wide.clear();
	detail::utf8_wchar(utf8.begin(), utf8.end(), std::insert_iterator<std::wstring>(wide, wide.end()));
}

inline std::wstring utf8_wchar(const std::string &str)
{
	std::wstring ret;
	utf8_wchar(str, ret);
	return ret;
}

inline void wchar_utf8(const std::wstring &wide, std::string &utf8)
{
	utf8.clear();
	detail::wchar_utf8(wide.begin(), wide.end(), std::insert_iterator<std::string>(utf8, utf8.end()));
}

inline std::string wchar_utf8(const std::wstring &str)
{
	std::string ret;
	wchar_utf8(str, ret);
	return ret;
}

}

#endif
<|endoftext|>


<commit_before>using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
using namespace System::Runtime::InteropServices;
using namespace System::Security::Permissions;

//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly:AssemblyTitleAttribute(L"BackgroundFinalizer")];
[assembly:AssemblyDescriptionAttribute(L"Finalizers that run in the application background")];
[assembly:AssemblyConfigurationAttribute(L"")];
[assembly:AssemblyCompanyAttribute(L"")];
[assembly:AssemblyProductAttribute(L"BackgroundFinalizer")];
[assembly:AssemblyCopyrightAttribute(L"Copyright (c) 2015 Shea Levy")];
[assembly:AssemblyTrademarkAttribute(L"")];
[assembly:AssemblyCultureAttribute(L"")];

//
// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version
//      Build Number
//      Revision
//
// You can specify all the value or you can default the Revision and Build Numbers
// by using the '*' as shown below:

[assembly:AssemblyVersionAttribute("1.0.*")];

[assembly:ComVisible(false)];

[assembly:CLSCompliantAttribute(true)];<commit_msg>Update description<commit_after>using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
using namespace System::Runtime::InteropServices;
using namespace System::Security::Permissions;

//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly:AssemblyTitleAttribute(L"BackgroundFinalizer")];
[assembly:AssemblyDescriptionAttribute(L"Defines a class that can be used to run finalizers out of line with the garbage collector")];
[assembly:AssemblyConfigurationAttribute(L"")];
[assembly:AssemblyCompanyAttribute(L"")];
[assembly:AssemblyProductAttribute(L"BackgroundFinalizer")];
[assembly:AssemblyCopyrightAttribute(L"Copyright (c) 2015 Shea Levy")];
[assembly:AssemblyTrademarkAttribute(L"")];
[assembly:AssemblyCultureAttribute(L"")];

//
// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version
//      Build Number
//      Revision
//
// You can specify all the value or you can default the Revision and Build Numbers
// by using the '*' as shown below:

[assembly:AssemblyVersionAttribute("1.0.*")];

[assembly:ComVisible(false)];

[assembly:CLSCompliantAttribute(true)];<|endoftext|>


<commit_before>/*

Copyright (C) 2014-2018 Nicolas Brown

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

*/

#pragma once

#include "../assembly.hpp"
#include "../virtualmachine.hpp"

using namespace loris;

namespace DSMathLib
{

Value NativeMod(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(fmod(vm->GetArg(0).AsNumber(),vm->GetArg(1).AsNumber() ));
}

Value NativeFloor(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(floor(vm->GetArg(0).AsNumber()));
}

Value NativeCeil(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(ceil(vm->GetArg(0).AsNumber()));
}

Value NativeSin(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(sin(vm->GetArg(0).AsNumber()));
}

Value NativeCos(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(cos(vm->GetArg(0).AsNumber()));
}

Value NativeTan(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(tan(vm->GetArg(0).AsNumber()));
}

Value NativeAsin(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(asin(vm->GetArg(0).AsNumber()));
}

Value NativeAcos(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(acos(vm->GetArg(0).AsNumber()));
}

Value NativeAtan(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(atan(vm->GetArg(0).AsNumber()));
}

Value NativeExp10(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(exp(vm->GetArg(0).AsNumber()*log(10)));
}

Value NativeExp2(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(exp(vm->GetArg(0).AsNumber()*log(10)));
}

Value NativeLog10(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(log(vm->GetArg(0).AsNumber())/log(10));
}

Value NativeLog2(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(log(vm->GetArg(0).AsNumber())/log(2));
}

Value NativePow(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(pow(vm->GetArg(0).AsNumber(),vm->GetArg(1).AsNumber() ));
}

Value NativeLog(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(log(vm->GetArg(0).AsNumber()));
}

Value NativeExp(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(exp(vm->GetArg(0).AsNumber()));
}

void Install(Assembly* lib)
{
	lib->AddFunction("mod",NativeMod);
	lib->AddFunction("floor",NativeFloor);
	lib->AddFunction("ceil",NativeCeil);
	lib->AddFunction("sin",NativeSin);
	lib->AddFunction("cos",NativeCos);
	lib->AddFunction("tan", NativeTan);
	lib->AddFunction("atan2", loris::Def(atan2f));
	lib->AddFunction("sqrt",loris::Def(sqrtf));
	lib->AddFunction("asin",NativeAsin);
	lib->AddFunction("acos",NativeAcos);
	lib->AddFunction("atan",NativeAtan);
	lib->AddFunction("log10",NativeLog10);
	lib->AddFunction("log2",NativeLog2);
	lib->AddFunction("exp10",NativeExp10);
	lib->AddFunction("exp2",NativeExp2);
	lib->AddFunction("pow",NativePow);
	lib->AddFunction("exp",NativeExp);
	lib->AddFunction("log",NativeLog);
}

}<commit_msg>Added radians and degrees functions to math lib<commit_after>/*

Copyright (C) 2014-2018 Nicolas Brown

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

*/

#pragma once

#include "../assembly.hpp"
#include "../virtualmachine.hpp"

using namespace loris;

namespace DSMathLib
{

Value NativeMod(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(fmod(vm->GetArg(0).AsNumber(),vm->GetArg(1).AsNumber() ));
}

Value NativeFloor(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(floor(vm->GetArg(0).AsNumber()));
}

Value NativeCeil(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(ceil(vm->GetArg(0).AsNumber()));
}

Value NativeSin(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(sin(vm->GetArg(0).AsNumber()));
}

Value NativeCos(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(cos(vm->GetArg(0).AsNumber()));
}

Value NativeTan(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(tan(vm->GetArg(0).AsNumber()));
}

Value NativeAsin(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(asin(vm->GetArg(0).AsNumber()));
}

Value NativeAcos(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(acos(vm->GetArg(0).AsNumber()));
}

Value NativeAtan(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(atan(vm->GetArg(0).AsNumber()));
}

Value NativeExp10(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(exp(vm->GetArg(0).AsNumber()*log(10)));
}

Value NativeExp2(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(exp(vm->GetArg(0).AsNumber()*log(10)));
}

Value NativeLog10(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(log(vm->GetArg(0).AsNumber())/log(10));
}

Value NativeLog2(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(log(vm->GetArg(0).AsNumber())/log(2));
}

Value NativePow(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(pow(vm->GetArg(0).AsNumber(),vm->GetArg(1).AsNumber() ));
}

Value NativeLog(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(log(vm->GetArg(0).AsNumber()));
}

Value NativeExp(VirtualMachine* vm,Object* self)
{
	return Value::CreateNumber(exp(vm->GetArg(0).AsNumber()));
}

// Converts radians to degrees.
float radiansf(float angleDegrees)
{
	return (angleDegrees * M_PI / 180.0);
}

// Converts radians to degrees.
float degreesf(float angleRadians)
{
	return (angleRadians * 180.0 / M_PI);
}

void Install(Assembly* lib)
{
	lib->AddFunction("mod",NativeMod);
	lib->AddFunction("floor",NativeFloor);
	lib->AddFunction("ceil",NativeCeil);
	lib->AddFunction("sin",NativeSin);
	lib->AddFunction("cos",NativeCos);
	lib->AddFunction("tan", NativeTan);
	lib->AddFunction("atan2", loris::Def(atan2f));
	lib->AddFunction("sqrt",loris::Def(sqrtf));
	lib->AddFunction("asin",NativeAsin);
	lib->AddFunction("acos",NativeAcos);
	lib->AddFunction("atan",NativeAtan);
	lib->AddFunction("log10",NativeLog10);
	lib->AddFunction("log2",NativeLog2);
	lib->AddFunction("exp10",NativeExp10);
	lib->AddFunction("exp2",NativeExp2);
	lib->AddFunction("pow",NativePow);
	lib->AddFunction("exp",NativeExp);
	lib->AddFunction("log",NativeLog);
	lib->AddFunction("radians", loris::Def(radiansf));
	lib->AddFunction("degrees", loris::Def(degreesf));
}

}<|endoftext|>


<commit_before>// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#include <Nazara/Graphics/BasicMaterial.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
#include <Nazara/Graphics/UberShader.hpp>
#include <Nazara/Renderer/Renderer.hpp>
#include <Nazara/Shader/Ast/AstSerializer.hpp>
#include <Nazara/Utility/BufferMapper.hpp>
#include <Nazara/Utility/FieldOffsets.hpp>
#include <Nazara/Utility/MaterialData.hpp>
#include <cassert>
#include <Nazara/Graphics/Debug.hpp>

namespace Nz
{
	namespace
	{
		const UInt8 r_fragmentShader[] = {
			#include <Nazara/Graphics/Resources/Shaders/basicmaterial.frag.shader.h>
		};

		const UInt8 r_vertexShader[] = {
			#include <Nazara/Graphics/Resources/Shaders/basicmaterial.vert.shader.h>
		};
	}

	BasicMaterial::BasicMaterial(Material& material) :
	m_material(material)
	{
		// Most common case: don't fetch texture indexes as a little optimization
		const std::shared_ptr<const MaterialSettings>& materialSettings = material.GetSettings();
		if (materialSettings == s_materialSettings)
		{
			m_conditionIndexes = s_conditionIndexes;
			m_textureIndexes = s_textureIndexes;
			m_uniformBlockIndex = s_uniformBlockIndex;
			m_uniformOffsets = s_uniformOffsets;
		}
		else
		{
			m_conditionIndexes.alphaTest = materialSettings->GetConditionIndex("AlphaTest");
			m_conditionIndexes.hasAlphaMap = materialSettings->GetConditionIndex("HasAlphaMap");
			m_conditionIndexes.hasDiffuseMap = materialSettings->GetConditionIndex("HasDiffuseMap");

			m_textureIndexes.alpha = materialSettings->GetTextureIndex("Alpha");
			m_textureIndexes.diffuse = materialSettings->GetTextureIndex("Diffuse");

			m_uniformBlockIndex = materialSettings->GetUniformBlockIndex("BasicSettings");

			m_uniformOffsets.alphaThreshold = materialSettings->GetUniformBlockVariableOffset(m_uniformBlockIndex, "AlphaThreshold");
			m_uniformOffsets.diffuseColor = materialSettings->GetUniformBlockVariableOffset(m_uniformBlockIndex, "DiffuseColor");
		}
	}

	float BasicMaterial::GetAlphaTestThreshold() const
	{
		NazaraAssert(HasAlphaTestThreshold(), "Material has no alpha threshold uniform");

		const std::vector<UInt8>& bufferData = m_material.GetUniformBufferConstData(m_uniformBlockIndex);

		return AccessByOffset<const float&>(bufferData.data(), m_uniformOffsets.alphaThreshold);
	}

	Color BasicMaterial::GetDiffuseColor() const
	{
		NazaraAssert(HasDiffuseColor(), "Material has no diffuse color uniform");

		const std::vector<UInt8>& bufferData = m_material.GetUniformBufferConstData(m_uniformBlockIndex);

		const float* colorPtr = AccessByOffset<const float*>(bufferData.data(), m_uniformOffsets.diffuseColor);
		return Color(colorPtr[0] * 255, colorPtr[1] * 255, colorPtr[2] * 255, colorPtr[3] * 255); //< TODO: Make color able to use float
	}

	void BasicMaterial::SetAlphaTestThreshold(float alphaThreshold)
	{
		NazaraAssert(HasAlphaTestThreshold(), "Material has no alpha threshold uniform");

		std::vector<UInt8>& bufferData = m_material.GetUniformBufferData(m_uniformBlockIndex);
		AccessByOffset<float&>(bufferData.data(), m_uniformOffsets.alphaThreshold) = alphaThreshold;
	}

	void BasicMaterial::SetDiffuseColor(const Color& diffuse)
	{
		NazaraAssert(HasDiffuseColor(), "Material has no diffuse color uniform");

		std::vector<UInt8>& bufferData = m_material.GetUniformBufferData(m_uniformBlockIndex);

		float* colorPtr = AccessByOffset<float*>(bufferData.data(), m_uniformOffsets.diffuseColor);
		colorPtr[0] = diffuse.r / 255.f;
		colorPtr[1] = diffuse.g / 255.f;
		colorPtr[2] = diffuse.b / 255.f;
		colorPtr[3] = diffuse.a / 255.f;
	}

	bool BasicMaterial::Initialize()
	{
		FieldOffsets fieldOffsets(StructLayout_Std140);

		s_uniformOffsets.alphaThreshold = fieldOffsets.AddField(StructFieldType_Float1);
		s_uniformOffsets.diffuseColor = fieldOffsets.AddField(StructFieldType_Float4);
		s_uniformOffsets.totalSize = fieldOffsets.GetSize();

		MaterialSettings::Builder settings;
		settings.predefinedBinding.fill(MaterialSettings::InvalidIndex);

		std::vector<MaterialSettings::UniformVariable> variables;
		variables.assign({
			{
				"AlphaThreshold",
				s_uniformOffsets.alphaThreshold
			},
			{
				"DiffuseColor",
				s_uniformOffsets.diffuseColor
			}
		});

		static_assert(sizeof(Vector4f) == 4 * sizeof(float), "Vector4f is expected to be exactly 4 floats wide");

		std::vector<UInt8> defaultValues(fieldOffsets.GetSize());
		AccessByOffset<Vector4f&>(defaultValues.data(), s_uniformOffsets.diffuseColor) = Vector4f(1.f, 1.f, 1.f, 1.f);
		AccessByOffset<float&>(defaultValues.data(), s_uniformOffsets.alphaThreshold) = 0.2f;

		s_textureIndexes.alpha = settings.textures.size();
		settings.textures.push_back({
			"MaterialAlphaMap",
			"Alpha",
			ImageType_2D
		});

		s_textureIndexes.diffuse = settings.textures.size();
		settings.textures.push_back({
			"MaterialDiffuseMap",
			"Diffuse",
			ImageType_2D
		});

		settings.predefinedBinding[UnderlyingCast(PredefinedShaderBinding::TexOverlay)] = settings.textures.size();
		settings.textures.push_back({
			"TextureOverlay",
			"Overlay",
			ImageType_2D
		});

		s_uniformBlockIndex = settings.uniformBlocks.size();
		settings.uniformBlocks.assign({
			{
				fieldOffsets.GetSize(),
				"BasicSettings",
				"MaterialBasicSettings",
				std::move(variables),
				std::move(defaultValues)
			}
		});

		settings.predefinedBinding[UnderlyingCast(PredefinedShaderBinding::UboInstanceData)] = settings.textures.size() + settings.uniformBlocks.size() + settings.sharedUniformBlocks.size();
		settings.sharedUniformBlocks.push_back(PredefinedInstanceData::GetUniformBlock());

		settings.predefinedBinding[UnderlyingCast(PredefinedShaderBinding::UboViewerData)] = settings.textures.size() + settings.uniformBlocks.size() + settings.sharedUniformBlocks.size();
		settings.sharedUniformBlocks.push_back(PredefinedViewerData::GetUniformBlock());

		// Shaders
		auto& fragmentShader = settings.shaders[UnderlyingCast(ShaderStageType::Fragment)];
		auto& vertexShader = settings.shaders[UnderlyingCast(ShaderStageType::Vertex)];

		fragmentShader = std::make_shared<UberShader>(ShaderStageType::Fragment, ShaderAst::UnserializeShader(r_fragmentShader, sizeof(r_fragmentShader)));
		vertexShader = std::make_shared<UberShader>(ShaderStageType::Vertex, ShaderAst::UnserializeShader(r_vertexShader, sizeof(r_vertexShader)));

		// Conditions

		// HasDiffuseMap
		{
			std::array<UInt64, ShaderStageTypeCount> shaderConditions;
			shaderConditions.fill(0);
			shaderConditions[UnderlyingCast(ShaderStageType::Fragment)] = fragmentShader->GetConditionFlagByName("HAS_DIFFUSE_TEXTURE");

			s_conditionIndexes.hasDiffuseMap = settings.conditions.size();
			settings.conditions.push_back({
				"HasDiffuseMap",
				shaderConditions
			});
		}

		// HasAlphaMap
		{
			std::array<UInt64, ShaderStageTypeCount> shaderConditions;
			shaderConditions.fill(0);
			shaderConditions[UnderlyingCast(ShaderStageType::Fragment)] = fragmentShader->GetConditionFlagByName("HAS_ALPHA_TEXTURE");

			s_conditionIndexes.hasAlphaMap = settings.conditions.size();
			settings.conditions.push_back({
				"HasAlphaMap",
				shaderConditions
			});
		}

		// AlphaTest
		{
			std::array<UInt64, ShaderStageTypeCount> shaderConditions;
			shaderConditions.fill(0);
			shaderConditions[UnderlyingCast(ShaderStageType::Fragment)] = fragmentShader->GetConditionFlagByName("ALPHA_TEST");

			s_conditionIndexes.alphaTest = settings.conditions.size();
			settings.conditions.push_back({
				"AlphaTest",
				shaderConditions
			});
		}

		s_materialSettings = std::make_shared<MaterialSettings>(std::move(settings));

		return true;
	}

	void BasicMaterial::Uninitialize()
	{
		s_materialSettings.reset();
	}

	std::shared_ptr<MaterialSettings> BasicMaterial::s_materialSettings;
	std::size_t BasicMaterial::s_uniformBlockIndex;
	BasicMaterial::ConditionIndexes BasicMaterial::s_conditionIndexes;
	BasicMaterial::TextureIndexes BasicMaterial::s_textureIndexes;
	BasicMaterial::UniformOffsets BasicMaterial::s_uniformOffsets;
}
<commit_msg>Fix Graphics module compilation<commit_after>// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#include <Nazara/Graphics/BasicMaterial.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
#include <Nazara/Graphics/UberShader.hpp>
#include <Nazara/Renderer/Renderer.hpp>
#include <Nazara/Shader/Ast/AstSerializer.hpp>
#include <Nazara/Utility/BufferMapper.hpp>
#include <Nazara/Utility/FieldOffsets.hpp>
#include <Nazara/Utility/MaterialData.hpp>
#include <cassert>
#include <Nazara/Graphics/Debug.hpp>

namespace Nz
{
	namespace
	{
		const UInt8 r_fragmentShader[] = {
			#include <Nazara/Graphics/Resources/Shaders/basicmaterial.frag.shader.h>
		};

		const UInt8 r_vertexShader[] = {
			#include <Nazara/Graphics/Resources/Shaders/basicmaterial.vert.shader.h>
		};
	}

	BasicMaterial::BasicMaterial(Material& material) :
	m_material(material)
	{
		// Most common case: don't fetch texture indexes as a little optimization
		const std::shared_ptr<const MaterialSettings>& materialSettings = material.GetSettings();
		if (materialSettings == s_materialSettings)
		{
			m_conditionIndexes = s_conditionIndexes;
			m_textureIndexes = s_textureIndexes;
			m_uniformBlockIndex = s_uniformBlockIndex;
			m_uniformOffsets = s_uniformOffsets;
		}
		else
		{
			m_conditionIndexes.alphaTest = materialSettings->GetConditionIndex("AlphaTest");
			m_conditionIndexes.hasAlphaMap = materialSettings->GetConditionIndex("HasAlphaMap");
			m_conditionIndexes.hasDiffuseMap = materialSettings->GetConditionIndex("HasDiffuseMap");

			m_textureIndexes.alpha = materialSettings->GetTextureIndex("Alpha");
			m_textureIndexes.diffuse = materialSettings->GetTextureIndex("Diffuse");

			m_uniformBlockIndex = materialSettings->GetUniformBlockIndex("BasicSettings");

			m_uniformOffsets.alphaThreshold = materialSettings->GetUniformBlockVariableOffset(m_uniformBlockIndex, "AlphaThreshold");
			m_uniformOffsets.diffuseColor = materialSettings->GetUniformBlockVariableOffset(m_uniformBlockIndex, "DiffuseColor");
		}
	}

	float BasicMaterial::GetAlphaTestThreshold() const
	{
		NazaraAssert(HasAlphaTestThreshold(), "Material has no alpha threshold uniform");

		const std::vector<UInt8>& bufferData = m_material.GetUniformBufferConstData(m_uniformBlockIndex);

		return AccessByOffset<const float&>(bufferData.data(), m_uniformOffsets.alphaThreshold);
	}

	Color BasicMaterial::GetDiffuseColor() const
	{
		NazaraAssert(HasDiffuseColor(), "Material has no diffuse color uniform");

		const std::vector<UInt8>& bufferData = m_material.GetUniformBufferConstData(m_uniformBlockIndex);

		const float* colorPtr = AccessByOffset<const float*>(bufferData.data(), m_uniformOffsets.diffuseColor);
		return Color(colorPtr[0] * 255, colorPtr[1] * 255, colorPtr[2] * 255, colorPtr[3] * 255); //< TODO: Make color able to use float
	}

	void BasicMaterial::SetAlphaTestThreshold(float alphaThreshold)
	{
		NazaraAssert(HasAlphaTestThreshold(), "Material has no alpha threshold uniform");

		std::vector<UInt8>& bufferData = m_material.GetUniformBufferData(m_uniformBlockIndex);
		AccessByOffset<float&>(bufferData.data(), m_uniformOffsets.alphaThreshold) = alphaThreshold;
	}

	void BasicMaterial::SetDiffuseColor(const Color& diffuse)
	{
		NazaraAssert(HasDiffuseColor(), "Material has no diffuse color uniform");

		std::vector<UInt8>& bufferData = m_material.GetUniformBufferData(m_uniformBlockIndex);

		float* colorPtr = AccessByOffset<float*>(bufferData.data(), m_uniformOffsets.diffuseColor);
		colorPtr[0] = diffuse.r / 255.f;
		colorPtr[1] = diffuse.g / 255.f;
		colorPtr[2] = diffuse.b / 255.f;
		colorPtr[3] = diffuse.a / 255.f;
	}

	bool BasicMaterial::Initialize()
	{
		FieldOffsets fieldOffsets(StructLayout_Std140);

		s_uniformOffsets.alphaThreshold = fieldOffsets.AddField(StructFieldType_Float1);
		s_uniformOffsets.diffuseColor = fieldOffsets.AddField(StructFieldType_Float4);
		s_uniformOffsets.totalSize = fieldOffsets.GetSize();

		MaterialSettings::Builder settings;
		settings.predefinedBinding.fill(MaterialSettings::InvalidIndex);

		std::vector<MaterialSettings::UniformVariable> variables;
		variables.assign({
			{
				"AlphaThreshold",
				s_uniformOffsets.alphaThreshold
			},
			{
				"DiffuseColor",
				s_uniformOffsets.diffuseColor
			}
		});

		static_assert(sizeof(Vector4f) == 4 * sizeof(float), "Vector4f is expected to be exactly 4 floats wide");

		std::vector<UInt8> defaultValues(fieldOffsets.GetSize());
		AccessByOffset<Vector4f&>(defaultValues.data(), s_uniformOffsets.diffuseColor) = Vector4f(1.f, 1.f, 1.f, 1.f);
		AccessByOffset<float&>(defaultValues.data(), s_uniformOffsets.alphaThreshold) = 0.2f;

		s_textureIndexes.alpha = settings.textures.size();
		settings.textures.push_back({
			"MaterialAlphaMap",
			"Alpha",
			ImageType_2D
		});

		s_textureIndexes.diffuse = settings.textures.size();
		settings.textures.push_back({
			"MaterialDiffuseMap",
			"Diffuse",
			ImageType_2D
		});

		settings.predefinedBinding[UnderlyingCast(PredefinedShaderBinding::TexOverlay)] = settings.textures.size();
		settings.textures.push_back({
			"TextureOverlay",
			"Overlay",
			ImageType_2D
		});

		s_uniformBlockIndex = settings.uniformBlocks.size();
		settings.uniformBlocks.assign({
			{
				fieldOffsets.GetSize(),
				"BasicSettings",
				"MaterialBasicSettings",
				std::move(variables),
				std::move(defaultValues)
			}
		});

		settings.predefinedBinding[UnderlyingCast(PredefinedShaderBinding::UboInstanceData)] = settings.textures.size() + settings.uniformBlocks.size() + settings.sharedUniformBlocks.size();
		settings.sharedUniformBlocks.push_back(PredefinedInstanceData::GetUniformBlock());

		settings.predefinedBinding[UnderlyingCast(PredefinedShaderBinding::UboViewerData)] = settings.textures.size() + settings.uniformBlocks.size() + settings.sharedUniformBlocks.size();
		settings.sharedUniformBlocks.push_back(PredefinedViewerData::GetUniformBlock());

		// Shaders
		auto& fragmentShader = settings.shaders[UnderlyingCast(ShaderStageType::Fragment)];
		auto& vertexShader = settings.shaders[UnderlyingCast(ShaderStageType::Vertex)];

		fragmentShader = std::make_shared<UberShader>(ShaderStageType::Fragment, ShaderAst::UnserializeShader(r_fragmentShader, sizeof(r_fragmentShader)));
		vertexShader = std::make_shared<UberShader>(ShaderStageType::Vertex, ShaderAst::UnserializeShader(r_vertexShader, sizeof(r_vertexShader)));

		// Conditions

		// HasDiffuseMap
		{
			std::array<UInt64, ShaderStageTypeCount> shaderConditions;
			shaderConditions.fill(0);
			shaderConditions[UnderlyingCast(ShaderStageType::Fragment)] = fragmentShader->GetOptionFlagByName("HAS_DIFFUSE_TEXTURE");

			s_conditionIndexes.hasDiffuseMap = settings.conditions.size();
			settings.conditions.push_back({
				"HasDiffuseMap",
				shaderConditions
			});
		}

		// HasAlphaMap
		{
			std::array<UInt64, ShaderStageTypeCount> shaderConditions;
			shaderConditions.fill(0);
			shaderConditions[UnderlyingCast(ShaderStageType::Fragment)] = fragmentShader->GetOptionFlagByName("HAS_ALPHA_TEXTURE");

			s_conditionIndexes.hasAlphaMap = settings.conditions.size();
			settings.conditions.push_back({
				"HasAlphaMap",
				shaderConditions
			});
		}

		// AlphaTest
		{
			std::array<UInt64, ShaderStageTypeCount> shaderConditions;
			shaderConditions.fill(0);
			shaderConditions[UnderlyingCast(ShaderStageType::Fragment)] = fragmentShader->GetOptionFlagByName("ALPHA_TEST");

			s_conditionIndexes.alphaTest = settings.conditions.size();
			settings.conditions.push_back({
				"AlphaTest",
				shaderConditions
			});
		}

		s_materialSettings = std::make_shared<MaterialSettings>(std::move(settings));

		return true;
	}

	void BasicMaterial::Uninitialize()
	{
		s_materialSettings.reset();
	}

	std::shared_ptr<MaterialSettings> BasicMaterial::s_materialSettings;
	std::size_t BasicMaterial::s_uniformBlockIndex;
	BasicMaterial::ConditionIndexes BasicMaterial::s_conditionIndexes;
	BasicMaterial::TextureIndexes BasicMaterial::s_textureIndexes;
	BasicMaterial::UniformOffsets BasicMaterial::s_uniformOffsets;
}
<|endoftext|>


<commit_before>/*===========================================================================*\
 *                                                                           *
 *                               OpenMesh                                    *
 *      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen      *
 *                           www.openmesh.org                                *
 *                                                                           *
 *---------------------------------------------------------------------------*
 *  This file is part of OpenMesh.                                           *
 *                                                                           *
 *  OpenMesh 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 with the              *
 *  following exceptions:                                                    *
 *                                                                           *
 *  If other files instantiate templates or use macros                       *
 *  or inline functions from this file, or you compile this file and         *
 *  link it with other files to produce an executable, this file does        *
 *  not by itself cause the resulting executable to be covered by the        *
 *  GNU Lesser General Public License. This exception does not however       *
 *  invalidate any other reasons why the executable file might be            *
 *  covered by the GNU Lesser General Public License.                        *
 *                                                                           *
 *  OpenMesh 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 LesserGeneral Public          *
 *  License along with OpenMesh.  If not,                                    *
 *  see <http://www.gnu.org/licenses/>.                                      *
 *                                                                           *
\*===========================================================================*/

/*===========================================================================*\
 *                                                                           *
 *   $Revision$                                                         *
 *   $Date$                   *
 *                                                                           *
\*===========================================================================*/

//=============================================================================
//
//  Helper Functions for binary reading / writing
//
//=============================================================================

#ifndef OPENMESH_COLOR_CAST_HH
#define OPENMESH_COLOR_CAST_HH

//== INCLUDES =================================================================

#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Utils/vector_cast.hh>

//== NAMESPACES ===============================================================

namespace OpenMesh {

//=============================================================================

/** \name Cast vector type to another vector type.
*/
//@{

//-----------------------------------------------------------------------------
#ifndef DOXY_IGNORE_THIS

/// Cast one color vector to another.
template <typename dst_t, typename src_t>
struct color_caster
{
  typedef dst_t  return_type;

  inline static return_type cast(const src_t& _src)
  {
    dst_t dst;
    vector_copy(_src, dst, GenProg::Int2Type<vector_traits<dst_t>::size_>());
    return dst;
  }
};

template <>
struct color_caster<Vec3uc,Vec3f>
{
  typedef Vec3uc return_type;

  inline static return_type cast(const Vec3f& _src)
  {
    return Vec3uc( (unsigned char)(_src[0]* 255.0f + 0.5f),
		               (unsigned char)(_src[1]* 255.0f + 0.5f),
		               (unsigned char)(_src[2]* 255.0f + 0.5f) );
  }
};

template <>
struct color_caster<Vec3uc,Vec4f>
{
  typedef Vec3uc return_type;

  inline static return_type cast(const Vec4f& _src)
  {
    return Vec3uc( (unsigned char)(_src[0]* 255.0f + 0.5f),
                   (unsigned char)(_src[1]* 255.0f + 0.5f),
                   (unsigned char)(_src[2]* 255.0f + 0.5f) );
  }
};

template <>
struct color_caster<Vec4uc,Vec3f>
{
  typedef Vec4uc return_type;

  inline static return_type cast(const Vec3f& _src)
  {
    return Vec4uc( (unsigned char)(_src[0]* 255.0f + 0.5f),
                   (unsigned char)(_src[1]* 255.0f + 0.5f),
                   (unsigned char)(_src[2]* 255.0f + 0.5f),
                   (unsigned char)(255) );
  }
};

template <>
struct color_caster<Vec4uc,Vec4f>
{
  typedef Vec4uc return_type;

  inline static return_type cast(const Vec4f& _src)
  {
    return Vec4uc( (unsigned char)(_src[0]* 255.0f + 0.5f),
                   (unsigned char)(_src[1]* 255.0f + 0.5f),
                   (unsigned char)(_src[2]* 255.0f + 0.5f),
                   (unsigned char)(_src[3]* 255.0f + 0.5f) );
  }
};

template <>
struct color_caster<Vec4uc,Vec3uc>
{
  typedef Vec4uc return_type;

  inline static return_type cast(const Vec3uc& _src)
  {
    return Vec4uc( _src[0], _src[1], _src[2], 255 );
  }
};

template <>
struct color_caster<Vec3f, Vec3uc>
{
  typedef Vec3f return_type;

  inline static return_type cast(const Vec3uc& _src)
  {
    const float f = 1.0f / 255.0f;
    return Vec3f(_src[0] * f, _src[1] *  f, _src[2] * f );
  }
};

template <>
struct color_caster<Vec3f, Vec4uc>
{
  typedef Vec3f return_type;

  inline static return_type cast(const Vec4uc& _src)
  {
    const float f = 1.0f / 255.0f;
    return Vec3f(_src[0] * f, _src[1] *  f, _src[2] * f );
  }
};

template <>
struct color_caster<Vec4f, Vec3uc>
{
  typedef Vec4f return_type;

  inline static return_type cast(const Vec3uc& _src)
  {
    const float f = 1.0f / 255.0f;
    return Vec4f(_src[0] * f, _src[1] *  f, _src[2] * f, 1.0f );
  }
};

template <>
struct color_caster<Vec4f, Vec4uc>
{
  typedef Vec4f return_type;

  inline static return_type cast(const Vec4uc& _src)
  {
    const float f = 1.0f / 255.0f;
    return Vec4f(_src[0] * f, _src[1] *  f, _src[2] * f, _src[3] * f );
  }
};

// ----------------------------------------------------------------------------

#ifndef DOXY_IGNORE_THIS

#if !defined(OM_CC_MSVC)
template <typename dst_t>
struct color_caster<dst_t,dst_t>
{
  typedef const dst_t&  return_type;

  inline static return_type cast(const dst_t& _src)
  {
    return _src;
  }
};
#endif

#endif

//-----------------------------------------------------------------------------

template <typename dst_t, typename src_t>
inline
typename color_caster<dst_t, src_t>::return_type
color_cast(const src_t& _src )
{
  return color_caster<dst_t, src_t>::cast(_src);
}

#endif
//-----------------------------------------------------------------------------

//@}

//=============================================================================
} // namespace OpenMesh
//=============================================================================
#endif // OPENMESH_COLOR_CAST_HH defined
//=============================================================================

<commit_msg>Added color caster from vec3f to vec4f<commit_after>/*===========================================================================*\
 *                                                                           *
 *                               OpenMesh                                    *
 *      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen      *
 *                           www.openmesh.org                                *
 *                                                                           *
 *---------------------------------------------------------------------------*
 *  This file is part of OpenMesh.                                           *
 *                                                                           *
 *  OpenMesh 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 with the              *
 *  following exceptions:                                                    *
 *                                                                           *
 *  If other files instantiate templates or use macros                       *
 *  or inline functions from this file, or you compile this file and         *
 *  link it with other files to produce an executable, this file does        *
 *  not by itself cause the resulting executable to be covered by the        *
 *  GNU Lesser General Public License. This exception does not however       *
 *  invalidate any other reasons why the executable file might be            *
 *  covered by the GNU Lesser General Public License.                        *
 *                                                                           *
 *  OpenMesh 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 LesserGeneral Public          *
 *  License along with OpenMesh.  If not,                                    *
 *  see <http://www.gnu.org/licenses/>.                                      *
 *                                                                           *
\*===========================================================================*/

/*===========================================================================*\
 *                                                                           *
 *   $Revision$                                                         *
 *   $Date$                   *
 *                                                                           *
\*===========================================================================*/

//=============================================================================
//
//  Helper Functions for binary reading / writing
//
//=============================================================================

#ifndef OPENMESH_COLOR_CAST_HH
#define OPENMESH_COLOR_CAST_HH

//== INCLUDES =================================================================

#include <OpenMesh/Core/System/config.h>
#include <OpenMesh/Core/Utils/vector_cast.hh>

//== NAMESPACES ===============================================================

namespace OpenMesh {

//=============================================================================

/** \name Cast vector type to another vector type.
*/
//@{

//-----------------------------------------------------------------------------
#ifndef DOXY_IGNORE_THIS

/// Cast one color vector to another.
template <typename dst_t, typename src_t>
struct color_caster
{
  typedef dst_t  return_type;

  inline static return_type cast(const src_t& _src)
  {
    dst_t dst;
    vector_copy(_src, dst, GenProg::Int2Type<vector_traits<dst_t>::size_>());
    return dst;
  }
};

template <>
struct color_caster<Vec3uc,Vec3f>
{
  typedef Vec3uc return_type;

  inline static return_type cast(const Vec3f& _src)
  {
    return Vec3uc( (unsigned char)(_src[0]* 255.0f + 0.5f),
		               (unsigned char)(_src[1]* 255.0f + 0.5f),
		               (unsigned char)(_src[2]* 255.0f + 0.5f) );
  }
};

template <>
struct color_caster<Vec3uc,Vec4f>
{
  typedef Vec3uc return_type;

  inline static return_type cast(const Vec4f& _src)
  {
    return Vec3uc( (unsigned char)(_src[0]* 255.0f + 0.5f),
                   (unsigned char)(_src[1]* 255.0f + 0.5f),
                   (unsigned char)(_src[2]* 255.0f + 0.5f) );
  }
};

template <>
struct color_caster<Vec4uc,Vec3f>
{
  typedef Vec4uc return_type;

  inline static return_type cast(const Vec3f& _src)
  {
    return Vec4uc( (unsigned char)(_src[0]* 255.0f + 0.5f),
                   (unsigned char)(_src[1]* 255.0f + 0.5f),
                   (unsigned char)(_src[2]* 255.0f + 0.5f),
                   (unsigned char)(255) );
  }
};

template <>
struct color_caster<Vec4f,Vec3f>
{
  typedef Vec4f return_type;

  inline static return_type cast(const Vec3f& _src)
  {
    return Vec4f( _src[0],
                  _src[1],
                  _src[2],
                  1.0f );
  }
};

template <>
struct color_caster<Vec4uc,Vec4f>
{
  typedef Vec4uc return_type;

  inline static return_type cast(const Vec4f& _src)
  {
    return Vec4uc( (unsigned char)(_src[0]* 255.0f + 0.5f),
                   (unsigned char)(_src[1]* 255.0f + 0.5f),
                   (unsigned char)(_src[2]* 255.0f + 0.5f),
                   (unsigned char)(_src[3]* 255.0f + 0.5f) );
  }
};

template <>
struct color_caster<Vec4uc,Vec3uc>
{
  typedef Vec4uc return_type;

  inline static return_type cast(const Vec3uc& _src)
  {
    return Vec4uc( _src[0], _src[1], _src[2], 255 );
  }
};

template <>
struct color_caster<Vec3f, Vec3uc>
{
  typedef Vec3f return_type;

  inline static return_type cast(const Vec3uc& _src)
  {
    const float f = 1.0f / 255.0f;
    return Vec3f(_src[0] * f, _src[1] *  f, _src[2] * f );
  }
};

template <>
struct color_caster<Vec3f, Vec4uc>
{
  typedef Vec3f return_type;

  inline static return_type cast(const Vec4uc& _src)
  {
    const float f = 1.0f / 255.0f;
    return Vec3f(_src[0] * f, _src[1] *  f, _src[2] * f );
  }
};

template <>
struct color_caster<Vec4f, Vec3uc>
{
  typedef Vec4f return_type;

  inline static return_type cast(const Vec3uc& _src)
  {
    const float f = 1.0f / 255.0f;
    return Vec4f(_src[0] * f, _src[1] *  f, _src[2] * f, 1.0f );
  }
};

template <>
struct color_caster<Vec4f, Vec4uc>
{
  typedef Vec4f return_type;

  inline static return_type cast(const Vec4uc& _src)
  {
    const float f = 1.0f / 255.0f;
    return Vec4f(_src[0] * f, _src[1] *  f, _src[2] * f, _src[3] * f );
  }
};

// ----------------------------------------------------------------------------

#ifndef DOXY_IGNORE_THIS

#if !defined(OM_CC_MSVC)
template <typename dst_t>
struct color_caster<dst_t,dst_t>
{
  typedef const dst_t&  return_type;

  inline static return_type cast(const dst_t& _src)
  {
    return _src;
  }
};
#endif

#endif

//-----------------------------------------------------------------------------

template <typename dst_t, typename src_t>
inline
typename color_caster<dst_t, src_t>::return_type
color_cast(const src_t& _src )
{
  return color_caster<dst_t, src_t>::cast(_src);
}

#endif
//-----------------------------------------------------------------------------

//@}

//=============================================================================
} // namespace OpenMesh
//=============================================================================
#endif // OPENMESH_COLOR_CAST_HH defined
//=============================================================================

<|endoftext|>


<commit_before>/****************************************************************************/
/**
**  @file tInputFile.cpp
**  @brief Member functions for class tInputFile.
**
**  (see tInputFile.h for a description of this class)
**
**  Greg Tucker, November 1997
**  Re-written, AD, July 2003
**
**  $Id: tInputFile.cpp,v 1.36 2004-05-28 16:43:26 childcvs Exp $
*/
/****************************************************************************/

#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

#include "tInputFile.h"
#include "../errors/errors.h"
#include "../tList/tList.h"
#include "../tTimeSeries/tTimeSeries.h"

#if !defined(HAVE_NO_NAMESPACE)
# include <iostream>
# include <fstream>
using namespace std;
#else
# include <iostream.h>
# include <fstream.h>
#endif

#define kCommentMark '#'

/****************************************************************************\
**
**  tKeyPair
**
**  a simple key-value class.
**  - 11/07/2003 AD
\****************************************************************************/

tKeyPair::tKeyPair(const char *key, const char *value) :
  key_(0), value_(0)
{
  setKey(key);
  setValue(value);
}

tKeyPair::tKeyPair(tKeyPair const &k) :
  key_(0), value_(0)
{
  setKey(k.key_);
  setValue(k.value_);
}

tKeyPair& tKeyPair::operator=(tKeyPair const&k){
  if (&k != this) {
    setKey(k.key_);
    setValue(k.value_);
  }
  return *this;
}

tKeyPair::~tKeyPair(){
  clear();
}

void tKeyPair::setKey(const char *s){
  clearKey();
  if (s == NULL) return;
  key_ = new char[strlen(s)+1];
  strcpy(key_,s);
}

void tKeyPair::setValue(const char *s){
  clearValue();
  if (s == NULL) return;
  value_ = new char[strlen(s)+1];
  strcpy(value_,s);
}

void tKeyPair::clear(){
  clearKey();
  clearValue();
}

void tKeyPair::clearKey(){
  delete [] key_; key_ = NULL;
}

void tKeyPair::clearValue(){
  delete [] value_; value_ = NULL;
}

/****************************************************************************\
**
**  setKeyWordTable
**
**  Set KeyWordTable
**  - 11/07/2003 AD
\****************************************************************************/
static
void setKeyWordTable(tArray< tKeyPair > &KeyWordTable,
		     tList< tKeyPair > &KeyWordList) {
  KeyWordTable.setSize(KeyWordList.getSize());
  int i = 0;
  tListIter< tKeyPair > ki(KeyWordList);
  for( tKeyPair *k=ki.FirstP(); !(ki.AtEnd()); k=ki.NextP(), ++i ) {
    KeyWordTable[i] = *k;
  }
}

/****************************************************************************\
**
**  various functions used for reading the input file
**
**  - 11/07/2003 AD
\****************************************************************************/
// read a line in headerLine and discards the any remaining characters
static
void readLine(char *headerLine, ifstream& infile){
  infile.getline( headerLine, kMaxNameLength );
  // still some characters left on the current line ?
  if ( !infile.eof() && !infile.bad() && infile.rdstate() & ios::failbit){
    // clear failbit
    infile.clear(infile.rdstate() & ~ios::failbit);
    // discard characters.
    char c;
    while( infile.get(c) && c != '\n');
  }
}

inline bool isComment(const char *headerLine){
  assert(headerLine != NULL);
  return BOOL(headerLine[0]==kCommentMark);
}

static
void skipCommentsAndReadValue(char *headerLine, ifstream& infile){
  do {
    readLine(headerLine, infile);
  } while( !infile.eof() && !infile.bad() &&
	   isComment(headerLine) );
}

// strip a string at the first ' ' or ':' found.
static
void stripKey(char *key){
  char c;
  int i = 0;
  while((c = key[i]) != '\n'){
    if (c == ':' || c == ' '){
      key[i] = '\0';
      break;
    }
    ++i;
  }
}

static
void stripTrailingCR(char *s){
  // strip trailing '\r' if we are dealing with a windows CR/LF text file
  const size_t len = strlen(s);
  if (len == 0) return;
  if (s[len-1] == '\r') s[len-1] = '\0';
}

static
void stripTrailingBlanks(char *s){
  const size_t len = strlen(s);
  int i = len - 1;
  while(i>=0){
    if (s[i] != ' '){
      s[i+1] = '\0';
      break;
    }
    --i;
  }
}

/* Read input file and build a list of key,value pair */
static
void readInputFile(ifstream& infile, tList< tKeyPair > &KeyWordList){
  char headerLine[kMaxNameLength];
  enum{ KEY, VALUE} state = KEY;
  tKeyPair aPair;

  for(;;){
    skipCommentsAndReadValue(headerLine, infile);
    if (infile.eof() || infile.bad())
      break;
    if (isComment(headerLine))
      goto fail;
    stripTrailingCR(headerLine);
    stripTrailingBlanks(headerLine);
    // if a blank line is reached, we stop.
    if (headerLine[0] == '\0')
      break;
    switch (state){
    case KEY:
      stripKey(headerLine);
      aPair.setKey(headerLine);
      state = VALUE;
      break;
    case VALUE:
      aPair.setValue(headerLine);
      assert(aPair.key() != NULL);
      KeyWordList.insertAtBack(aPair);
      aPair.clear();
      state = KEY;
      break;
    }
  }

  return;
 fail:
  cerr
    << "I expected to read a parameter or a value"
    "', but reached EOF first" << endl;
  ReportFatalError( "Error in input file" );
  /*NOTREACHED*/
}

/****************************************************************************\
**
**  tInputFile Constructor
**
**  Looks for a file called filename, opens it if found or generates an
**  error if not. Then reads the base name for output files and creates
**  a file called <filename>.inputs which will act as a log file for
**  parameters read. (This is often useful when the original input file
**  gets lost or modified).
**
**  Modifications:
**    - 2/02: error check for inoutfile added (GT)
**    - rewritten 11/07/2003 AD
**
\****************************************************************************/
tInputFile::tInputFile( const char *filename )
{
   ifstream infile;     // the input file

   // Open file
   infile.open( filename );
   if( !infile.good() )
   {
      cerr << "tInputFile::tInputFile: Unable to open '" << filename
	   << "'." << endl;
      ReportFatalError( "The file may not exist or may be mis-named." );
   }

   // Set KeyWordTable
   {
     tList< tKeyPair > KeyWordList;
     readInputFile(infile, KeyWordList);
     setKeyWordTable(KeyWordTable, KeyWordList);
   }
   infile.close();

   // write log File
   writeLogFile();
}

/****************************************************************************\
**
**  tInputFile::writeLogFile
**
**  Write log file.
**  - 11/07/2003 AD
\****************************************************************************/
void tInputFile::writeLogFile() const
{
  ofstream inoutfile;  // output file in which items are recorded
  char inoutname[kMaxNameLength];
  // Create log file for inputs
  ReadItem( inoutname, sizeof(inoutname), "OUTFILENAME" );
  strcat( inoutname, ".inputs" );
  inoutfile.open( inoutname );
  if( !inoutfile.good() )
    {
      cerr << "Unable to open '" << inoutname << "'.\n"
	"(Error generated in module tInputFile,"
	" function tInputFile::tInputFile( const char * ) )" << endl;
      ReportFatalError( "The specified path name may not exist.\n" );
    }
  // write header
  {
    const time_t now = time(NULL);
    char *p = ctime(&now);
    *strchr(p, '\n') = '\0';
    inoutfile << "# Created by CHILD on " << p << "." << endl;
  }
  // dump content of KeyWordTable
  {
    const int len = KeyWordTable.getSize();
     for( int i = 0; i < len; ++i ) {
       inoutfile << KeyWordTable[i].key() << '\n'
		 << KeyWordTable[i].value() << '\n';
     }
  }
  inoutfile.close();
}

/****************************************************************************\
**
**  tInputFile::findKeyWord
**
**  Find a tKeyPair in KeyWordTable. A match is found when the beginning of a
**  key is equal to the argument 'key'.
**  Returns notFound in case of failure.
**  - 11/07/2003 AD
\****************************************************************************/
int tInputFile::findKeyWord( const char *key ) const
{
  assert(key != NULL);
  const int len = KeyWordTable.getSize();
  const size_t sizeKey = strlen(key);

  for(int i=0; i < len; ++i){
    const char * const thisKey = KeyWordTable[i].key();
    if (0 == strncmp(key, thisKey, sizeKey)) {
      if (strlen(thisKey) != sizeKey)
	cout
	  << "Warning: `" << thisKey << "' chosen as match for keyword `"
	  << key << "'." << endl;
      return i;
    }
  }
  return notFound;
}

bool tInputFile::Contain(const char *itemCode) const {
  return findKeyWord( itemCode ) != notFound;
}

void tInputFile::WarnObsoleteKeyword(const char *ancient,
				     const char *modern) const {
  if (Contain(ancient))
    cout
      << "Warning: `" << ancient << "' is obsolete and is ignored.\n Use `"
      << modern << "' instead." << endl;
}

/****************************************************************************\
**
**  tInputFile::ReadItem
**
**  Reads one parameter from the file. The format is assumed to be a line
**  of text that begins with the code "itemCode", followed by a line containing
**  the parameter to be read. The function is overloaded according to the
**  type of data desired (datType simply governs which overloaded function
**  will be called; it is not used by the routines).
**
**  Inputs:  datType -- dummy variable indicating the data type to be read
**                      (in the case of the string version, the string read
**                      is placed here)
**           itemCode -- string that describes the parameter to be read
**  Returns:  the item read (except in the case of the string version)
**  Modifications:
**    - revised to allow arbitrary ordering of items in infile and/or
**      ReadItem calls in code; routine searches through
**      list until it either finds the right itemCode or reaches EOF.
**      12/23/97 SL
**    - rewritten 11/07/2003 AD
**    - can merely issue warning and return zero-value if bool reqParam =
**      true. 9/12/03 SL
**
\****************************************************************************/
static
void ReportNonExistingKeyWord(const char *itemCode, bool reqParam ){
  cerr << "Cannot find  '" << itemCode
       << "' in the input file." << endl;
  if( reqParam )
      ReportFatalError( "Missing parameter in input file" );
  else
      ReportWarning( "Missing parameter in input file, use zero or default value" );
}

int tInputFile::ReadItem( const int & /*datType*/, const char *itemCode, bool reqParam ) const
{
  return ReadInt( itemCode, reqParam );
}

long tInputFile::ReadItem( const long & /*datType*/, const char *itemCode, bool reqParam ) const
{
  return ReadLong( itemCode, reqParam );
}

double tInputFile::ReadItem( const double & /*datType*/, const char *itemCode, bool reqParam ) const
{
  return ReadDouble( itemCode, reqParam );
}

// The size of 'theString' is 'len' including the trailing '\0'
void tInputFile::ReadItem( char * theString, size_t len,
			   const char *itemCode, bool reqParam ) const
{
  assert(len>0);
  const int i = findKeyWord( itemCode );
  if (i == notFound)
  {
     ReportNonExistingKeyWord( itemCode, reqParam );
     theString[0] = '\0';
     return;
  }
  strncpy(theString, KeyWordTable[i].value(), len);
  theString[len-1] = '\0';
}

bool tInputFile::ReadBool( const char *itemCode, bool reqParam ) const
{
  const int i = findKeyWord( itemCode );
  if (i == notFound)
  {
     ReportNonExistingKeyWord( itemCode, reqParam );
     return false;
  }

  const char * const v = KeyWordTable[i].value();
  if (strlen(v)>=4
      && (v[0] == 'T' || v[0] == 't' )
      && (v[1] == 'R' || v[1] == 'r' )
      && (v[2] == 'U' || v[2] == 'u' )
      && (v[3] == 'E' || v[3] == 'e' )
      ) return true;
  if (strlen(v)>=5
      && (v[0] == 'F' || v[0] == 'f' )
      && (v[1] == 'A' || v[1] == 'a' )
      && (v[2] == 'L' || v[2] == 'l' )
      && (v[3] == 'S' || v[3] == 's' )
      && (v[4] == 'S' || v[4] == 'e' )
      ) return false;
  return 0 != atoi(KeyWordTable[i].value());
}

int tInputFile::ReadInt( const char *itemCode, bool reqParam ) const
{
  const int i = findKeyWord( itemCode );
  if (i == notFound)
  {
     ReportNonExistingKeyWord( itemCode, reqParam );
     return 0;
  }
  return atoi(KeyWordTable[i].value());
}

double tInputFile::ReadDouble( const char *itemCode, bool reqParam  ) const
{
  const int i = findKeyWord( itemCode );
  if (i == notFound)
  {
    ReportNonExistingKeyWord( itemCode, reqParam );
    return 0.0;
  }
  return atof(KeyWordTable[i].value());
}

long tInputFile::ReadLong( const char *itemCode, bool reqParam ) const
{
  const int i = findKeyWord( itemCode );
  if (i == notFound)
  {
    ReportNonExistingKeyWord( itemCode, reqParam );
    return 0L;
  }
  return atol(KeyWordTable[i].value());
}

tArray< tKeyPair > & tInputFile::GetKeyWordTableRef()
{
  return KeyWordTable;
}

//****************************************************************
// Designed and implemented:
// PWB, jan-feb 2000
// AD Jan 2004: Added to Child.
//****************************************************************
void tInputFile::ReadItem(tTimeSeries &ts, const char *itemCode,
			  bool reqParam ) const
{
  const int i = findKeyWord( itemCode );
  if (i == notFound)
  {
    ReportNonExistingKeyWord( itemCode, reqParam );
    return;
  }
  ts.configure(KeyWordTable[i].value());
}
<commit_msg>(Arnaud) fix stripKeys that contained a stupid typo.<commit_after>/****************************************************************************/
/**
**  @file tInputFile.cpp
**  @brief Member functions for class tInputFile.
**
**  (see tInputFile.h for a description of this class)
**
**  Greg Tucker, November 1997
**  Re-written, AD, July 2003
**
**  $Id: tInputFile.cpp,v 1.37 2004-06-02 09:58:14 childcvs Exp $
*/
/****************************************************************************/

#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

#include "tInputFile.h"
#include "../errors/errors.h"
#include "../tList/tList.h"
#include "../tTimeSeries/tTimeSeries.h"

#if !defined(HAVE_NO_NAMESPACE)
# include <iostream>
# include <fstream>
using namespace std;
#else
# include <iostream.h>
# include <fstream.h>
#endif

#define kCommentMark '#'

/****************************************************************************\
**
**  tKeyPair
**
**  a simple key-value class.
**  - 11/07/2003 AD
\****************************************************************************/

tKeyPair::tKeyPair(const char *key, const char *value) :
  key_(0), value_(0)
{
  setKey(key);
  setValue(value);
}

tKeyPair::tKeyPair(tKeyPair const &k) :
  key_(0), value_(0)
{
  setKey(k.key_);
  setValue(k.value_);
}

tKeyPair& tKeyPair::operator=(tKeyPair const&k){
  if (&k != this) {
    setKey(k.key_);
    setValue(k.value_);
  }
  return *this;
}

tKeyPair::~tKeyPair(){
  clear();
}

void tKeyPair::setKey(const char *s){
  clearKey();
  if (s == NULL) return;
  key_ = new char[strlen(s)+1];
  strcpy(key_,s);
}

void tKeyPair::setValue(const char *s){
  clearValue();
  if (s == NULL) return;
  value_ = new char[strlen(s)+1];
  strcpy(value_,s);
}

void tKeyPair::clear(){
  clearKey();
  clearValue();
}

void tKeyPair::clearKey(){
  delete [] key_; key_ = NULL;
}

void tKeyPair::clearValue(){
  delete [] value_; value_ = NULL;
}

/****************************************************************************\
**
**  setKeyWordTable
**
**  Set KeyWordTable
**  - 11/07/2003 AD
\****************************************************************************/
static
void setKeyWordTable(tArray< tKeyPair > &KeyWordTable,
		     tList< tKeyPair > &KeyWordList) {
  KeyWordTable.setSize(KeyWordList.getSize());
  int i = 0;
  tListIter< tKeyPair > ki(KeyWordList);
  for( tKeyPair *k=ki.FirstP(); !(ki.AtEnd()); k=ki.NextP(), ++i ) {
    KeyWordTable[i] = *k;
  }
}

/****************************************************************************\
**
**  various functions used for reading the input file
**
**  - 11/07/2003 AD
\****************************************************************************/
// read a line in headerLine and discards the any remaining characters
static
void readLine(char *headerLine, ifstream& infile){
  infile.getline( headerLine, kMaxNameLength );
  // still some characters left on the current line ?
  if ( !infile.eof() && !infile.bad() && infile.rdstate() & ios::failbit){
    // clear failbit
    infile.clear(infile.rdstate() & ~ios::failbit);
    // discard characters.
    char c;
    while( infile.get(c) && c != '\n');
  }
}

inline bool isComment(const char *headerLine){
  assert(headerLine != NULL);
  return BOOL(headerLine[0]==kCommentMark);
}

static
void skipCommentsAndReadValue(char *headerLine, ifstream& infile){
  do {
    readLine(headerLine, infile);
  } while( !infile.eof() && !infile.bad() &&
	   isComment(headerLine) );
}

// strip a string at the first ' ' or ':' found.
static
void stripKey(char *key){
  char c;
  int i = 0;
  while((c = key[i]) != '\0'){
    if (c == ':' || c == ' '){
      key[i] = '\0';
      break;
    }
    ++i;
  }
}

static
void stripTrailingCR(char *s){
  // strip trailing '\r' if we are dealing with a windows CR/LF text file
  const size_t len = strlen(s);
  if (len == 0) return;
  if (s[len-1] == '\r') s[len-1] = '\0';
}

static
void stripTrailingBlanks(char *s){
  const size_t len = strlen(s);
  int i = len - 1;
  while(i>=0){
    if (s[i] != ' '){
      s[i+1] = '\0';
      break;
    }
    --i;
  }
}

/* Read input file and build a list of key,value pair */
static
void readInputFile(ifstream& infile, tList< tKeyPair > &KeyWordList){
  char headerLine[kMaxNameLength];
  enum{ KEY, VALUE} state = KEY;
  tKeyPair aPair;

  for(;;){
    skipCommentsAndReadValue(headerLine, infile);
    if (infile.eof() || infile.bad())
      break;
    if (isComment(headerLine))
      goto fail;
    stripTrailingCR(headerLine);
    stripTrailingBlanks(headerLine);
    // if a blank line is reached, we stop.
    if (headerLine[0] == '\0')
      break;
    switch (state){
    case KEY:
      stripKey(headerLine);
      aPair.setKey(headerLine);
      state = VALUE;
      break;
    case VALUE:
      aPair.setValue(headerLine);
      assert(aPair.key() != NULL);
      KeyWordList.insertAtBack(aPair);
      aPair.clear();
      state = KEY;
      break;
    }
  }

  return;
 fail:
  cerr
    << "I expected to read a parameter or a value"
    "', but reached EOF first" << endl;
  ReportFatalError( "Error in input file" );
  /*NOTREACHED*/
}

/****************************************************************************\
**
**  tInputFile Constructor
**
**  Looks for a file called filename, opens it if found or generates an
**  error if not. Then reads the base name for output files and creates
**  a file called <filename>.inputs which will act as a log file for
**  parameters read. (This is often useful when the original input file
**  gets lost or modified).
**
**  Modifications:
**    - 2/02: error check for inoutfile added (GT)
**    - rewritten 11/07/2003 AD
**
\****************************************************************************/
tInputFile::tInputFile( const char *filename )
{
   ifstream infile;     // the input file

   // Open file
   infile.open( filename );
   if( !infile.good() )
   {
      cerr << "tInputFile::tInputFile: Unable to open '" << filename
	   << "'." << endl;
      ReportFatalError( "The file may not exist or may be mis-named." );
   }

   // Set KeyWordTable
   {
     tList< tKeyPair > KeyWordList;
     readInputFile(infile, KeyWordList);
     setKeyWordTable(KeyWordTable, KeyWordList);
   }
   infile.close();

   // write log File
   writeLogFile();
}

/****************************************************************************\
**
**  tInputFile::writeLogFile
**
**  Write log file.
**  - 11/07/2003 AD
\****************************************************************************/
void tInputFile::writeLogFile() const
{
  ofstream inoutfile;  // output file in which items are recorded
  char inoutname[kMaxNameLength];
  // Create log file for inputs
  ReadItem( inoutname, sizeof(inoutname), "OUTFILENAME" );
  strcat( inoutname, ".inputs" );
  inoutfile.open( inoutname );
  if( !inoutfile.good() )
    {
      cerr << "Unable to open '" << inoutname << "'.\n"
	"(Error generated in module tInputFile,"
	" function tInputFile::tInputFile( const char * ) )" << endl;
      ReportFatalError( "The specified path name may not exist.\n" );
    }
  // write header
  {
    const time_t now = time(NULL);
    char *p = ctime(&now);
    *strchr(p, '\n') = '\0';
    inoutfile << "# Created by CHILD on " << p << "." << endl;
  }
  // dump content of KeyWordTable
  {
    const int len = KeyWordTable.getSize();
     for( int i = 0; i < len; ++i ) {
       inoutfile << KeyWordTable[i].key() << '\n'
		 << KeyWordTable[i].value() << '\n';
     }
  }
  inoutfile.close();
}

/****************************************************************************\
**
**  tInputFile::findKeyWord
**
**  Find a tKeyPair in KeyWordTable. A match is found when the beginning of a
**  key is equal to the argument 'key'.
**  Returns notFound in case of failure.
**  - 11/07/2003 AD
\****************************************************************************/
int tInputFile::findKeyWord( const char *key ) const
{
  assert(key != NULL);
  const int len = KeyWordTable.getSize();
  const size_t sizeKey = strlen(key);

  for(int i=0; i < len; ++i){
    const char * const thisKey = KeyWordTable[i].key();
    if (0 == strncmp(key, thisKey, sizeKey)) {
      if (strlen(thisKey) != sizeKey)
	cout
	  << "Warning: `" << thisKey << "' chosen as match for keyword `"
	  << key << "'." << endl;
      return i;
    }
  }
  return notFound;
}

bool tInputFile::Contain(const char *itemCode) const {
  return findKeyWord( itemCode ) != notFound;
}

void tInputFile::WarnObsoleteKeyword(const char *ancient,
				     const char *modern) const {
  if (Contain(ancient))
    cout
      << "Warning: `" << ancient << "' is obsolete and is ignored.\n Use `"
      << modern << "' instead." << endl;
}

/****************************************************************************\
**
**  tInputFile::ReadItem
**
**  Reads one parameter from the file. The format is assumed to be a line
**  of text that begins with the code "itemCode", followed by a line containing
**  the parameter to be read. The function is overloaded according to the
**  type of data desired (datType simply governs which overloaded function
**  will be called; it is not used by the routines).
**
**  Inputs:  datType -- dummy variable indicating the data type to be read
**                      (in the case of the string version, the string read
**                      is placed here)
**           itemCode -- string that describes the parameter to be read
**  Returns:  the item read (except in the case of the string version)
**  Modifications:
**    - revised to allow arbitrary ordering of items in infile and/or
**      ReadItem calls in code; routine searches through
**      list until it either finds the right itemCode or reaches EOF.
**      12/23/97 SL
**    - rewritten 11/07/2003 AD
**    - can merely issue warning and return zero-value if bool reqParam =
**      true. 9/12/03 SL
**
\****************************************************************************/
static
void ReportNonExistingKeyWord(const char *itemCode, bool reqParam ){
  cerr << "Cannot find  '" << itemCode
       << "' in the input file." << endl;
  if( reqParam )
      ReportFatalError( "Missing parameter in input file" );
  else
      ReportWarning( "Missing parameter in input file, use zero or default value" );
}

int tInputFile::ReadItem( const int & /*datType*/, const char *itemCode, bool reqParam ) const
{
  return ReadInt( itemCode, reqParam );
}

long tInputFile::ReadItem( const long & /*datType*/, const char *itemCode, bool reqParam ) const
{
  return ReadLong( itemCode, reqParam );
}

double tInputFile::ReadItem( const double & /*datType*/, const char *itemCode, bool reqParam ) const
{
  return ReadDouble( itemCode, reqParam );
}

// The size of 'theString' is 'len' including the trailing '\0'
void tInputFile::ReadItem( char * theString, size_t len,
			   const char *itemCode, bool reqParam ) const
{
  assert(len>0);
  const int i = findKeyWord( itemCode );
  if (i == notFound)
  {
     ReportNonExistingKeyWord( itemCode, reqParam );
     theString[0] = '\0';
     return;
  }
  strncpy(theString, KeyWordTable[i].value(), len);
  theString[len-1] = '\0';
}

bool tInputFile::ReadBool( const char *itemCode, bool reqParam ) const
{
  const int i = findKeyWord( itemCode );
  if (i == notFound)
  {
     ReportNonExistingKeyWord( itemCode, reqParam );
     return false;
  }

  const char * const v = KeyWordTable[i].value();
  if (strlen(v)>=4
      && (v[0] == 'T' || v[0] == 't' )
      && (v[1] == 'R' || v[1] == 'r' )
      && (v[2] == 'U' || v[2] == 'u' )
      && (v[3] == 'E' || v[3] == 'e' )
      ) return true;
  if (strlen(v)>=5
      && (v[0] == 'F' || v[0] == 'f' )
      && (v[1] == 'A' || v[1] == 'a' )
      && (v[2] == 'L' || v[2] == 'l' )
      && (v[3] == 'S' || v[3] == 's' )
      && (v[4] == 'S' || v[4] == 'e' )
      ) return false;
  return 0 != atoi(KeyWordTable[i].value());
}

int tInputFile::ReadInt( const char *itemCode, bool reqParam ) const
{
  const int i = findKeyWord( itemCode );
  if (i == notFound)
  {
     ReportNonExistingKeyWord( itemCode, reqParam );
     return 0;
  }
  return atoi(KeyWordTable[i].value());
}

double tInputFile::ReadDouble( const char *itemCode, bool reqParam  ) const
{
  const int i = findKeyWord( itemCode );
  if (i == notFound)
  {
    ReportNonExistingKeyWord( itemCode, reqParam );
    return 0.0;
  }
  return atof(KeyWordTable[i].value());
}

long tInputFile::ReadLong( const char *itemCode, bool reqParam ) const
{
  const int i = findKeyWord( itemCode );
  if (i == notFound)
  {
    ReportNonExistingKeyWord( itemCode, reqParam );
    return 0L;
  }
  return atol(KeyWordTable[i].value());
}

tArray< tKeyPair > & tInputFile::GetKeyWordTableRef()
{
  return KeyWordTable;
}

//****************************************************************
// Designed and implemented:
// PWB, jan-feb 2000
// AD Jan 2004: Added to Child.
//****************************************************************
void tInputFile::ReadItem(tTimeSeries &ts, const char *itemCode,
			  bool reqParam ) const
{
  const int i = findKeyWord( itemCode );
  if (i == notFound)
  {
    ReportNonExistingKeyWord( itemCode, reqParam );
    return;
  }
  ts.configure(KeyWordTable[i].value());
}
<|endoftext|>