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

#ifndef MAPNIK_ENUMERATION_HPP
#define MAPNIK_ENUMERATION_HPP

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

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

namespace mapnik {

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

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

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

protected:
    std::string what_;
};

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

template <typename ENUM, int THE_MAX>
class MAPNIK_DECL enumeration {
public:
    using native_type = ENUM;

    enumeration()
        :  value_() {}

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

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

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

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

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

    enum Max
    {
        MAX = THE_MAX
    };

    /** Converts @p str to an enum.
     * @throw illegal_enum_value @p str is not a legal identifier.
     * */
    void from_string(std::string const& str)
    {
        // TODO: Enum value strings with underscore are deprecated in Mapnik 3.x
        // and support will be removed in Mapnik 4.x.
        bool deprecated = false;
        std::string str_copy(str);
        if (str_copy.find('_') != std::string::npos)
        {
            std::replace(str_copy.begin(), str_copy.end(), '_', '-');
            deprecated = true;
        }
        for (unsigned i = 0; i < THE_MAX; ++i)
        {
            if (str_copy == our_strings_[i])
            {
                value_ = static_cast<ENUM>(i);
                if (deprecated)
                {
                    MAPNIK_LOG_ERROR(enumerations) << "enumeration value (" << str << ") using \"_\" is deprecated and will be removed in Mapnik 4.x, use '" << str_copy << "' instead";
                }
                return;
            }
        }
        throw illegal_enum_value(std::string("Illegal enumeration value '") +
                                 str + "' for enum " + our_name_);
    }

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

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

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

        return is;
    }

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

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

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

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

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

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

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

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

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

} // end of namespace

/** Helper macro.
 * @relates mapnik::enumeration
 */
#ifdef _MSC_VER
#define DEFINE_ENUM( name, e)                   \
    template enumeration<e, e ## _MAX>;         \
    using name = enumeration<e, e ## _MAX>;
#else
#define DEFINE_ENUM( name, e)                   \
    using name = enumeration<e, e ## _MAX>;
#endif

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

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

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

#ifndef MAPNIK_ENUMERATION_HPP
#define MAPNIK_ENUMERATION_HPP

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

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

namespace mapnik {

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

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

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

protected:
    std::string what_;
};

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

template <typename ENUM, int THE_MAX>
class MAPNIK_DECL enumeration {
public:
    using native_type = ENUM;

    enumeration()
        :  value_() {}

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

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

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

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

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

    enum Max
    {
        MAX = THE_MAX
    };

    /** Converts @p str to an enum.
     * @throw illegal_enum_value @p str is not a legal identifier.
     * */
    void from_string(std::string const& str)
    {
        // TODO: Enum value strings with underscore are deprecated in Mapnik 3.x
        // and support will be removed in Mapnik 4.x.
        bool deprecated = false;
        std::string str_copy(str);
        if (str_copy.find('_') != std::string::npos)
        {
            std::replace(str_copy.begin(), str_copy.end(), '_', '-');
            deprecated = true;
        }
        for (unsigned i = 0; i < THE_MAX; ++i)
        {
            if (str_copy == our_strings_[i])
            {
                value_ = static_cast<ENUM>(i);
                if (deprecated)
                {
                    MAPNIK_LOG_ERROR(enumerations) << "enumeration value (" << str << ") using \"_\" is deprecated and will be removed in Mapnik 4.x, use '" << str_copy << "' instead";
                }
                return;
            }
        }
        throw illegal_enum_value(std::string("Illegal enumeration value '") +
                                 str + "' for enum " + our_name_);
    }

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

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

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

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

} // end of namespace

/** Helper macro.
 * @relates mapnik::enumeration
 */
#ifdef _MSC_VER
#define DEFINE_ENUM( name, e)                   \
    template enumeration<e, e ## _MAX>;         \
    using name = enumeration<e, e ## _MAX>;
#else
#define DEFINE_ENUM( name, e)                   \
    using name = enumeration<e, e ## _MAX>;
#endif

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

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

#endif // MAPNIK_ENUMERATION_HPP
<|endoftext|>


<commit_before>/** @file configs.hpp
 *
 * @copyright (C) 2016
 * @date 2016.03.07
 * @version 1.0.0
 * @author amir zamani <azadkuh@live.com>
 *
 */

#ifndef MBEDCRYPTO_CONFIGS_HPP
#define MBEDCRYPTO_CONFIGS_HPP

#include <memory>
#include <string>

#if defined(QT_CORE_LIB)
#include <QByteArray>
#endif // QT_CORE_LIB
///////////////////////////////////////////////////////////////////////////////
namespace mbedcrypto {

/// std::string is able to hold both TEXT and Binary data.
/// as encryption is frequently being used with both text strings and binaries,
///  std::string is more convenient than std::vector<unsigned char> or
///  std::basic_string<unsigned char>.
/// although std::vector<unsigned char> is a better options for binary contents.
using buffer_t = std::string;

// synonyms
using cuchars = const unsigned char*;
using uchars  = unsigned char*;

// helper function used internally
inline auto
to_const_ptr(const buffer_t& b) {
    return reinterpret_cast<cuchars>(b.data());
}

inline auto
to_ptr(buffer_t& b) {
    return reinterpret_cast<uchars>(&b.front());
}

#if defined(QT_CORE_LIB)
inline auto
to_const_ptr(const QByteArray& b) {
    return reinterpret_cast<cuchars>(b.data());
}

inline auto
to_ptr(QByteArray& b) {
    return reinterpret_cast<uchars>(b.data());
}
#endif // QT_CORE_LIB

///////////////////////////////////////////////////////////////////////////////
} // namespace mbedcrypto
///////////////////////////////////////////////////////////////////////////////
#endif // MBEDCRYPTO_CONFIGS_HPP
<commit_msg>introduce buffer_view_t<commit_after>/** @file configs.hpp
 *
 * @copyright (C) 2016
 * @date 2016.03.07
 * @version 1.0.0
 * @author amir zamani <azadkuh@live.com>
 *
 */

#ifndef MBEDCRYPTO_CONFIGS_HPP
#define MBEDCRYPTO_CONFIGS_HPP

#include <memory>
#include <string>

#if defined(QT_CORE_LIB)
#include <QByteArray>
#endif // QT_CORE_LIB
///////////////////////////////////////////////////////////////////////////////
namespace mbedcrypto {

/// std::string is able to hold both TEXT and Binary data.
/// as encryption is frequently being used with both text strings and binaries,
///  std::string is more convenient than std::vector<unsigned char> or
///  std::basic_string<unsigned char>.
/// although std::vector<unsigned char> is a better options for binary contents.
using buffer_t = std::string;

// synonyms
using cuchars = const unsigned char*;
using uchars  = unsigned char*;

// helper function used internally
inline auto
to_const_ptr(const buffer_t& b) {
    return reinterpret_cast<cuchars>(b.data());
}

inline auto
to_ptr(buffer_t& b) {
    return reinterpret_cast<uchars>(&b.front());
}

template<class T>
inline auto
to_const_ptr(const T& container) {
    return container.data();
}

template<class T>
inline auto
to_ptr(const T& container) {
    return &container.front();
}

#if defined(QT_CORE_LIB)
inline auto
to_const_ptr(const QByteArray& b) {
    return reinterpret_cast<cuchars>(b.data());
}

inline auto
to_ptr(QByteArray& b) {
    return reinterpret_cast<uchars>(b.data());
}

inline QByteArray
QByteArrayShallow(const buffer_t& src) {
    return QByteArray::fromRawData(src.data(), src.size());
}

inline QByteArray
QByteArrayShallow(cuchars src, size_t size) {
    return QByteArray::fromRawData(reinterpret_cast<const char*>(src), size);
}
#endif // QT_CORE_LIB

///////////////////////////////////////////////////////////////////////////////
/// a class similar to c++17 std::string_view
class buffer_view_t
{
    cuchars  data_ = nullptr;
    size_t   size_ = 0;

public:
    constexpr buffer_view_t(cuchars data, size_t length) noexcept
        : data_(data), size_(length) {}

    // T could be std::string, QByteArray or even an std::vector<uchar>
    template <class T>
    constexpr buffer_view_t(const T& src)
        : data_(to_const_ptr(src)), size_(src.length()) {}

    constexpr cuchars data() const noexcept {
        return data_;
    }

    constexpr size_t size() const noexcept {
        return size_;
    }

    constexpr size_t length() const noexcept {
        return size_;
    }

    constexpr bool empty() const noexcept {
        return size_ == 0;
    }

    // copyalbe, moveable
    ~buffer_view_t() = default;
    buffer_view_t()  = delete;
    buffer_view_t(const buffer_view_t&) = default;
    buffer_view_t(buffer_view_t&&)      = default;
    buffer_view_t& operator=(const buffer_view_t&) = default;
    buffer_view_t& operator=(buffer_view_t&&)      = default;
}; // buffer_view_t

///////////////////////////////////////////////////////////////////////////////
} // namespace mbedcrypto
///////////////////////////////////////////////////////////////////////////////
#endif // MBEDCRYPTO_CONFIGS_HPP
<|endoftext|>


<commit_before>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "QmitkTransferFunctionGeneratorWidget.h"

#include <mitkImageStatisticsHolder.h>
#include <mitkTransferFunctionProperty.h>
#include <mitkRenderingManager.h>
#include <mitkTransferFunctionInitializer.h>
#include <mitkUnstructuredGrid.h>
#include <QFileDialog>

#include <MitkSceneSerializationExports.h>
#include <mitkTransferFunctionPropertySerializer.h>

#include <vtkUnstructuredGrid.h>

QmitkTransferFunctionGeneratorWidget::QmitkTransferFunctionGeneratorWidget(QWidget* parent,
    Qt::WindowFlags f) :
  QWidget(parent, f), deltaScale(1.0), deltaMax(1024), deltaMin(1)
{
  histoGramm = NULL;

  this->setupUi(this);

  // LevelWindow Tab
  {
    connect( m_CrossLevelWindow, SIGNAL( SignalDeltaMove( int, int ) ), this, SLOT( OnDeltaLevelWindow( int, int ) ) );
  }

  // Threshold Tab
  {
    connect( m_CrossThreshold, SIGNAL( SignalDeltaMove( int, int ) ), this, SLOT( OnDeltaThreshold( int, int ) ) );
    thDelta = 100;
  }

  // Presets Tab
  {
    m_TransferFunctionComboBox->setVisible(false);

    connect( m_TransferFunctionComboBox, SIGNAL( activated( int ) ), this, SIGNAL(SignalTransferFunctionModeChanged(int)) );
    connect( m_TransferFunctionComboBox, SIGNAL( activated( int ) ), this, SLOT(OnPreset(int)) );

    connect( m_SavePreset, SIGNAL( clicked() ), this, SLOT( OnSavePreset() ) );

    connect( m_LoadPreset, SIGNAL( clicked() ), this, SLOT( OnLoadPreset() ) );
  }

  presetFileName = ".";
}

int QmitkTransferFunctionGeneratorWidget::AddPreset(const QString &presetName)
{
  m_TransferFunctionComboBox->setVisible(true);

  m_TransferFunctionComboBox->addItem( presetName);
  return m_TransferFunctionComboBox->count()-1;
}

void QmitkTransferFunctionGeneratorWidget::SetPresetsTabEnabled(bool enable)
{
  m_PresetTab->setEnabled(enable);
}

void QmitkTransferFunctionGeneratorWidget::SetThresholdTabEnabled(bool enable)
{
  m_ThresholdTab->setEnabled(enable);
}

void QmitkTransferFunctionGeneratorWidget::SetBellTabEnabled(bool enable)
{
  m_BellTab->setEnabled(enable);
}

void QmitkTransferFunctionGeneratorWidget::OnSavePreset( )
{
  if(tfpToChange.IsNull())
    return;

  mitk::TransferFunction::Pointer tf = tfpToChange->GetValue();

  std::string fileName;
  std::string fileNameOutput;

  presetFileName = QFileDialog::getSaveFileName( this,"Choose a filename to save the transferfunction",presetFileName, "Transferfunction (*.xml)" );

  fileName=presetFileName.toLocal8Bit().constData();

  MITK_INFO << "Saving Transferfunction under path: " << fileName;

  fileNameOutput= ReduceFileName(fileName);

  if ( mitk::TransferFunctionPropertySerializer::SerializeTransferFunction( fileName.c_str(),  tf ))
    m_InfoPreset->setText( QString( (std::string("saved ")+ fileNameOutput).c_str() ) );
  else
    m_InfoPreset->setText( QString( std::string("saving failed").c_str() ) );
}

void QmitkTransferFunctionGeneratorWidget::OnLoadPreset( )
{
  if(tfpToChange.IsNull())
    return;

  std::string fileName;
  std::string fileNameOutput;

  presetFileName = QFileDialog::getOpenFileName( this,"Choose a file to open the transferfunction from",presetFileName, "Transferfunction (*.xml)"  );

  fileName=presetFileName.toLocal8Bit().constData();

  MITK_INFO << "Loading Transferfunction from path: " << fileName;

  fileNameOutput= ReduceFileName(fileName);

  mitk::TransferFunction::Pointer tf = mitk::TransferFunctionPropertySerializer::DeserializeTransferFunction(fileName.c_str());

  if(tf.IsNotNull())
  {
    tfpToChange->SetValue( tf );

    m_InfoPreset->setText( QString( (std::string("loaded ")+ fileNameOutput).c_str() ) );
    mitk::RenderingManager::GetInstance()->RequestUpdateAll();
    emit SignalUpdateCanvas();
  }
}

void QmitkTransferFunctionGeneratorWidget::OnPreset(int mode)
{
  //first item is only information
  if( --mode == -1 )
    return;

  m_InfoPreset->setText(QString("selected ") + m_TransferFunctionComboBox->currentText());

  //revert to first item
  m_TransferFunctionComboBox->setCurrentIndex( 0 );
}

static double transformationGlocke ( double x )
{
  double z = 0.1;

  double a = 2 - 2 * z;

  double b = 2 * z - 1;

  x = a * x + b;

  return x;
}

static double stepFunctionGlocke ( double x )
{
  x = 1-(2*x -1.0); // map [0.5;1] to [0,1]
  x = x * ( 3*x - 2*x*x ); // apply smoothing function

  x = x * x;

  return x;
}

double QmitkTransferFunctionGeneratorWidget::ScaleDelta(int d) const
{
  return deltaScale*(double)d;
}

void QmitkTransferFunctionGeneratorWidget::OnDeltaLevelWindow(int dx, int dy) // bell
{
  if(tfpToChange.IsNull())
    return;

  thPos += ScaleDelta(dx);
  thDelta -= ScaleDelta(dy);

  if(thDelta < deltaMin)
    thDelta = deltaMin;

  if(thDelta > deltaMax)
    thDelta = deltaMax;

  if(thPos < histoMinimum)
    thPos = histoMinimum;

  if(thPos > histoMaximum)
    thPos = histoMaximum;

  std::stringstream ss;

  ss << "Click on the cross and move the mouse"<<"\n"
     <<"\n"
     << "center at " << thPos << "\n"
     << "width " << thDelta * 2;

  m_InfoLevelWindow->setText( QString( ss.str().c_str() ) );

  mitk::TransferFunction::Pointer tf = tfpToChange->GetValue();

  // grayvalue->opacity
  {
    vtkPiecewiseFunction *f=tf->GetScalarOpacityFunction();
    f->RemoveAllPoints();

    for( int r = 0; r<= 6; r++)
    {
      double relPos = (r / 6.0) * 0.5 + 0.5;
      f->AddPoint(thPos+thDelta*(-transformationGlocke(relPos)),stepFunctionGlocke(relPos));
      f->AddPoint(thPos+thDelta*( transformationGlocke(relPos)),stepFunctionGlocke(relPos));
    }

    f->Modified();
  }

  // gradient at grayvalue->opacity
  {
    vtkPiecewiseFunction *f=tf->GetGradientOpacityFunction();
    f->RemoveAllPoints();

    f->AddPoint( 0, 1.0 );
    f->Modified();
  }

  tf->Modified();

  mitk::RenderingManager::GetInstance()->RequestUpdateAll();
  emit SignalUpdateCanvas();
}

static double stepFunctionThreshold ( double x )
{
  x = 0.5*x + 0.5; // map [-1;1] to [0,1]
  x = x * ( 3*x - 2*x*x ); // apply smoothing function

  x = x * x;

  return x;
}

void QmitkTransferFunctionGeneratorWidget::OnDeltaThreshold(int dx, int dy) // LEVELWINDOW
{

  if(tfpToChange.IsNull())
    return;

  thPos += ScaleDelta(dx);
  thDelta += ScaleDelta(dy);

  if(thDelta < deltaMin)
    thDelta = deltaMin;

  if(thDelta > deltaMax)
    thDelta = deltaMax;

  if(thPos < histoMinimum)
    thPos = histoMinimum;

  if(thPos > histoMaximum)
    thPos = histoMaximum;

  std::stringstream ss;

  ss << "Click on the cross and move the mouse"<<"\n"
     <<"\n"
     << "threshold at " << thPos << "\n"
     << "width " << thDelta * 2;

  m_InfoThreshold->setText( QString( ss.str().c_str() ) );

  mitk::TransferFunction::Pointer tf = tfpToChange->GetValue();

  // grayvalue->opacity
  {
    vtkPiecewiseFunction *f=tf->GetScalarOpacityFunction();
    f->RemoveAllPoints();

    for( int r = 1; r<= 4; r++)
    {
      double relPos = r / 4.0;
      f->AddPoint(thPos+thDelta*(-relPos),stepFunctionThreshold(-relPos));
      f->AddPoint(thPos+thDelta*( relPos),stepFunctionThreshold( relPos));
    }
    f->Modified();
  }

  // gradient at grayvalue->opacity
  {
    vtkPiecewiseFunction *f=tf->GetGradientOpacityFunction();
    f->RemoveAllPoints();
    f->AddPoint( 0, 1.0 );
    f->Modified();
  }

  tf->Modified();
  mitk::RenderingManager::GetInstance()->RequestUpdateAll();
  emit SignalUpdateCanvas();

}

std::string QmitkTransferFunctionGeneratorWidget::ReduceFileName(std::string fileNameLong )
{
  if (fileNameLong.length()< 40)
    return fileNameLong;

  std::string fileNameShort;
  std::string fileNameRevert;

  for(unsigned int i=0; i< fileNameLong.length(); i++)
  {
    if(i<3)
    {
      char x= fileNameLong[i];
      fileNameShort= fileNameShort+x;
    }
    if(i==3)
    {
      fileNameShort= fileNameShort+"...";
      break;
    }
  }

  unsigned int len( fileNameLong.length() );
  for(unsigned int i=len-1; i <= len; i--)
  {
    std::string x=std::string("")+fileNameLong[i];

    if ( x.compare("/")==0 || x.compare("\\")==0)
    {
      fileNameRevert= "/" + fileNameRevert;
      break;
    }

    if (i>=fileNameLong.length()-24)
    {
      fileNameRevert= x+ fileNameRevert;
    }
    else
    {
      fileNameRevert= "/..." + fileNameRevert;
      break;
    }

  }

  return fileNameShort+fileNameRevert;
}

QmitkTransferFunctionGeneratorWidget::~QmitkTransferFunctionGeneratorWidget()
{
}

void QmitkTransferFunctionGeneratorWidget::SetDataNode(mitk::DataNode* node)
{
  histoGramm = NULL;

  if (node)
  {
    tfpToChange = dynamic_cast<mitk::TransferFunctionProperty*>(node->GetProperty("TransferFunction"));

    if(!tfpToChange)
    {
      node->SetProperty("TransferFunction", tfpToChange = mitk::TransferFunctionProperty::New() );
      dynamic_cast<mitk::TransferFunctionProperty*>(node->GetProperty("TransferFunction"));
    }

    mitk::TransferFunction::Pointer tf = tfpToChange->GetValue();

    if( mitk::Image* image = dynamic_cast<mitk::Image*>( node->GetData() ) )
    {
      mitk::ImageStatisticsHolder* statistics = image->GetStatistics();
      histoMinimum= statistics->GetScalarValueMin();
      histoMaximum= statistics->GetScalarValueMax();
    }
    else if (mitk::UnstructuredGrid* grid = dynamic_cast<mitk::UnstructuredGrid*>( node->GetData() ) )
    {
      double* range = grid->GetVtkUnstructuredGrid()->GetScalarRange();
      histoMinimum = range[0];
      histoMaximum = range[1];
      double histoRange = histoMaximum - histoMinimum;
      deltaMax = histoRange/4.0;
      deltaMin = histoRange/400.0;
      deltaScale = histoRange/1024.0;
    }
    else
    {
      MITK_WARN << "QmitkTransferFunctonGeneratorWidget does not support " << node->GetData()->GetNameOfClass() << " instances";
    }

    thPos = ( histoMinimum + histoMaximum ) / 2.0;

  }
  else
  {
    tfpToChange = 0;
    m_InfoPreset->setText( QString( "" ) );

  }
}

<commit_msg>Fixed more QtWidgetsExt warnings.<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "QmitkTransferFunctionGeneratorWidget.h"

#include <mitkImageStatisticsHolder.h>
#include <mitkTransferFunctionProperty.h>
#include <mitkRenderingManager.h>
#include <mitkTransferFunctionInitializer.h>
#include <mitkUnstructuredGrid.h>
#include <QFileDialog>

#include <MitkSceneSerializationExports.h>
#include <mitkTransferFunctionPropertySerializer.h>

#include <vtkUnstructuredGrid.h>

QmitkTransferFunctionGeneratorWidget::QmitkTransferFunctionGeneratorWidget(QWidget* parent,
    Qt::WindowFlags f) :
  QWidget(parent, f), deltaScale(1.0), deltaMax(1024), deltaMin(1)
{
  histoGramm = NULL;

  this->setupUi(this);

  // LevelWindow Tab
  {
    connect( m_CrossLevelWindow, SIGNAL( SignalDeltaMove( int, int ) ), this, SLOT( OnDeltaLevelWindow( int, int ) ) );
  }

  // Threshold Tab
  {
    connect( m_CrossThreshold, SIGNAL( SignalDeltaMove( int, int ) ), this, SLOT( OnDeltaThreshold( int, int ) ) );
    thDelta = 100;
  }

  // Presets Tab
  {
    m_TransferFunctionComboBox->setVisible(false);

    connect( m_TransferFunctionComboBox, SIGNAL( activated( int ) ), this, SIGNAL(SignalTransferFunctionModeChanged(int)) );
    connect( m_TransferFunctionComboBox, SIGNAL( activated( int ) ), this, SLOT(OnPreset(int)) );

    connect( m_SavePreset, SIGNAL( clicked() ), this, SLOT( OnSavePreset() ) );

    connect( m_LoadPreset, SIGNAL( clicked() ), this, SLOT( OnLoadPreset() ) );
  }

  presetFileName = ".";
}

int QmitkTransferFunctionGeneratorWidget::AddPreset(const QString &presetName)
{
  m_TransferFunctionComboBox->setVisible(true);

  m_TransferFunctionComboBox->addItem( presetName);
  return m_TransferFunctionComboBox->count()-1;
}

void QmitkTransferFunctionGeneratorWidget::SetPresetsTabEnabled(bool enable)
{
  m_PresetTab->setEnabled(enable);
}

void QmitkTransferFunctionGeneratorWidget::SetThresholdTabEnabled(bool enable)
{
  m_ThresholdTab->setEnabled(enable);
}

void QmitkTransferFunctionGeneratorWidget::SetBellTabEnabled(bool enable)
{
  m_BellTab->setEnabled(enable);
}

void QmitkTransferFunctionGeneratorWidget::OnSavePreset( )
{
  if(tfpToChange.IsNull())
    return;

  mitk::TransferFunction::Pointer tf = tfpToChange->GetValue();

  std::string fileName;
  std::string fileNameOutput;

  presetFileName = QFileDialog::getSaveFileName( this,"Choose a filename to save the transferfunction",presetFileName, "Transferfunction (*.xml)" );

  fileName=presetFileName.toLocal8Bit().constData();

  MITK_INFO << "Saving Transferfunction under path: " << fileName;

  fileNameOutput= ReduceFileName(fileName);

  if ( mitk::TransferFunctionPropertySerializer::SerializeTransferFunction( fileName.c_str(),  tf ))
    m_InfoPreset->setText( QString( (std::string("saved ")+ fileNameOutput).c_str() ) );
  else
    m_InfoPreset->setText( QString( std::string("saving failed").c_str() ) );
}

void QmitkTransferFunctionGeneratorWidget::OnLoadPreset( )
{
  if(tfpToChange.IsNull())
    return;

  std::string fileName;
  std::string fileNameOutput;

  presetFileName = QFileDialog::getOpenFileName( this,"Choose a file to open the transferfunction from",presetFileName, "Transferfunction (*.xml)"  );

  fileName=presetFileName.toLocal8Bit().constData();

  MITK_INFO << "Loading Transferfunction from path: " << fileName;

  fileNameOutput= ReduceFileName(fileName);

  mitk::TransferFunction::Pointer tf = mitk::TransferFunctionPropertySerializer::DeserializeTransferFunction(fileName.c_str());

  if(tf.IsNotNull())
  {
    tfpToChange->SetValue( tf );

    m_InfoPreset->setText( QString( (std::string("loaded ")+ fileNameOutput).c_str() ) );
    mitk::RenderingManager::GetInstance()->RequestUpdateAll();
    emit SignalUpdateCanvas();
  }
}

void QmitkTransferFunctionGeneratorWidget::OnPreset(int mode)
{
  //first item is only information
  if( --mode == -1 )
    return;

  m_InfoPreset->setText(QString("selected ") + m_TransferFunctionComboBox->currentText());

  //revert to first item
  m_TransferFunctionComboBox->setCurrentIndex( 0 );
}

static double transformationGlocke ( double x )
{
  double z = 0.1;

  double a = 2 - 2 * z;

  double b = 2 * z - 1;

  x = a * x + b;

  return x;
}

static double stepFunctionGlocke ( double x )
{
  x = 1-(2*x -1.0); // map [0.5;1] to [0,1]
  x = x * ( 3*x - 2*x*x ); // apply smoothing function

  x = x * x;

  return x;
}

double QmitkTransferFunctionGeneratorWidget::ScaleDelta(int d) const
{
  return deltaScale*(double)d;
}

void QmitkTransferFunctionGeneratorWidget::OnDeltaLevelWindow(int dx, int dy) // bell
{
  if(tfpToChange.IsNull())
    return;

  thPos += ScaleDelta(dx);
  thDelta -= ScaleDelta(dy);

  if(thDelta < deltaMin)
    thDelta = deltaMin;

  if(thDelta > deltaMax)
    thDelta = deltaMax;

  if(thPos < histoMinimum)
    thPos = histoMinimum;

  if(thPos > histoMaximum)
    thPos = histoMaximum;

  std::stringstream ss;

  ss << "Click on the cross and move the mouse"<<"\n"
     <<"\n"
     << "center at " << thPos << "\n"
     << "width " << thDelta * 2;

  m_InfoLevelWindow->setText( QString( ss.str().c_str() ) );

  mitk::TransferFunction::Pointer tf = tfpToChange->GetValue();

  // grayvalue->opacity
  {
    vtkPiecewiseFunction *f=tf->GetScalarOpacityFunction();
    f->RemoveAllPoints();

    for( int r = 0; r<= 6; r++)
    {
      double relPos = (r / 6.0) * 0.5 + 0.5;
      f->AddPoint(thPos+thDelta*(-transformationGlocke(relPos)),stepFunctionGlocke(relPos));
      f->AddPoint(thPos+thDelta*( transformationGlocke(relPos)),stepFunctionGlocke(relPos));
    }

    f->Modified();
  }

  // gradient at grayvalue->opacity
  {
    vtkPiecewiseFunction *f=tf->GetGradientOpacityFunction();
    f->RemoveAllPoints();

    f->AddPoint( 0, 1.0 );
    f->Modified();
  }

  tf->Modified();

  mitk::RenderingManager::GetInstance()->RequestUpdateAll();
  emit SignalUpdateCanvas();
}

static double stepFunctionThreshold ( double x )
{
  x = 0.5*x + 0.5; // map [-1;1] to [0,1]
  x = x * ( 3*x - 2*x*x ); // apply smoothing function

  x = x * x;

  return x;
}

void QmitkTransferFunctionGeneratorWidget::OnDeltaThreshold(int dx, int dy) // LEVELWINDOW
{

  if(tfpToChange.IsNull())
    return;

  thPos += ScaleDelta(dx);
  thDelta += ScaleDelta(dy);

  if(thDelta < deltaMin)
    thDelta = deltaMin;

  if(thDelta > deltaMax)
    thDelta = deltaMax;

  if(thPos < histoMinimum)
    thPos = histoMinimum;

  if(thPos > histoMaximum)
    thPos = histoMaximum;

  std::stringstream ss;

  ss << "Click on the cross and move the mouse"<<"\n"
     <<"\n"
     << "threshold at " << thPos << "\n"
     << "width " << thDelta * 2;

  m_InfoThreshold->setText( QString( ss.str().c_str() ) );

  mitk::TransferFunction::Pointer tf = tfpToChange->GetValue();

  // grayvalue->opacity
  {
    vtkPiecewiseFunction *f=tf->GetScalarOpacityFunction();
    f->RemoveAllPoints();

    for( int r = 1; r<= 4; r++)
    {
      double relPos = r / 4.0;
      f->AddPoint(thPos+thDelta*(-relPos),stepFunctionThreshold(-relPos));
      f->AddPoint(thPos+thDelta*( relPos),stepFunctionThreshold( relPos));
    }
    f->Modified();
  }

  // gradient at grayvalue->opacity
  {
    vtkPiecewiseFunction *f=tf->GetGradientOpacityFunction();
    f->RemoveAllPoints();
    f->AddPoint( 0, 1.0 );
    f->Modified();
  }

  tf->Modified();
  mitk::RenderingManager::GetInstance()->RequestUpdateAll();
  emit SignalUpdateCanvas();

}

std::string QmitkTransferFunctionGeneratorWidget::ReduceFileName(std::string fileNameLong )
{
  if (fileNameLong.length()< 40)
    return fileNameLong;

  std::string fileNameShort;
  std::string fileNameRevert;

  for(unsigned int i=0; i< fileNameLong.length(); i++)
  {
    if(i<3)
    {
      char x= fileNameLong[i];
      fileNameShort= fileNameShort+x;
    }
    if(i==3)
    {
      fileNameShort= fileNameShort+"...";
      break;
    }
  }

  unsigned int len( fileNameLong.length() );
  for(unsigned int i=len-1; i <= len; i--)
  {
    std::string x=std::string("")+fileNameLong[i];

    if ( x.compare("/")==0 || x.compare("\\")==0)
    {
      fileNameRevert= "/" + fileNameRevert;
      break;
    }

    if (i>=fileNameLong.length()-24)
    {
      fileNameRevert= x+ fileNameRevert;
    }
    else
    {
      fileNameRevert= "/..." + fileNameRevert;
      break;
    }

  }

  return fileNameShort+fileNameRevert;
}

QmitkTransferFunctionGeneratorWidget::~QmitkTransferFunctionGeneratorWidget()
{
}

void QmitkTransferFunctionGeneratorWidget::SetDataNode(mitk::DataNode* node)
{
  histoGramm = NULL;

  if (node)
  {
    tfpToChange = dynamic_cast<mitk::TransferFunctionProperty*>(node->GetProperty("TransferFunction"));

    if(!tfpToChange)
      node->SetProperty("TransferFunction", tfpToChange = mitk::TransferFunctionProperty::New() );

    mitk::TransferFunction::Pointer tf = tfpToChange->GetValue();

    if( mitk::Image* image = dynamic_cast<mitk::Image*>( node->GetData() ) )
    {
      mitk::ImageStatisticsHolder* statistics = image->GetStatistics();
      histoMinimum= statistics->GetScalarValueMin();
      histoMaximum= statistics->GetScalarValueMax();
    }
    else if (mitk::UnstructuredGrid* grid = dynamic_cast<mitk::UnstructuredGrid*>( node->GetData() ) )
    {
      double* range = grid->GetVtkUnstructuredGrid()->GetScalarRange();
      histoMinimum = range[0];
      histoMaximum = range[1];
      double histoRange = histoMaximum - histoMinimum;
      deltaMax = histoRange/4.0;
      deltaMin = histoRange/400.0;
      deltaScale = histoRange/1024.0;
    }
    else
    {
      MITK_WARN << "QmitkTransferFunctonGeneratorWidget does not support " << node->GetData()->GetNameOfClass() << " instances";
    }

    thPos = ( histoMinimum + histoMaximum ) / 2.0;

  }
  else
  {
    tfpToChange = 0;
    m_InfoPreset->setText( QString( "" ) );

  }
}

<|endoftext|>


<commit_before>#pragma once

#include <utility>
#include <type_traits>
#include <string>

#include "any.hpp"
#include <type_list.hpp>
#include <function_deduction.hpp>
#include <member_variable_deduction.hpp>
#include <void_t.hpp>

namespace shadow
{
// free function signature
typedef any (*free_function_binding_signature)(any*);
// member function signature
typedef any (*member_function_binding_signature)(any&, any*);
// member variable getter
typedef any (*member_variable_get_binding_signature)(const any&);
// member variable setter
typedef void (*member_variable_set_binding_signature)(any&, const any&);
// constructor signature
typedef any (*constructor_binding_signature)(any*);
// conversion signature
typedef any (*conversion_binding_signature)(const any&);
// string serialize signature
typedef std::string (*string_serialization_signature)(const any&);
// string deserialization signature
typedef any (*string_deserialization_signature)(const std::string&);

////////////////////////////////////////////////////////////////////////////////
// generic bind point for free functions
// has the same signature as function pointer free_function_binding_signature
// which can be stored in the free_function_info struct

namespace free_function_detail
{
// necessary to handle void as return type differently when calling underlying
// free function
template <class ReturnType>
struct return_type_specializer
{
    // dispatch: unpacks argument type list and sequence to correctly index into
    // argument array and call get with the right types to retrieve raw values
    // from the anys
    template <class FunctionPointerType,
              FunctionPointerType FunctionPointerValue,
              class... ArgTypes,
              std::size_t... ArgSeq>
    static any
    dispatch(any* argument_array,
             metamusil::t_list::type_list<ArgTypes...>,
             std::index_sequence<ArgSeq...>)
    {
        // necessary to remove reference from types as any only stores
        // unqualified types, ie values only
        return FunctionPointerValue(
            argument_array[ArgSeq]
                .get<typename std::remove_reference_t<ArgTypes>>()...);
    }
};

template <>
struct return_type_specializer<void>
{
    // dispatch: unpacks argument type list and sequence to correctly index into
    // argument array and call get with the right types to retrieve raw values
    // from the anys
    template <class FunctionPointerType,
              FunctionPointerType FunctionPointerValue,
              class... ArgTypes,
              std::size_t... ArgSeq>
    static any
    dispatch(any* argument_array,
             metamusil::t_list::type_list<ArgTypes...>,
             std::index_sequence<ArgSeq...>)
    {
        // necessary to remove reference from types as any only stores
        // unqualified types, ie values only
        FunctionPointerValue(
            argument_array[ArgSeq]
                .get<typename std::remove_reference_t<ArgTypes>>()...);

        // return empty any, ie 'void'
        return any();
    }
};

// the value of the function pointer is stored at runtime in the template
// overload set
// this enables any function to be wrapped into uniform function signature that
// can be stored homogenously at runtime
template <class FunctionPointerType, FunctionPointerType FunctionPointerValue>
any
generic_free_function_bind_point(any* argument_array)
{
    typedef metamusil::deduce_return_type_t<FunctionPointerType> return_type;
    typedef metamusil::deduce_parameter_types_t<FunctionPointerType>
        parameter_types;
    // make integer sequence from type list
    typedef metamusil::t_list::index_sequence_for_t<parameter_types>
        parameter_sequence;

    return return_type_specializer<return_type>::
        template dispatch<FunctionPointerType, FunctionPointerValue>(
            argument_array, parameter_types(), parameter_sequence());
}
}

namespace member_function_detail
{

template <class ReturnType>
struct return_type_specializer
{
    template <class MemFunPointerType,
              MemFunPointerType MemFunPointerValue,
              class ObjectType,
              class... ParamTypes,
              std::size_t... ParamSequence>
    static any
    dispatch(any& object,
             any* argument_array,
             metamusil::t_list::type_list<ParamTypes...>,
             std::index_sequence<ParamSequence...>)
    {
        return (object.get<ObjectType>().*MemFunPointerValue)(
            argument_array[ParamSequence]
                .get<std::remove_reference_t<ParamTypes>>()...);
    }
};

template <>
struct return_type_specializer<void>
{
    template <class MemFunPointerType,
              MemFunPointerType MemFunPointerValue,
              class ObjectType,
              class... ParamTypes,
              std::size_t... ParamSequence>
    static any
    dispatch(any& object,
             any* argument_array,
             metamusil::t_list::type_list<ParamTypes...>,
             std::index_sequence<ParamSequence...>)
    {
        (object.get<ObjectType>().*MemFunPointerValue)(
            argument_array[ParamSequence]
                .get<std::remove_reference_t<ParamTypes>>()...);

        return any();
    }
};

template <class MemFunPointerType, MemFunPointerType MemFunPointerValue>
any
generic_member_function_bind_point(any& object, any* argument_array)
{
    // deduce return type
    typedef metamusil::deduce_return_type_t<MemFunPointerType> return_type;

    // deduce parameter types
    typedef metamusil::deduce_parameter_types_t<MemFunPointerType>
        parameter_types;

    // make integer sequence from parameter type list
    typedef metamusil::t_list::index_sequence_for_t<parameter_types>
        parameter_sequence;

    // deduce object type
    typedef metamusil::deduce_object_type_t<MemFunPointerType> object_type;

    return return_type_specializer<return_type>::
        template dispatch<MemFunPointerType, MemFunPointerValue, object_type>(
            object, argument_array, parameter_types(), parameter_sequence());
}
}

namespace member_variable_detail
{

template <class MemVarPointerType,
          MemVarPointerType MemVarPointerValue,
          class ObjectType,
          class MemVarType>
any
get_dispatch(const any& object)
{
    return (object.get<ObjectType>().*MemVarPointerValue);
}

template <class MemVarPointerType,
          MemVarPointerType MemVarPointerValue,
          class ObjectType,
          class MemVarType>
void
set_dispatch(any& object, const any& value)
{
    (object.get<ObjectType>().*MemVarPointerValue) = value.get<MemVarType>();
}

template <class MemVarPointerType, MemVarPointerType MemVarPointerValue>
any
generic_member_variable_get_bind_point(const any& object)
{
    typedef metamusil::deduce_member_variable_object_type_t<MemVarPointerType>
        object_type;
    typedef metamusil::deduce_member_variable_type_t<MemVarPointerType>
        member_variable_type;

    return get_dispatch<MemVarPointerType,
                        MemVarPointerValue,
                        object_type,
                        member_variable_type>(object);
}

template <class MemVarPointerType, MemVarPointerType MemVarPointerValue>
void
generic_member_variable_set_bind_point(any& object, const any& value)
{
    typedef metamusil::deduce_member_variable_object_type_t<MemVarPointerType>
        object_type;
    typedef metamusil::deduce_member_variable_type_t<MemVarPointerType>
        member_variable_type;

    return set_dispatch<MemVarPointerType,
                        MemVarPointerValue,
                        object_type,
                        member_variable_type>(object, value);
}
}

namespace constructor_detail
{

// purpose of braced_init_selector is to attempt to use constructor T(...) if
// available, otherwise fall back to braced init list initialization
template <class, class T, class... ParamTypes>
struct braced_init_selector_impl
{
    template <std::size_t... Seq>
    static any
    constructor_dispatch(any* argument_array, std::index_sequence<Seq...>)
    {
        any out = T{argument_array[Seq].get<ParamTypes>()...};
        return out;
    }
};

template <class T, class... ParamTypes>
struct braced_init_selector_impl<
    metamusil::void_t<decltype(T(std::declval<ParamTypes>()...))>,
    T,
    ParamTypes...>
{
    template <std::size_t... Seq>
    static any
    constructor_dispatch(any* argument_array, std::index_sequence<Seq...>)
    {
        any out = T(argument_array[Seq].get<ParamTypes>()...);
        return out;
    }
};

template <class T, class... ParamTypes>
using braced_init_selector = braced_init_selector_impl<void, T, ParamTypes...>;

template <class T, class... ParamTypes>
any
generic_constructor_bind_point(any* argument_array)
{
    typedef std::index_sequence_for<ParamTypes...> param_sequence;

    return braced_init_selector<T, ParamTypes...>::constructor_dispatch(
        argument_array, param_sequence());
}
}

namespace conversion_detail
{
template <class TargetType, class SourceType, class = void>
struct conversion_specializer;

template <>
struct conversion_specializer<void, void>;

template <class TargetType, class SourceType>
struct conversion_specializer<
    TargetType,
    SourceType,
    std::enable_if_t<std::is_convertible<SourceType, TargetType>::value>>
{
    static any
    dispatch(const any& src)
    {
        TargetType temp = (TargetType)src.get<SourceType>();
        return temp;
    }
};

template <class TargetType, class SourceType>
any
generic_conversion_bind_point(const any& src)
{
    return conversion_specializer<TargetType, SourceType>::dispatch(src);
}
}

namespace string_serialization_detail
{

template <class T, class = void>
struct type_selector;

template <class T>
struct type_selector<T, std::enable_if_t<std::is_arithmetic<T>::value>>
{
    static std::string
    serialize_dispatch(const any& value)
    {
        std::to_string(value.get<T>());
    }
};

template <class T>
std::string
generic_string_serialization_bind_point(const any& value)
{
    return type_selector<T>::serialize_dispatch(value);
}
}
}
<commit_msg>Rename. 	modified:   include/reflection_binding.hpp<commit_after>#pragma once

#include <utility>
#include <type_traits>
#include <string>

#include "any.hpp"
#include <type_list.hpp>
#include <function_deduction.hpp>
#include <member_variable_deduction.hpp>
#include <void_t.hpp>

namespace shadow
{
// free function signature
typedef any (*free_function_binding_signature)(any*);
// member function signature
typedef any (*member_function_binding_signature)(any&, any*);
// member variable getter
typedef any (*member_variable_get_binding_signature)(const any&);
// member variable setter
typedef void (*member_variable_set_binding_signature)(any&, const any&);
// constructor signature
typedef any (*constructor_binding_signature)(any*);
// conversion signature
typedef any (*conversion_binding_signature)(const any&);
// string serialize signature
typedef std::string (*string_serialization_signature)(const any&);
// string deserialization signature
typedef any (*string_deserialization_signature)(const std::string&);

////////////////////////////////////////////////////////////////////////////////
// generic bind point for free functions
// has the same signature as function pointer free_function_binding_signature
// which can be stored in the free_function_info struct

namespace free_function_detail
{
// necessary to handle void as return type differently when calling underlying
// free function
template <class ReturnType>
struct return_type_specializer
{
    // dispatch: unpacks argument type list and sequence to correctly index into
    // argument array and call get with the right types to retrieve raw values
    // from the anys
    template <class FunctionPointerType,
              FunctionPointerType FunctionPointerValue,
              class... ArgTypes,
              std::size_t... ArgSeq>
    static any
    dispatch(any* argument_array,
             metamusil::t_list::type_list<ArgTypes...>,
             std::index_sequence<ArgSeq...>)
    {
        // necessary to remove reference from types as any only stores
        // unqualified types, ie values only
        return FunctionPointerValue(
            argument_array[ArgSeq]
                .get<typename std::remove_reference_t<ArgTypes>>()...);
    }
};

template <>
struct return_type_specializer<void>
{
    // dispatch: unpacks argument type list and sequence to correctly index into
    // argument array and call get with the right types to retrieve raw values
    // from the anys
    template <class FunctionPointerType,
              FunctionPointerType FunctionPointerValue,
              class... ArgTypes,
              std::size_t... ArgSeq>
    static any
    dispatch(any* argument_array,
             metamusil::t_list::type_list<ArgTypes...>,
             std::index_sequence<ArgSeq...>)
    {
        // necessary to remove reference from types as any only stores
        // unqualified types, ie values only
        FunctionPointerValue(
            argument_array[ArgSeq]
                .get<typename std::remove_reference_t<ArgTypes>>()...);

        // return empty any, ie 'void'
        return any();
    }
};

// the value of the function pointer is stored at runtime in the template
// overload set
// this enables any function to be wrapped into uniform function signature that
// can be stored homogenously at runtime
template <class FunctionPointerType, FunctionPointerType FunctionPointerValue>
any
generic_free_function_bind_point(any* argument_array)
{
    typedef metamusil::deduce_return_type_t<FunctionPointerType> return_type;
    typedef metamusil::deduce_parameter_types_t<FunctionPointerType>
        parameter_types;
    // make integer sequence from type list
    typedef metamusil::t_list::index_sequence_for_t<parameter_types>
        parameter_sequence;

    return return_type_specializer<return_type>::
        template dispatch<FunctionPointerType, FunctionPointerValue>(
            argument_array, parameter_types(), parameter_sequence());
}
}

namespace member_function_detail
{

template <class ReturnType>
struct return_type_specializer
{
    template <class MemFunPointerType,
              MemFunPointerType MemFunPointerValue,
              class ObjectType,
              class... ParamTypes,
              std::size_t... ParamSequence>
    static any
    dispatch(any& object,
             any* argument_array,
             metamusil::t_list::type_list<ParamTypes...>,
             std::index_sequence<ParamSequence...>)
    {
        return (object.get<ObjectType>().*MemFunPointerValue)(
            argument_array[ParamSequence]
                .get<std::remove_reference_t<ParamTypes>>()...);
    }
};

template <>
struct return_type_specializer<void>
{
    template <class MemFunPointerType,
              MemFunPointerType MemFunPointerValue,
              class ObjectType,
              class... ParamTypes,
              std::size_t... ParamSequence>
    static any
    dispatch(any& object,
             any* argument_array,
             metamusil::t_list::type_list<ParamTypes...>,
             std::index_sequence<ParamSequence...>)
    {
        (object.get<ObjectType>().*MemFunPointerValue)(
            argument_array[ParamSequence]
                .get<std::remove_reference_t<ParamTypes>>()...);

        return any();
    }
};

template <class MemFunPointerType, MemFunPointerType MemFunPointerValue>
any
generic_member_function_bind_point(any& object, any* argument_array)
{
    // deduce return type
    typedef metamusil::deduce_return_type_t<MemFunPointerType> return_type;

    // deduce parameter types
    typedef metamusil::deduce_parameter_types_t<MemFunPointerType>
        parameter_types;

    // make integer sequence from parameter type list
    typedef metamusil::t_list::index_sequence_for_t<parameter_types>
        parameter_sequence;

    // deduce object type
    typedef metamusil::deduce_object_type_t<MemFunPointerType> object_type;

    return return_type_specializer<return_type>::
        template dispatch<MemFunPointerType, MemFunPointerValue, object_type>(
            object, argument_array, parameter_types(), parameter_sequence());
}
}

namespace member_variable_detail
{

template <class MemVarPointerType,
          MemVarPointerType MemVarPointerValue,
          class ObjectType,
          class MemVarType>
any
get_dispatch(const any& object)
{
    return (object.get<ObjectType>().*MemVarPointerValue);
}

template <class MemVarPointerType,
          MemVarPointerType MemVarPointerValue,
          class ObjectType,
          class MemVarType>
void
set_dispatch(any& object, const any& value)
{
    (object.get<ObjectType>().*MemVarPointerValue) = value.get<MemVarType>();
}

template <class MemVarPointerType, MemVarPointerType MemVarPointerValue>
any
generic_member_variable_get_bind_point(const any& object)
{
    typedef metamusil::deduce_member_variable_object_type_t<MemVarPointerType>
        object_type;
    typedef metamusil::deduce_member_variable_type_t<MemVarPointerType>
        member_variable_type;

    return get_dispatch<MemVarPointerType,
                        MemVarPointerValue,
                        object_type,
                        member_variable_type>(object);
}

template <class MemVarPointerType, MemVarPointerType MemVarPointerValue>
void
generic_member_variable_set_bind_point(any& object, const any& value)
{
    typedef metamusil::deduce_member_variable_object_type_t<MemVarPointerType>
        object_type;
    typedef metamusil::deduce_member_variable_type_t<MemVarPointerType>
        member_variable_type;

    return set_dispatch<MemVarPointerType,
                        MemVarPointerValue,
                        object_type,
                        member_variable_type>(object, value);
}
}

namespace constructor_detail
{

// purpose of braced_init_selector is to attempt to use constructor T(...) if
// available, otherwise fall back to braced init list initialization
template <class, class T, class... ParamTypes>
struct braced_init_selector_impl
{
    template <std::size_t... Seq>
    static any
    constructor_dispatch(any* argument_array, std::index_sequence<Seq...>)
    {
        any out = T{argument_array[Seq].get<ParamTypes>()...};
        return out;
    }
};

template <class T, class... ParamTypes>
struct braced_init_selector_impl<
    metamusil::void_t<decltype(T(std::declval<ParamTypes>()...))>,
    T,
    ParamTypes...>
{
    template <std::size_t... Seq>
    static any
    constructor_dispatch(any* argument_array, std::index_sequence<Seq...>)
    {
        any out = T(argument_array[Seq].get<ParamTypes>()...);
        return out;
    }
};

template <class T, class... ParamTypes>
using braced_init_selector = braced_init_selector_impl<void, T, ParamTypes...>;

template <class T, class... ParamTypes>
any
generic_constructor_bind_point(any* argument_array)
{
    typedef std::index_sequence_for<ParamTypes...> param_sequence;

    return braced_init_selector<T, ParamTypes...>::constructor_dispatch(
        argument_array, param_sequence());
}
}

namespace conversion_detail
{
template <class TargetType, class SourceType, class = void>
struct conversion_specializer;

template <>
struct conversion_specializer<void, void>;

template <class TargetType, class SourceType>
struct conversion_specializer<
    TargetType,
    SourceType,
    std::enable_if_t<std::is_convertible<SourceType, TargetType>::value>>
{
    static any
    dispatch(const any& src)
    {
        TargetType temp = (TargetType)src.get<SourceType>();
        return temp;
    }
};

template <class TargetType, class SourceType>
any
generic_conversion_bind_point(const any& src)
{
    return conversion_specializer<TargetType, SourceType>::dispatch(src);
}
}

namespace string_serialization_detail
{

template <class T, class = void>
struct string_serialize_type_selector;

template <class T>
struct string_serialize_type_selector<
    T,
    std::enable_if_t<std::is_arithmetic<T>::value>>
{
    static std::string
    dispatch(const any& value)
    {
        return std::to_string(value.get<T>());
    }
};

template <class T>
std::string
generic_string_serialization_bind_point(const any& value)
{
    return type_selector<T>::serialize_dispatch(value);
}
}
}
<|endoftext|>


<commit_before>#ifndef REFLECTION_BINDING_HPP
#define REFLECTION_BINDING_HPP

#include <string>
#include <type_traits>
#include <utility>

#include "any.hpp"
#include <function_deduction.hpp>
#include <member_variable_deduction.hpp>
#include <type_list.hpp>
#include <void_t.hpp>

namespace shadow
{
// free function signature
typedef any (*free_function_binding_signature)(any*);
// member function signature
typedef any (*member_function_binding_signature)(any&, any*);
// member variable getter
typedef any (*member_variable_get_binding_signature)(const any&);
// member variable setter
typedef void (*member_variable_set_binding_signature)(any&, const any&);
// constructor signature
typedef any (*constructor_binding_signature)(any*);
// conversion signature
typedef any (*conversion_binding_signature)(const any&);
// string serialize signature
typedef std::string (*string_serialization_signature)(const any&);
// string deserialization signature
typedef any (*string_deserialization_signature)(const std::string&);
// address of signature
typedef any (*address_of_signature)(any&);
// dereference signature
typedef any (*dereference_signature)(any&);

////////////////////////////////////////////////////////////////////////////////
// generic bind point for free functions
// has the same signature as function pointer free_function_binding_signature
// which can be stored in the free_function_info struct

namespace free_function_detail
{
// necessary to handle void as return type differently when calling underlying
// free function
template <class ReturnType>
struct return_type_specializer
{
    // dispatch: unpacks argument type list and sequence to correctly index into
    // argument array and call get with the right types to retrieve raw values
    // from the anys
    template <class FunctionPointerType,
              FunctionPointerType FunctionPointerValue,
              class... ArgTypes,
              std::size_t... ArgSeq>
    static any
    dispatch(any* argument_array,
             metamusil::t_list::type_list<ArgTypes...>,
             std::index_sequence<ArgSeq...>)
    {
        // necessary to remove reference from types as any only stores
        // unqualified types, ie values only
        return FunctionPointerValue(
            argument_array[ArgSeq]
                .get<typename std::remove_reference_t<ArgTypes>>()...);
    }
};

template <>
struct return_type_specializer<void>
{
    // dispatch: unpacks argument type list and sequence to correctly index into
    // argument array and call get with the right types to retrieve raw values
    // from the anys
    template <class FunctionPointerType,
              FunctionPointerType FunctionPointerValue,
              class... ArgTypes,
              std::size_t... ArgSeq>
    static any
    dispatch(any* argument_array,
             metamusil::t_list::type_list<ArgTypes...>,
             std::index_sequence<ArgSeq...>)
    {
        // necessary to remove reference from types as any only stores
        // unqualified types, ie values only
        FunctionPointerValue(
            argument_array[ArgSeq]
                .get<typename std::remove_reference_t<ArgTypes>>()...);

        // return empty any, ie 'void'
        return any();
    }
};

// the value of the function pointer is stored at runtime in the template
// overload set
// this enables any function to be wrapped into uniform function signature that
// can be stored homogenously at runtime
template <class FunctionPointerType, FunctionPointerType FunctionPointerValue>
any
generic_free_function_bind_point(any* argument_array)
{
    typedef metamusil::deduce_return_type_t<FunctionPointerType> return_type;
    typedef metamusil::deduce_parameter_types_t<FunctionPointerType>
        parameter_types;
    // make integer sequence from type list
    typedef metamusil::t_list::index_sequence_for_t<parameter_types>
        parameter_sequence;

    return return_type_specializer<return_type>::
        template dispatch<FunctionPointerType, FunctionPointerValue>(
            argument_array, parameter_types(), parameter_sequence());
}
} // namespace free_function_detail

namespace member_function_detail
{

template <class ReturnType>
struct return_type_specializer
{
    template <class MemFunPointerType,
              MemFunPointerType MemFunPointerValue,
              class ObjectType,
              class... ParamTypes,
              std::size_t... ParamSequence>
    static any
    dispatch(any& object,
             any* argument_array,
             metamusil::t_list::type_list<ParamTypes...>,
             std::index_sequence<ParamSequence...>)
    {
        return (object.get<ObjectType>().*MemFunPointerValue)(
            argument_array[ParamSequence]
                .get<std::remove_reference_t<ParamTypes>>()...);
    }
};

template <>
struct return_type_specializer<void>
{
    template <class MemFunPointerType,
              MemFunPointerType MemFunPointerValue,
              class ObjectType,
              class... ParamTypes,
              std::size_t... ParamSequence>
    static any
    dispatch(any& object,
             any* argument_array,
             metamusil::t_list::type_list<ParamTypes...>,
             std::index_sequence<ParamSequence...>)
    {
        (object.get<ObjectType>().*MemFunPointerValue)(
            argument_array[ParamSequence]
                .get<std::remove_reference_t<ParamTypes>>()...);

        return any();
    }
};

template <class MemFunPointerType, MemFunPointerType MemFunPointerValue>
any
generic_member_function_bind_point(any& object, any* argument_array)
{
    // deduce return type
    typedef metamusil::deduce_return_type_t<MemFunPointerType> return_type;

    // deduce parameter types
    typedef metamusil::deduce_parameter_types_t<MemFunPointerType>
        parameter_types;

    // make integer sequence from parameter type list
    typedef metamusil::t_list::index_sequence_for_t<parameter_types>
        parameter_sequence;

    // deduce object type
    typedef metamusil::deduce_object_type_t<MemFunPointerType> object_type;

    return return_type_specializer<return_type>::
        template dispatch<MemFunPointerType, MemFunPointerValue, object_type>(
            object, argument_array, parameter_types(), parameter_sequence());
}
} // namespace member_function_detail

namespace member_variable_detail
{

template <class MemVarPointerType,
          MemVarPointerType MemVarPointerValue,
          class ObjectType,
          class MemVarType>
any
get_dispatch(const any& object)
{
    return (object.get<ObjectType>().*MemVarPointerValue);
}

template <class MemVarPointerType,
          MemVarPointerType MemVarPointerValue,
          class ObjectType,
          class MemVarType>
void
set_dispatch(any& object, const any& value)
{
    (object.get<ObjectType>().*MemVarPointerValue) = value.get<MemVarType>();
}

template <class MemVarPointerType, MemVarPointerType MemVarPointerValue>
any
generic_member_variable_get_bind_point(const any& object)
{
    typedef metamusil::deduce_member_variable_object_type_t<MemVarPointerType>
        object_type;
    typedef metamusil::deduce_member_variable_type_t<MemVarPointerType>
        member_variable_type;

    return get_dispatch<MemVarPointerType,
                        MemVarPointerValue,
                        object_type,
                        member_variable_type>(object);
}

template <class MemVarPointerType, MemVarPointerType MemVarPointerValue>
void
generic_member_variable_set_bind_point(any& object, const any& value)
{
    typedef metamusil::deduce_member_variable_object_type_t<MemVarPointerType>
        object_type;
    typedef metamusil::deduce_member_variable_type_t<MemVarPointerType>
        member_variable_type;

    return set_dispatch<MemVarPointerType,
                        MemVarPointerValue,
                        object_type,
                        member_variable_type>(object, value);
}
} // namespace member_variable_detail

namespace constructor_detail
{

// purpose of braced_init_selector is to attempt to use constructor T(...) if
// available, otherwise fall back to braced init list initialization
template <class, class T, class... ParamTypes>
struct braced_init_selector_impl
{
    template <std::size_t... Seq>
    static any
    constructor_dispatch(any* argument_array, std::index_sequence<Seq...>)
    {
        any out = T{argument_array[Seq].get<ParamTypes>()...};
        return out;
    }
};

template <class T, class... ParamTypes>
struct braced_init_selector_impl<
    metamusil::void_t<decltype(T(std::declval<ParamTypes>()...))>,
    T,
    ParamTypes...>
{
    template <std::size_t... Seq>
    static any
    constructor_dispatch(any* argument_array, std::index_sequence<Seq...>)
    {
        any out = T(argument_array[Seq].get<ParamTypes>()...);
        return out;
    }
};

template <class T, class... ParamTypes>
using braced_init_selector = braced_init_selector_impl<void, T, ParamTypes...>;

template <class T, class... ParamTypes>
any
generic_constructor_bind_point(any* argument_array)
{
    typedef std::index_sequence_for<ParamTypes...> param_sequence;

    return braced_init_selector<T, ParamTypes...>::constructor_dispatch(
        argument_array, param_sequence());
}
} // namespace constructor_detail

namespace conversion_detail
{
template <class TargetType, class SourceType, class = void>
struct conversion_specializer;

template <>
struct conversion_specializer<void, void>;

template <class TargetType, class SourceType>
struct conversion_specializer<
    TargetType,
    SourceType,
    std::enable_if_t<std::is_convertible<SourceType, TargetType>::value>>
{
    static any
    dispatch(const any& src)
    {
        TargetType temp = static_cast<TargetType>(src.get<SourceType>());
        return temp;
    }
};

template <class TargetType, class SourceType>
any
generic_conversion_bind_point(const any& src)
{
    return conversion_specializer<TargetType, SourceType>::dispatch(src);
}
} // namespace conversion_detail

namespace string_serialization_detail
{

template <class T, class = void>
struct string_serialize_type_selector;

template <class T>
struct string_serialize_type_selector<
    T,
    std::enable_if_t<std::is_arithmetic<T>::value>>
{
    static std::string
    dispatch(const any& value)
    {
        return std::to_string(value.get<T>());
    }
};

template <>
struct string_serialize_type_selector<std::string>
{
    static std::string
    dispatch(const any& value)
    {
        return value.get<std::string>();
    }
};

template <>
struct string_serialize_type_selector<char>
{
    static std::string
    dispatch(const any& value)
    {
        std::string out;
        out.push_back(value.get<char>());
        return out;
    }
};

template <>
struct string_serialize_type_selector<void>
{
    static std::string
    dispatch(const any&)
    {
        return "empty";
    }
};

template <class T>
std::string
generic_string_serialization_bind_point(const any& value)
{
    return string_serialize_type_selector<T>::dispatch(value);
}

template <class T, class = void>
struct string_deserialize_type_selector;

template <class T>
struct string_deserialize_type_selector<
    T,
    std::enable_if_t<std::is_arithmetic<T>::value>>
{
    static any
    dispatch(const std::string& str_value)
    {
        T out = std::stold(str_value);
        return out;
    }
};

template <>
struct string_deserialize_type_selector<char>
{
    static any
    dispatch(const std::string& str_value)
    {
        return str_value[0];
    }
};

template <>
struct string_deserialize_type_selector<std::string>
{
    static any
    dispatch(const std::string& str_value)
    {
        return str_value;
    }
};

template <>
struct string_deserialize_type_selector<int>
{
    static any
    dispatch(const std::string& str_value)
    {
        return std::stoi(str_value);
    }
};

template <>
struct string_deserialize_type_selector<long>
{
    static any
    dispatch(const std::string& str_value)
    {
        return std::stol(str_value);
    }
};

template <>
struct string_deserialize_type_selector<long long>
{
    static any
    dispatch(const std::string& str_value)
    {
        return std::stoll(str_value);
    }
};

template <>
struct string_deserialize_type_selector<unsigned long>
{
    static any
    dispatch(const std::string& str_value)
    {
        return std::stoul(str_value);
    }
};

template <>
struct string_deserialize_type_selector<unsigned long long>
{
    static any
    dispatch(const std::string& str_value)
    {
        return std::stoull(str_value);
    }
};

template <>
struct string_deserialize_type_selector<float>
{
    static any
    dispatch(const std::string& str_value)
    {
        return std::stof(str_value);
    }
};

template <>
struct string_deserialize_type_selector<double>
{
    static any
    dispatch(const std::string& str_value)
    {
        return std::stod(str_value);
    }
};

template <>
struct string_deserialize_type_selector<long double>
{
    static any
    dispatch(const std::string& str_value)
    {
        return std::stold(str_value);
    }
};

template <>
struct string_deserialize_type_selector<void>
{
    static any
    dispatch(const std::string&)
    {
        return shadow::any();
    }
};

template <class T>
any
generic_string_deserialization_bind_point(const std::string& str_value)
{
    return string_deserialize_type_selector<T>::dispatch(str_value);
}
} // namespace string_serialization_detail

namespace pointer_detail
{
template <class T>
inline any
generic_address_of_bind_point(any& value)
{
    return any(&(value.get<T>()));
}

template <>
inline any
generic_address_of_bind_point<void>(any&)
{
    return any(nullptr);
}

template <class T>
inline any
generic_dereference_bind_point(any& value)
{
    return any(*(value.get<T*>()));
}

template <>
inline any
generic_dereference_bind_point<void>(any&)
{
    return any();
}

} // namespace pointer_detail

} // namespace shadow

#endif
<commit_msg>Add remove_reference when unwrapping argument_array in constructor_dispatch. 	modified:   include/reflection_binding.hpp<commit_after>#ifndef REFLECTION_BINDING_HPP
#define REFLECTION_BINDING_HPP

#include <string>
#include <type_traits>
#include <utility>

#include "any.hpp"
#include <function_deduction.hpp>
#include <member_variable_deduction.hpp>
#include <type_list.hpp>
#include <void_t.hpp>

namespace shadow
{
// free function signature
typedef any (*free_function_binding_signature)(any*);
// member function signature
typedef any (*member_function_binding_signature)(any&, any*);
// member variable getter
typedef any (*member_variable_get_binding_signature)(const any&);
// member variable setter
typedef void (*member_variable_set_binding_signature)(any&, const any&);
// constructor signature
typedef any (*constructor_binding_signature)(any*);
// conversion signature
typedef any (*conversion_binding_signature)(const any&);
// string serialize signature
typedef std::string (*string_serialization_signature)(const any&);
// string deserialization signature
typedef any (*string_deserialization_signature)(const std::string&);
// address of signature
typedef any (*address_of_signature)(any&);
// dereference signature
typedef any (*dereference_signature)(any&);

////////////////////////////////////////////////////////////////////////////////
// generic bind point for free functions
// has the same signature as function pointer free_function_binding_signature
// which can be stored in the free_function_info struct

namespace free_function_detail
{
// necessary to handle void as return type differently when calling underlying
// free function
template <class ReturnType>
struct return_type_specializer
{
    // dispatch: unpacks argument type list and sequence to correctly index into
    // argument array and call get with the right types to retrieve raw values
    // from the anys
    template <class FunctionPointerType,
              FunctionPointerType FunctionPointerValue,
              class... ArgTypes,
              std::size_t... ArgSeq>
    static any
    dispatch(any* argument_array,
             metamusil::t_list::type_list<ArgTypes...>,
             std::index_sequence<ArgSeq...>)
    {
        // necessary to remove reference from types as any only stores
        // unqualified types, ie values only
        return FunctionPointerValue(
            argument_array[ArgSeq]
                .get<typename std::remove_reference_t<ArgTypes>>()...);
    }
};

template <>
struct return_type_specializer<void>
{
    // dispatch: unpacks argument type list and sequence to correctly index into
    // argument array and call get with the right types to retrieve raw values
    // from the anys
    template <class FunctionPointerType,
              FunctionPointerType FunctionPointerValue,
              class... ArgTypes,
              std::size_t... ArgSeq>
    static any
    dispatch(any* argument_array,
             metamusil::t_list::type_list<ArgTypes...>,
             std::index_sequence<ArgSeq...>)
    {
        // necessary to remove reference from types as any only stores
        // unqualified types, ie values only
        FunctionPointerValue(
            argument_array[ArgSeq]
                .get<typename std::remove_reference_t<ArgTypes>>()...);

        // return empty any, ie 'void'
        return any();
    }
};

// the value of the function pointer is stored at runtime in the template
// overload set
// this enables any function to be wrapped into uniform function signature that
// can be stored homogenously at runtime
template <class FunctionPointerType, FunctionPointerType FunctionPointerValue>
any
generic_free_function_bind_point(any* argument_array)
{
    typedef metamusil::deduce_return_type_t<FunctionPointerType> return_type;
    typedef metamusil::deduce_parameter_types_t<FunctionPointerType>
        parameter_types;
    // make integer sequence from type list
    typedef metamusil::t_list::index_sequence_for_t<parameter_types>
        parameter_sequence;

    return return_type_specializer<return_type>::
        template dispatch<FunctionPointerType, FunctionPointerValue>(
            argument_array, parameter_types(), parameter_sequence());
}
} // namespace free_function_detail

namespace member_function_detail
{

template <class ReturnType>
struct return_type_specializer
{
    template <class MemFunPointerType,
              MemFunPointerType MemFunPointerValue,
              class ObjectType,
              class... ParamTypes,
              std::size_t... ParamSequence>
    static any
    dispatch(any& object,
             any* argument_array,
             metamusil::t_list::type_list<ParamTypes...>,
             std::index_sequence<ParamSequence...>)
    {
        return (object.get<ObjectType>().*MemFunPointerValue)(
            argument_array[ParamSequence]
                .get<std::remove_reference_t<ParamTypes>>()...);
    }
};

template <>
struct return_type_specializer<void>
{
    template <class MemFunPointerType,
              MemFunPointerType MemFunPointerValue,
              class ObjectType,
              class... ParamTypes,
              std::size_t... ParamSequence>
    static any
    dispatch(any& object,
             any* argument_array,
             metamusil::t_list::type_list<ParamTypes...>,
             std::index_sequence<ParamSequence...>)
    {
        (object.get<ObjectType>().*MemFunPointerValue)(
            argument_array[ParamSequence]
                .get<std::remove_reference_t<ParamTypes>>()...);

        return any();
    }
};

template <class MemFunPointerType, MemFunPointerType MemFunPointerValue>
any
generic_member_function_bind_point(any& object, any* argument_array)
{
    // deduce return type
    typedef metamusil::deduce_return_type_t<MemFunPointerType> return_type;

    // deduce parameter types
    typedef metamusil::deduce_parameter_types_t<MemFunPointerType>
        parameter_types;

    // make integer sequence from parameter type list
    typedef metamusil::t_list::index_sequence_for_t<parameter_types>
        parameter_sequence;

    // deduce object type
    typedef metamusil::deduce_object_type_t<MemFunPointerType> object_type;

    return return_type_specializer<return_type>::
        template dispatch<MemFunPointerType, MemFunPointerValue, object_type>(
            object, argument_array, parameter_types(), parameter_sequence());
}
} // namespace member_function_detail

namespace member_variable_detail
{

template <class MemVarPointerType,
          MemVarPointerType MemVarPointerValue,
          class ObjectType,
          class MemVarType>
any
get_dispatch(const any& object)
{
    return (object.get<ObjectType>().*MemVarPointerValue);
}

template <class MemVarPointerType,
          MemVarPointerType MemVarPointerValue,
          class ObjectType,
          class MemVarType>
void
set_dispatch(any& object, const any& value)
{
    (object.get<ObjectType>().*MemVarPointerValue) = value.get<MemVarType>();
}

template <class MemVarPointerType, MemVarPointerType MemVarPointerValue>
any
generic_member_variable_get_bind_point(const any& object)
{
    typedef metamusil::deduce_member_variable_object_type_t<MemVarPointerType>
        object_type;
    typedef metamusil::deduce_member_variable_type_t<MemVarPointerType>
        member_variable_type;

    return get_dispatch<MemVarPointerType,
                        MemVarPointerValue,
                        object_type,
                        member_variable_type>(object);
}

template <class MemVarPointerType, MemVarPointerType MemVarPointerValue>
void
generic_member_variable_set_bind_point(any& object, const any& value)
{
    typedef metamusil::deduce_member_variable_object_type_t<MemVarPointerType>
        object_type;
    typedef metamusil::deduce_member_variable_type_t<MemVarPointerType>
        member_variable_type;

    return set_dispatch<MemVarPointerType,
                        MemVarPointerValue,
                        object_type,
                        member_variable_type>(object, value);
}
} // namespace member_variable_detail

namespace constructor_detail
{

// purpose of braced_init_selector is to attempt to use constructor T(...) if
// available, otherwise fall back to braced init list initialization
template <class, class T, class... ParamTypes>
struct braced_init_selector_impl
{
    template <std::size_t... Seq>
    static any
    constructor_dispatch(any* argument_array, std::index_sequence<Seq...>)
    {
        any out =
            T{argument_array[Seq]
                  .get<typename std::remove_reference<ParamTypes>::type>()...};
        return out;
    }
};

template <class T, class... ParamTypes>
struct braced_init_selector_impl<
    metamusil::void_t<decltype(T(std::declval<ParamTypes>()...))>,
    T,
    ParamTypes...>
{
    template <std::size_t... Seq>
    static any
    constructor_dispatch(any* argument_array, std::index_sequence<Seq...>)
    {
        any out =
            T(argument_array[Seq]
                  .get<typename std::remove_reference<ParamTypes>::type>()...);
        return out;
    }
};

template <class T, class... ParamTypes>
using braced_init_selector = braced_init_selector_impl<void, T, ParamTypes...>;

template <class T, class... ParamTypes>
any
generic_constructor_bind_point(any* argument_array)
{
    typedef std::index_sequence_for<ParamTypes...> param_sequence;

    return braced_init_selector<T, ParamTypes...>::constructor_dispatch(
        argument_array, param_sequence());
}
} // namespace constructor_detail

namespace conversion_detail
{
template <class TargetType, class SourceType, class = void>
struct conversion_specializer;

template <>
struct conversion_specializer<void, void>;

template <class TargetType, class SourceType>
struct conversion_specializer<
    TargetType,
    SourceType,
    std::enable_if_t<std::is_convertible<SourceType, TargetType>::value>>
{
    static any
    dispatch(const any& src)
    {
        TargetType temp = static_cast<TargetType>(src.get<SourceType>());
        return temp;
    }
};

template <class TargetType, class SourceType>
any
generic_conversion_bind_point(const any& src)
{
    return conversion_specializer<TargetType, SourceType>::dispatch(src);
}
} // namespace conversion_detail

namespace string_serialization_detail
{

template <class T, class = void>
struct string_serialize_type_selector;

template <class T>
struct string_serialize_type_selector<
    T,
    std::enable_if_t<std::is_arithmetic<T>::value>>
{
    static std::string
    dispatch(const any& value)
    {
        return std::to_string(value.get<T>());
    }
};

template <>
struct string_serialize_type_selector<std::string>
{
    static std::string
    dispatch(const any& value)
    {
        return value.get<std::string>();
    }
};

template <>
struct string_serialize_type_selector<char>
{
    static std::string
    dispatch(const any& value)
    {
        std::string out;
        out.push_back(value.get<char>());
        return out;
    }
};

template <>
struct string_serialize_type_selector<void>
{
    static std::string
    dispatch(const any&)
    {
        return "empty";
    }
};

template <class T>
std::string
generic_string_serialization_bind_point(const any& value)
{
    return string_serialize_type_selector<T>::dispatch(value);
}

template <class T, class = void>
struct string_deserialize_type_selector;

template <class T>
struct string_deserialize_type_selector<
    T,
    std::enable_if_t<std::is_arithmetic<T>::value>>
{
    static any
    dispatch(const std::string& str_value)
    {
        T out = std::stold(str_value);
        return out;
    }
};

template <>
struct string_deserialize_type_selector<char>
{
    static any
    dispatch(const std::string& str_value)
    {
        return str_value[0];
    }
};

template <>
struct string_deserialize_type_selector<std::string>
{
    static any
    dispatch(const std::string& str_value)
    {
        return str_value;
    }
};

template <>
struct string_deserialize_type_selector<int>
{
    static any
    dispatch(const std::string& str_value)
    {
        return std::stoi(str_value);
    }
};

template <>
struct string_deserialize_type_selector<long>
{
    static any
    dispatch(const std::string& str_value)
    {
        return std::stol(str_value);
    }
};

template <>
struct string_deserialize_type_selector<long long>
{
    static any
    dispatch(const std::string& str_value)
    {
        return std::stoll(str_value);
    }
};

template <>
struct string_deserialize_type_selector<unsigned long>
{
    static any
    dispatch(const std::string& str_value)
    {
        return std::stoul(str_value);
    }
};

template <>
struct string_deserialize_type_selector<unsigned long long>
{
    static any
    dispatch(const std::string& str_value)
    {
        return std::stoull(str_value);
    }
};

template <>
struct string_deserialize_type_selector<float>
{
    static any
    dispatch(const std::string& str_value)
    {
        return std::stof(str_value);
    }
};

template <>
struct string_deserialize_type_selector<double>
{
    static any
    dispatch(const std::string& str_value)
    {
        return std::stod(str_value);
    }
};

template <>
struct string_deserialize_type_selector<long double>
{
    static any
    dispatch(const std::string& str_value)
    {
        return std::stold(str_value);
    }
};

template <>
struct string_deserialize_type_selector<void>
{
    static any
    dispatch(const std::string&)
    {
        return shadow::any();
    }
};

template <class T>
any
generic_string_deserialization_bind_point(const std::string& str_value)
{
    return string_deserialize_type_selector<T>::dispatch(str_value);
}
} // namespace string_serialization_detail

namespace pointer_detail
{
template <class T>
inline any
generic_address_of_bind_point(any& value)
{
    return any(&(value.get<T>()));
}

template <>
inline any
generic_address_of_bind_point<void>(any&)
{
    return any(nullptr);
}

template <class T>
inline any
generic_dereference_bind_point(any& value)
{
    return any(*(value.get<T*>()));
}

template <>
inline any
generic_dereference_bind_point<void>(any&)
{
    return any();
}

} // namespace pointer_detail

} // namespace shadow

#endif
<|endoftext|>


<commit_before>#pragma once
/**
	@file
	@brief operator class
	@author MITSUNARI Shigeo(@herumi)
	@license modified new BSD license
	http://opensource.org/licenses/BSD-3-Clause
*/
#include <mcl/op.hpp>
#include <mcl/util.hpp>
#ifdef _MSC_VER
	#ifndef MCL_FORCE_INLINE
		#define MCL_FORCE_INLINE __forceinline
	#endif
	#pragma warning(push)
	#pragma warning(disable : 4714)
#else
	#ifndef MCL_FORCE_INLINE
		#define MCL_FORCE_INLINE __attribute__((always_inline))
	#endif
#endif

namespace mcl { namespace fp {

template<class T>
struct Empty {};

/*
	T must have add, sub, mul, inv, neg
*/
template<class T, class E = Empty<T> >
struct Operator : E {
	template<class S> MCL_FORCE_INLINE T& operator+=(const S& rhs) { T::add(static_cast<T&>(*this), static_cast<const T&>(*this), rhs); return static_cast<T&>(*this); }
	template<class S> MCL_FORCE_INLINE T& operator-=(const S& rhs) { T::sub(static_cast<T&>(*this), static_cast<const T&>(*this), rhs); return static_cast<T&>(*this); }
	template<class S> friend MCL_FORCE_INLINE T operator+(const T& a, const S& b) { T c; T::add(c, a, b); return c; }
	template<class S> friend MCL_FORCE_INLINE T operator-(const T& a, const S& b) { T c; T::sub(c, a, b); return c; }
	template<class S> MCL_FORCE_INLINE T& operator*=(const S& rhs) { T::mul(static_cast<T&>(*this), static_cast<const T&>(*this), rhs); return static_cast<T&>(*this); }
	template<class S> friend MCL_FORCE_INLINE T operator*(const T& a, const S& b) { T c; T::mul(c, a, b); return c; }
	MCL_FORCE_INLINE T& operator/=(const T& rhs) { T c; T::inv(c, rhs); T::mul(static_cast<T&>(*this), static_cast<const T&>(*this), c); return static_cast<T&>(*this); }
	static MCL_FORCE_INLINE void div(T& c, const T& a, const T& b) { T t; T::inv(t, b); T::mul(c, a, t); }
	friend MCL_FORCE_INLINE T operator/(const T& a, const T& b) { T c; T::inv(c, b); c *= a; return c; }
	MCL_FORCE_INLINE T operator-() const { T c; T::neg(c, static_cast<const T&>(*this)); return c; }
	template<class tag2, size_t maxBitSize2, template<class _tag, size_t _maxBitSize> class FpT>
	static void pow(T& z, const T& x, const FpT<tag2, maxBitSize2>& y)
	{
		fp::Block b;
		y.getBlock(b);
		powArray(z, x, b.p, b.n, false);
	}
	static void pow(T& z, const T& x, int y)
	{
		const Unit u = abs(y);
		powArray(z, x, &u, 1, y < 0);
	}
	static void pow(T& z, const T& x, const mpz_class& y)
	{
		powArray(z, x, gmp::getUnit(y), abs(y.get_mpz_t()->_mp_size), y < 0);
	}
private:
	static void powArray(T& z, const T& x, const Unit *y, size_t yn, bool isNegative)
	{
		T tmp;
		const T *px = &x;
		if (&z == &x) {
			tmp = x;
			px = &tmp;
		}
		z = 1;
		fp::powGeneric(z, *px, y, yn, T::mul, T::sqr, (void (*)(T&, const T&))0);
		if (isNegative) {
			T::inv(z, z);
		}
	}
};

} } // mcl::fp

<commit_msg>Expose const time exponentiation for fields<commit_after>#pragma once
/**
	@file
	@brief operator class
	@author MITSUNARI Shigeo(@herumi)
	@license modified new BSD license
	http://opensource.org/licenses/BSD-3-Clause
*/
#include <mcl/op.hpp>
#include <mcl/util.hpp>
#ifdef _MSC_VER
	#ifndef MCL_FORCE_INLINE
		#define MCL_FORCE_INLINE __forceinline
	#endif
	#pragma warning(push)
	#pragma warning(disable : 4714)
#else
	#ifndef MCL_FORCE_INLINE
		#define MCL_FORCE_INLINE __attribute__((always_inline))
	#endif
#endif

namespace mcl { namespace fp {

template<class T>
struct Empty {};

/*
	T must have add, sub, mul, inv, neg
*/
template<class T, class E = Empty<T> >
struct Operator : E {
	template<class S> MCL_FORCE_INLINE T& operator+=(const S& rhs) { T::add(static_cast<T&>(*this), static_cast<const T&>(*this), rhs); return static_cast<T&>(*this); }
	template<class S> MCL_FORCE_INLINE T& operator-=(const S& rhs) { T::sub(static_cast<T&>(*this), static_cast<const T&>(*this), rhs); return static_cast<T&>(*this); }
	template<class S> friend MCL_FORCE_INLINE T operator+(const T& a, const S& b) { T c; T::add(c, a, b); return c; }
	template<class S> friend MCL_FORCE_INLINE T operator-(const T& a, const S& b) { T c; T::sub(c, a, b); return c; }
	template<class S> MCL_FORCE_INLINE T& operator*=(const S& rhs) { T::mul(static_cast<T&>(*this), static_cast<const T&>(*this), rhs); return static_cast<T&>(*this); }
	template<class S> friend MCL_FORCE_INLINE T operator*(const T& a, const S& b) { T c; T::mul(c, a, b); return c; }
	MCL_FORCE_INLINE T& operator/=(const T& rhs) { T c; T::inv(c, rhs); T::mul(static_cast<T&>(*this), static_cast<const T&>(*this), c); return static_cast<T&>(*this); }
	static MCL_FORCE_INLINE void div(T& c, const T& a, const T& b) { T t; T::inv(t, b); T::mul(c, a, t); }
	friend MCL_FORCE_INLINE T operator/(const T& a, const T& b) { T c; T::inv(c, b); c *= a; return c; }
	MCL_FORCE_INLINE T operator-() const { T c; T::neg(c, static_cast<const T&>(*this)); return c; }
	template<class tag2, size_t maxBitSize2, template<class _tag, size_t _maxBitSize> class FpT>
	static void pow(T& z, const T& x, const FpT<tag2, maxBitSize2>& y, bool constTime = false)
	{
		fp::Block b;
		y.getBlock(b);
		powArray(z, x, b.p, b.n, false, constTime);
	}
	static void pow(T& z, const T& x, int y, bool constTime = false)
	{
		const Unit u = abs(y);
		powArray(z, x, &u, 1, y < 0, constTime);
	}
	static void pow(T& z, const T& x, const mpz_class& y, bool constTime = false)
	{
		powArray(z, x, gmp::getUnit(y), abs(y.get_mpz_t()->_mp_size), y < 0, constTime);
	}
private:
	static void powArray(T& z, const T& x, const Unit *y, size_t yn, bool isNegative, bool constTime)
	{
		T tmp;
		const T *px = &x;
		if (&z == &x) {
			tmp = x;
			px = &tmp;
		}
		z = 1;
		fp::powGeneric(z, *px, y, yn, T::mul, T::sqr, (void (*)(T&, const T&))0, constTime);
		if (isNegative) {
			T::inv(z, z);
		}
	}
};

} } // mcl::fp

<|endoftext|>