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

#ifndef ZIPPYLOG_DEVICE_PERSISTED_STATE_REACTOR_HPP_
#define ZIPPYLOG_DEVICE_PERSISTED_STATE_REACTOR_HPP_

#include <zippylog/zippylog.hpp>
#include <zippylog/device/device.hpp>
#include <zippylog/persisted_state_manager.hpp>
#include <zippylog/store.hpp>

#include <zmq.hpp>

#include <string>

namespace zippylog {
namespace device {

/// Container for parameters used to initialize PersistedStateReactor
class ZIPPYLOG_EXPORT PersistedStateReactorStartParams {
public:
    /// Create a new container
    PersistedStateReactorStartParams() :
        ctx(NULL),
        active(NULL)
    { }

    /// 0MQ context
    ::zmq::context_t *ctx;

    /// Endpoint for socket that should receive store changes
    ::std::string store_change_endpoint;

    /// Endpoint for socket that leads back to clients
    ::std::string client_endpoint;

    /// Endpoint for socket that receives new persisted state requests
    ::std::string subscription_endpoint;

    /// Endpoint for socket that receives updates from clients
    ::std::string subscription_updates_endpoint;

    /// Endpoint for a logger to send logging information
    ::std::string logger_endpoint;

    /// Semaphore stating whether device should remain active
    ::zippylog::platform::ConditionalWait *active;

    /// Parameters used to construct a persisted state observer
    PersistedStateManagerStartParams manager_params;
};

/// Device that reacts to events related to persisted state
///
/// The device is responsible for managing subscriptions and plugins and
/// handling all events that these are interested in.
///
/// Interaction with the device is performed through a number of 0MQ sockets:
///
///   - store_changes - SUB that receives store change notifications
///   - client        - PUSH that sends subscription responses to clients
///   - subscriptions - PULL that receives new subscription requests
///   - subscription_updates - SUB that receives updates concerning existing subscriptions
///   - logger        - PUSH that sends logging info from the device
///
/// The general pattern is to instantiate this class on a thread and call
/// Run(), which will block until the device is shut down.
class ZIPPYLOG_EXPORT PersistedStateReactor : public ::zippylog::device::Device {
public:
    /// Construct a persisted state reactor from parameters
    ///
    /// @params Options to define instance
    PersistedStateReactor(PersistedStateReactorStartParams const &params);

    ~PersistedStateReactor();

    /// Performs work on the device if there is work to be done
    ///
    /// Waits up to the specified time for work to become available, if none is available
    ::zippylog::device::PumpResult Pump(int32 timeout_microseconds);
protected:

    ///@{
    /// Persisted state manager handlers
    ///
    /// The persisted state manager calls into these for every subscription
    /// that cares about them. The functions formulate a response and send
    /// them to the client.
    static void PathAddedCallback(SubscriptionInfo const &subscription, ::std::string const &path, void *data);
    static void PathDeletedCallback(SubscriptionInfo const &subscription, ::std::string const &path, void *data);
    static void StreamAppendedCallback(SubscriptionInfo const &subscription, EnvelopeSubscriptionResponseState &state, void *data);
    ///@}

    /// Initializes the object
    ///
    /// Called by the constructor. Throws an exception on error.
    void Initialize();

    /// Processes a received store change message
    void ProcessStoreChangeMessage(::zmq::message_t &msg);

    /// Process a subscription update message
    void ProcessSubscriptionUpdate(::zmq::message_t &msg);

    /// 0MQ context
    ::zmq::context_t *ctx;

    /// Endpoint on which we listen for store change notifications
    ::std::string store_changes_endpoint;

    /// Endpoint that leads back to clients
    ::std::string client_endpoint;

    /// Endpoint that receives new persisted state requests
    ::std::string subscription_endpoint;

    /// Endpoint that receives persisted state updates
    ::std::string subscription_updates_endpoint;

    /// Endpoint for where to send log messages
    ::std::string logger_endpoint;

    /// Parameters used to initialize the PersistedStateManager
    PersistedStateManagerStartParams manager_params;

    /// Identifier for this instance
    ::std::string id;

    /// SUB that receives store change notifications
    ::zmq::socket_t *store_changes_sock;

    /// PUSH that sends messages back to clients
    ::zmq::socket_t *client_sock;

    /// PULL that receives new persisted state requests
    ::zmq::socket_t *subscription_sock;

    /// SUB that receives persisted state updates
    ::zmq::socket_t *subscription_updates_sock;

    /// PUSH that sends logging messages
    ::zmq::socket_t *logger_sock;

    /// Polling structure for 0MQ
    ::zmq::pollitem_t pollitems[3];

    /// The thing that actually handles persisted state
    PersistedStateManager *manager;

private:
    // disallow copy constructor and assignment operator
    PersistedStateReactor(PersistedStateReactor const &);
    PersistedStateReactor & operator=(PersistedStateReactor const &);
};

}} // namespace

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

#ifndef ZIPPYLOG_DEVICE_PERSISTED_STATE_REACTOR_HPP_
#define ZIPPYLOG_DEVICE_PERSISTED_STATE_REACTOR_HPP_

#include <zippylog/zippylog.hpp>
#include <zippylog/device/device.hpp>
#include <zippylog/persisted_state_manager.hpp>
#include <zippylog/store.hpp>

#include <zmq.hpp>

#include <string>

namespace zippylog {
namespace device {

/// Container for parameters used to initialize PersistedStateReactor
class ZIPPYLOG_EXPORT PersistedStateReactorStartParams {
public:
    /// Create a new container
    PersistedStateReactorStartParams() :
        ctx(NULL),
        active(NULL)
    { }

    /// 0MQ context
    ::zmq::context_t *ctx;

    /// Endpoint for socket that should receive store changes
    ::std::string store_change_endpoint;

    /// Endpoint for socket that leads back to clients
    ::std::string client_endpoint;

    /// Endpoint for socket that receives new persisted state requests
    ::std::string subscription_endpoint;

    /// Endpoint for socket that receives updates from clients
    ::std::string subscription_updates_endpoint;

    /// Endpoint for a logger to send logging information
    ::std::string logger_endpoint;

    /// Semaphore stating whether device should remain active
    ::zippylog::platform::ConditionalWait *active;

    /// Parameters used to construct a persisted state observer
    PersistedStateManagerStartParams manager_params;
};

/// Device that reacts to events related to persisted state
///
/// The device is responsible for managing subscriptions and plugins and
/// handling all events that these are interested in.
///
/// Interaction with the device is performed through a number of 0MQ sockets:
///
///   - store_changes - SUB that receives store change notifications
///   - client        - PUSH that sends subscription responses to clients
///   - subscriptions - PULL that receives new subscription requests
///   - subscription_updates - SUB that receives updates concerning existing subscriptions
///   - logger        - PUSH that sends logging info from the device
///
/// The general pattern is to instantiate this class on a thread and call
/// Run(), which will block until the device is shut down.
class ZIPPYLOG_EXPORT PersistedStateReactor : public ::zippylog::device::Device {
public:
    /// Construct a persisted state reactor from parameters
    ///
    /// @param params Options to define instance
    PersistedStateReactor(PersistedStateReactorStartParams const &params);

    ~PersistedStateReactor();

    /// Performs work on the device if there is work to be done
    ///
    /// Waits up to the specified time for work to become available, if none is available
    ::zippylog::device::PumpResult Pump(int32 timeout_microseconds);
protected:

    ///@{
    /// Persisted state manager handlers
    ///
    /// The persisted state manager calls into these for every subscription
    /// that cares about them. The functions formulate a response and send
    /// them to the client.
    static void PathAddedCallback(SubscriptionInfo const &subscription, ::std::string const &path, void *data);
    static void PathDeletedCallback(SubscriptionInfo const &subscription, ::std::string const &path, void *data);
    static void StreamAppendedCallback(SubscriptionInfo const &subscription, EnvelopeSubscriptionResponseState &state, void *data);
    ///@}

    /// Initializes the object
    ///
    /// Called by the constructor. Throws an exception on error.
    void Initialize();

    /// Processes a received store change message
    void ProcessStoreChangeMessage(::zmq::message_t &msg);

    /// Process a subscription update message
    void ProcessSubscriptionUpdate(::zmq::message_t &msg);

    /// 0MQ context
    ::zmq::context_t *ctx;

    /// Endpoint on which we listen for store change notifications
    ::std::string store_changes_endpoint;

    /// Endpoint that leads back to clients
    ::std::string client_endpoint;

    /// Endpoint that receives new persisted state requests
    ::std::string subscription_endpoint;

    /// Endpoint that receives persisted state updates
    ::std::string subscription_updates_endpoint;

    /// Endpoint for where to send log messages
    ::std::string logger_endpoint;

    /// Parameters used to initialize the PersistedStateManager
    PersistedStateManagerStartParams manager_params;

    /// Identifier for this instance
    ::std::string id;

    /// SUB that receives store change notifications
    ::zmq::socket_t *store_changes_sock;

    /// PUSH that sends messages back to clients
    ::zmq::socket_t *client_sock;

    /// PULL that receives new persisted state requests
    ::zmq::socket_t *subscription_sock;

    /// SUB that receives persisted state updates
    ::zmq::socket_t *subscription_updates_sock;

    /// PUSH that sends logging messages
    ::zmq::socket_t *logger_sock;

    /// Polling structure for 0MQ
    ::zmq::pollitem_t pollitems[3];

    /// The thing that actually handles persisted state
    PersistedStateManager *manager;

private:
    // disallow copy constructor and assignment operator
    PersistedStateReactor(PersistedStateReactor const &);
    PersistedStateReactor & operator=(PersistedStateReactor const &);
};

}} // namespace

#endif // file include<|endoftext|>


<commit_before>// validator: no-include-guards
/*
disabled_warnings.hpp
*/
/*
Copyright © 2015 Far Group
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
3. The name of the authors may not be used to endorse or promote products
   derived from this software without specific prior written permission.

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

#ifdef _MSC_VER
// https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warnings-c4000-c5999

// some warnings do not exist in older VC versions, no need to care about them:
#pragma warning(disable: 4616) // #pragma warning : warning number 'number' not a valid compiler warning
#pragma warning(disable: 4619) // #pragma warning : there is no warning number 'number'

#ifdef DISABLE_WARNINGS_IN_STD_HEADERS
// these warnings are triggered in the standard headers only:
#pragma warning(disable: 4091) // 'typedef ': ignored on left of 'type' when no variable is declared
#pragma warning(disable: 4265) // 'class' : class has virtual functions, but destructor is not virtual
#pragma warning(disable: 4668) // 'symbol' is not defined as a preprocessor macro, replacing with '0' for 'directives'
#pragma warning(disable: 4768) // __declspec attributes before linkage specification are ignored
#pragma warning(disable: 4774) // 'function' : format string expected in argument 'number' is not a string literal
#pragma warning(disable: 4917) // 'declarator' : a GUID can only be associated with a class, interface or namespace
#pragma warning(disable: 4987) // nonstandard extension used: 'throw (...)'
#pragma warning(disable: 4996) // The compiler encountered a deprecated declaration
#pragma warning(disable: 4582) // 'class': constructor is not implicitly called
#pragma warning(disable: 4583) // 'class': destructor is not implicitly called
#pragma warning(disable: 5219) // implicit conversion from 'type1' to 'type2', possible loss of data
#else
// these in the rest of the code as well:
// TODO: some of these might be useful
#pragma warning(disable: 4061) // enumerator 'identifier' in switch of enum 'enumeration' is not explicitly handled by a case label
#pragma warning(disable: 4100) // 'identifier' : unreferenced formal parameter
#pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union
#pragma warning(disable: 4242) // 'identifier' : conversion from 'type1' to 'type2', possible loss of data
#pragma warning(disable: 4244) // 'conversion' conversion from 'type1' to 'type2', possible loss of data
#pragma warning(disable: 4245) // 'conversion' : conversion from 'type1' to 'type2', signed/unsigned mismatch
#pragma warning(disable: 4250) // 'class1' : inherits 'class2::member' via dominance
#pragma warning(disable: 4324) // 'struct_name' : structure was padded due to __declspec(align())
#pragma warning(disable: 4355) // 'this' : used in base member initializer list
#pragma warning(disable: 4365) // 'action' : conversion from 'type_1' to 'type_2', signed/unsigned mismatch
#pragma warning(disable: 4371) // layout of class may have changed from a previous version of the compiler due to better packing of member 'member'
#pragma warning(disable: 4373) // 'function': virtual function overrides 'function', previous versions of the compiler did not override when parameters only differed by const/volatile qualifiers
#pragma warning(disable: 4435) // 'class1' : Object layout under /vd2 will change due to virtual base 'class2'
#pragma warning(disable: 4464) // relative include path contains '..'
#pragma warning(disable: 4503) // 'identifier' : decorated name length exceeded, name was truncated
#pragma warning(disable: 4512) // 'class' : assignment operator could not be generated
#pragma warning(disable: 4514) // 'function' : unreferenced inline function has been removed
#pragma warning(disable: 4571) // Informational: catch(...) semantics changed since Visual C++ 7.1; structured exceptions (SEH) are no longer caught
#pragma warning(disable: 4574) // 'identifier' is defined to be '0': did you mean to use '#if identifier'?
#pragma warning(disable: 4623) // 'derived class' : default constructor was implicitly defined as deleted because a base class default constructor is inaccessible or deleted
#pragma warning(disable: 4625) // 'derived class' : copy constructor could not be generated because a base class copy constructor is inaccessible
#pragma warning(disable: 4626) // 'derived class' : assignment operator could not be generated because a base class assignment operator is inaccessible
#pragma warning(disable: 4640) // 'instance' : construction of local static object is not thread-safe
#pragma warning(disable: 4670) // identifier' : this base class is inaccessible
#pragma warning(disable: 4673) // throwing 'identifier' the following types will not be considered at the catch site
#pragma warning(disable: 4710) // 'function' : function not inlined
#pragma warning(disable: 4711) // function 'function' selected for inline expansion
#pragma warning(disable: 4746) // volatile access of '<expression>' is subject to /volatile:[iso|ms] setting; consider using __iso_volatile_load/store intrinsic functions
#pragma warning(disable: 4770) // partially validated enum 'name' used as index
#pragma warning(disable: 4738) // storing 32-bit float result in memory, possible loss of performance
#pragma warning(disable: 4686) //'user-defined type' : possible change in behavior, change in UDT return calling convention
#pragma warning(disable: 4814) // in C++14 'constexpr' will not imply 'const'; consider explicitly specifying 'const'
#pragma warning(disable: 4820) // 'bytes' bytes padding added after construct 'member_name'
#pragma warning(disable: 4866) // compiler may not enforce left-to-right evaluation order for call to operator_name
#pragma warning(disable: 4868) // compiler may not enforce left-to-right evaluation order in braced initializer list
#pragma warning(disable: 5025) // 'class': move assignment operator was implicitly defined as deleted
#pragma warning(disable: 5026) // 'class': move constructor was implicitly defined as deleted because a base class move constructor is inaccessible or deleted
#pragma warning(disable: 5027) // 'class': move assignment operator was implicitly defined as deleted because a base class move assignment operator is inaccessible or deleted
#pragma warning(disable: 5030) // attribute 'attribute' is not recognized
#pragma warning(disable: 5039) // 'function': pointer or reference to potentially throwing function passed to extern C function under -EHc. Undefined behavior may occur if this function throws an exception.
#pragma warning(disable: 5045) // Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
#pragma warning(disable: 5052) // Keyword 'char8_t' was introduced in C++20 and requires use of the '/std:c++latest' command-line option
#endif

#ifdef _DEBUG
// Happens only after "Apply code changes"
#pragma warning(disable: 4599) // command line argument number number does not match precompiled header
#endif

#endif

#ifdef __GNUC__
// https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

#pragma GCC diagnostic ignored "-Wunknown-pragmas"

// TODO: some of these might be useful
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"

#endif

#ifdef __clang__
// https://clang.llvm.org/docs/DiagnosticsReference.html

#pragma clang diagnostic ignored "-Wunknown-warning-option"

// TODO: some of these might be useful
#pragma clang diagnostic ignored "-Wc++98-compat"
#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wcovered-switch-default"
#pragma clang diagnostic ignored "-Wctad-maybe-unsupported"
#pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
#pragma clang diagnostic ignored "-Wenum-compare"
#pragma clang diagnostic ignored "-Wexit-time-destructors"
#pragma clang diagnostic ignored "-Wglobal-constructors"
#pragma clang diagnostic ignored "-Wgnu-anonymous-struct"
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
#pragma clang diagnostic ignored "-Wkeyword-macro"
#pragma clang diagnostic ignored "-Wlanguage-extension-token"
#pragma clang diagnostic ignored "-Wmicrosoft-enum-value"
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
#pragma clang diagnostic ignored "-Wnested-anon-types"
#pragma clang diagnostic ignored "-Wnonportable-system-include-path"
#pragma clang diagnostic ignored "-Wpadded"
#pragma clang diagnostic ignored "-Wreturn-std-move-in-c++11"
#pragma clang diagnostic ignored "-Wreserved-id-macro"
#pragma clang diagnostic ignored "-Wshadow-field-in-constructor"
#pragma clang diagnostic ignored "-Wshadow-field"
#pragma clang diagnostic ignored "-Wsign-conversion"
#pragma clang diagnostic ignored "-Wswitch-enum"
#pragma clang diagnostic ignored "-Wundefined-func-template"
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wunused-member-function"
#pragma clang diagnostic ignored "-Wunused-parameter"
#pragma clang diagnostic ignored "-Wweak-vtables"
#endif
<commit_msg>Suppress useless warning<commit_after>// validator: no-include-guards
/*
disabled_warnings.hpp
*/
/*
Copyright © 2015 Far Group
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
3. The name of the authors may not be used to endorse or promote products
   derived from this software without specific prior written permission.

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

#ifdef _MSC_VER
// https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warnings-c4000-c5999

// some warnings do not exist in older VC versions, no need to care about them:
#pragma warning(disable: 4616) // #pragma warning : warning number 'number' not a valid compiler warning
#pragma warning(disable: 4619) // #pragma warning : there is no warning number 'number'

#ifdef DISABLE_WARNINGS_IN_STD_HEADERS
// these warnings are triggered in the standard headers only:
#pragma warning(disable: 4091) // 'typedef ': ignored on left of 'type' when no variable is declared
#pragma warning(disable: 4265) // 'class' : class has virtual functions, but destructor is not virtual
#pragma warning(disable: 4668) // 'symbol' is not defined as a preprocessor macro, replacing with '0' for 'directives'
#pragma warning(disable: 4768) // __declspec attributes before linkage specification are ignored
#pragma warning(disable: 4774) // 'function' : format string expected in argument 'number' is not a string literal
#pragma warning(disable: 4917) // 'declarator' : a GUID can only be associated with a class, interface or namespace
#pragma warning(disable: 4987) // nonstandard extension used: 'throw (...)'
#pragma warning(disable: 4996) // The compiler encountered a deprecated declaration
#pragma warning(disable: 4582) // 'class': constructor is not implicitly called
#pragma warning(disable: 4583) // 'class': destructor is not implicitly called
#pragma warning(disable: 5219) // implicit conversion from 'type1' to 'type2', possible loss of data
#else
// these in the rest of the code as well:
// TODO: some of these might be useful
#pragma warning(disable: 4061) // enumerator 'identifier' in switch of enum 'enumeration' is not explicitly handled by a case label
#pragma warning(disable: 4100) // 'identifier' : unreferenced formal parameter
#pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union
#pragma warning(disable: 4242) // 'identifier' : conversion from 'type1' to 'type2', possible loss of data
#pragma warning(disable: 4244) // 'conversion' conversion from 'type1' to 'type2', possible loss of data
#pragma warning(disable: 4245) // 'conversion' : conversion from 'type1' to 'type2', signed/unsigned mismatch
#pragma warning(disable: 4250) // 'class1' : inherits 'class2::member' via dominance
#pragma warning(disable: 4324) // 'struct_name' : structure was padded due to __declspec(align())
#pragma warning(disable: 4355) // 'this' : used in base member initializer list
#pragma warning(disable: 4365) // 'action' : conversion from 'type_1' to 'type_2', signed/unsigned mismatch
#pragma warning(disable: 4371) // layout of class may have changed from a previous version of the compiler due to better packing of member 'member'
#pragma warning(disable: 4373) // 'function': virtual function overrides 'function', previous versions of the compiler did not override when parameters only differed by const/volatile qualifiers
#pragma warning(disable: 4435) // 'class1' : Object layout under /vd2 will change due to virtual base 'class2'
#pragma warning(disable: 4464) // relative include path contains '..'
#pragma warning(disable: 4503) // 'identifier' : decorated name length exceeded, name was truncated
#pragma warning(disable: 4512) // 'class' : assignment operator could not be generated
#pragma warning(disable: 4514) // 'function' : unreferenced inline function has been removed
#pragma warning(disable: 4571) // Informational: catch(...) semantics changed since Visual C++ 7.1; structured exceptions (SEH) are no longer caught
#pragma warning(disable: 4574) // 'identifier' is defined to be '0': did you mean to use '#if identifier'?
#pragma warning(disable: 4623) // 'derived class' : default constructor was implicitly defined as deleted because a base class default constructor is inaccessible or deleted
#pragma warning(disable: 4625) // 'derived class' : copy constructor could not be generated because a base class copy constructor is inaccessible
#pragma warning(disable: 4626) // 'derived class' : assignment operator could not be generated because a base class assignment operator is inaccessible
#pragma warning(disable: 4640) // 'instance' : construction of local static object is not thread-safe
#pragma warning(disable: 4670) // identifier' : this base class is inaccessible
#pragma warning(disable: 4673) // throwing 'identifier' the following types will not be considered at the catch site
#pragma warning(disable: 4710) // 'function' : function not inlined
#pragma warning(disable: 4711) // function 'function' selected for inline expansion
#pragma warning(disable: 4746) // volatile access of '<expression>' is subject to /volatile:[iso|ms] setting; consider using __iso_volatile_load/store intrinsic functions
#pragma warning(disable: 4770) // partially validated enum 'name' used as index
#pragma warning(disable: 4738) // storing 32-bit float result in memory, possible loss of performance
#pragma warning(disable: 4686) //'user-defined type' : possible change in behavior, change in UDT return calling convention
#pragma warning(disable: 4814) // in C++14 'constexpr' will not imply 'const'; consider explicitly specifying 'const'
#pragma warning(disable: 4820) // 'bytes' bytes padding added after construct 'member_name'
#pragma warning(disable: 4866) // compiler may not enforce left-to-right evaluation order for call to operator_name
#pragma warning(disable: 4868) // compiler may not enforce left-to-right evaluation order in braced initializer list
#pragma warning(disable: 5025) // 'class': move assignment operator was implicitly defined as deleted
#pragma warning(disable: 5026) // 'class': move constructor was implicitly defined as deleted because a base class move constructor is inaccessible or deleted
#pragma warning(disable: 5027) // 'class': move assignment operator was implicitly defined as deleted because a base class move assignment operator is inaccessible or deleted
#pragma warning(disable: 5030) // attribute 'attribute' is not recognized
#pragma warning(disable: 5039) // 'function': pointer or reference to potentially throwing function passed to extern C function under -EHc. Undefined behavior may occur if this function throws an exception.
#pragma warning(disable: 5045) // Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
#pragma warning(disable: 5052) // Keyword 'char8_t' was introduced in C++20 and requires use of the '/std:c++latest' command-line option
#endif

#ifdef _DEBUG
// Happens only after "Apply code changes"
#pragma warning(disable: 4599) // command line argument number number does not match precompiled header
#endif

#endif

#ifdef __GNUC__
// https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

#pragma GCC diagnostic ignored "-Wunknown-pragmas"

// TODO: some of these might be useful
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"

#endif

#ifdef __clang__
// https://clang.llvm.org/docs/DiagnosticsReference.html

#pragma clang diagnostic ignored "-Wunknown-warning-option"

// TODO: some of these might be useful
#pragma clang diagnostic ignored "-Wc++98-compat"
#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wcovered-switch-default"
#pragma clang diagnostic ignored "-Wctad-maybe-unsupported"
#pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
#pragma clang diagnostic ignored "-Wenum-compare"
#pragma clang diagnostic ignored "-Wexit-time-destructors"
#pragma clang diagnostic ignored "-Wglobal-constructors"
#pragma clang diagnostic ignored "-Wgnu-anonymous-struct"
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
#pragma clang diagnostic ignored "-Wkeyword-macro"
#pragma clang diagnostic ignored "-Wlanguage-extension-token"
#pragma clang diagnostic ignored "-Wmicrosoft-enum-value"
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
#pragma clang diagnostic ignored "-Wnested-anon-types"
#pragma clang diagnostic ignored "-Wnonportable-system-include-path"
#pragma clang diagnostic ignored "-Wpadded"
#pragma clang diagnostic ignored "-Wreturn-std-move-in-c++11"
#pragma clang diagnostic ignored "-Wreserved-identifier"
#pragma clang diagnostic ignored "-Wreserved-id-macro"
#pragma clang diagnostic ignored "-Wshadow-field-in-constructor"
#pragma clang diagnostic ignored "-Wshadow-field"
#pragma clang diagnostic ignored "-Wsign-conversion"
#pragma clang diagnostic ignored "-Wswitch-enum"
#pragma clang diagnostic ignored "-Wundefined-func-template"
#pragma clang diagnostic ignored "-Wunknown-pragmas"
#pragma clang diagnostic ignored "-Wunused-member-function"
#pragma clang diagnostic ignored "-Wunused-parameter"
#pragma clang diagnostic ignored "-Wweak-vtables"
#endif
<|endoftext|>


<commit_before>/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "TouchEventEmitter.h"

namespace facebook {
namespace react {

#pragma mark - Touches

static void setTouchPayloadOnObject(
    jsi::Object &object,
    jsi::Runtime &runtime,
    Touch const &touch) {
  object.setProperty(runtime, "locationX", touch.offsetPoint.x);
  object.setProperty(runtime, "locationY", touch.offsetPoint.y);
  object.setProperty(runtime, "pageX", touch.pagePoint.x);
  object.setProperty(runtime, "pageY", touch.pagePoint.y);
  object.setProperty(runtime, "screenX", touch.screenPoint.x);
  object.setProperty(runtime, "screenY", touch.screenPoint.y);
  object.setProperty(runtime, "identifier", touch.identifier);
  object.setProperty(runtime, "target", touch.target);
  object.setProperty(runtime, "timestamp", touch.timestamp * 1000);
  object.setProperty(runtime, "force", touch.force);
}

static jsi::Value touchesPayload(
    jsi::Runtime &runtime,
    Touches const &touches) {
  auto array = jsi::Array(runtime, touches.size());
  int i = 0;
  for (auto const &touch : touches) {
    auto object = jsi::Object(runtime);
    setTouchPayloadOnObject(object, runtime, touch);
    array.setValueAtIndex(runtime, i++, object);
  }
  return array;
}

static jsi::Value touchEventPayload(
    jsi::Runtime &runtime,
    TouchEvent const &event) {
  auto object = jsi::Object(runtime);
  object.setProperty(
      runtime, "touches", touchesPayload(runtime, event.touches));
  object.setProperty(
      runtime, "changedTouches", touchesPayload(runtime, event.changedTouches));
  object.setProperty(
      runtime, "targetTouches", touchesPayload(runtime, event.targetTouches));

  if (!event.changedTouches.empty()) {
    auto const &firstChangedTouch = *event.changedTouches.begin();
    setTouchPayloadOnObject(object, runtime, firstChangedTouch);
  }
  return object;
}

static jsi::Value pointerEventPayload(
    jsi::Runtime &runtime,
    PointerEvent const &event) {
  auto object = jsi::Object(runtime);
  object.setProperty(runtime, "pointerId", event.pointerId);
  object.setProperty(runtime, "pressure", event.pressure);
  object.setProperty(runtime, "pointerType", event.pointerType);
  object.setProperty(runtime, "clientX", event.clientPoint.x);
  object.setProperty(runtime, "clientY", event.clientPoint.y);
  object.setProperty(runtime, "width", event.width);
  object.setProperty(runtime, "height", event.height);
  object.setProperty(runtime, "tiltX", event.tiltX);
  object.setProperty(runtime, "tiltY", event.tiltY);
  object.setProperty(runtime, "detail", event.detail);
  object.setProperty(runtime, "buttons", event.buttons);
  object.setProperty(runtime, "tangentialPressure", event.tangentialPressure);
  object.setProperty(runtime, "twist", event.twist);
  return object;
}

void TouchEventEmitter::dispatchTouchEvent(
    std::string type,
    TouchEvent const &event,
    EventPriority priority,
    RawEvent::Category category) const {
  dispatchEvent(
      std::move(type),
      [event](jsi::Runtime &runtime) {
        return touchEventPayload(runtime, event);
      },
      priority,
      category);
}

void TouchEventEmitter::dispatchPointerEvent(
    std::string type,
    PointerEvent const &event,
    EventPriority priority,
    RawEvent::Category category) const {
  dispatchEvent(
      std::move(type),
      [event](jsi::Runtime &runtime) {
        return pointerEventPayload(runtime, event);
      },
      priority,
      category);
}

void TouchEventEmitter::onTouchStart(TouchEvent const &event) const {
  dispatchTouchEvent(
      "touchStart",
      event,
      EventPriority::AsynchronousBatched,
      RawEvent::Category::ContinuousStart);
}

void TouchEventEmitter::onTouchMove(TouchEvent const &event) const {
  dispatchUniqueEvent("touchMove", [event](jsi::Runtime &runtime) {
    return touchEventPayload(runtime, event);
  });
}

void TouchEventEmitter::onTouchEnd(TouchEvent const &event) const {
  dispatchTouchEvent(
      "touchEnd",
      event,
      EventPriority::AsynchronousBatched,
      RawEvent::Category::ContinuousEnd);
}

void TouchEventEmitter::onTouchCancel(TouchEvent const &event) const {
  dispatchTouchEvent(
      "touchCancel",
      event,
      EventPriority::AsynchronousBatched,
      RawEvent::Category::ContinuousEnd);
}

void TouchEventEmitter::onPointerCancel(const PointerEvent &event) const {
  dispatchPointerEvent(
      "pointerCancel",
      event,
      EventPriority::AsynchronousBatched,
      RawEvent::Category::ContinuousEnd);
}

void TouchEventEmitter::onPointerDown(const PointerEvent &event) const {
  dispatchPointerEvent(
      "pointerDown",
      event,
      EventPriority::AsynchronousBatched,
      RawEvent::Category::ContinuousStart);
}

void TouchEventEmitter::onPointerMove(const PointerEvent &event) const {
  dispatchUniqueEvent("pointerMove", [event](jsi::Runtime &runtime) {
    return pointerEventPayload(runtime, event);
  });
}

void TouchEventEmitter::onPointerUp(const PointerEvent &event) const {
  dispatchPointerEvent(
      "pointerUp",
      event,
      EventPriority::AsynchronousBatched,
      RawEvent::Category::ContinuousEnd);
}

void TouchEventEmitter::onPointerEnter(const PointerEvent &event) const {
  dispatchPointerEvent(
      "pointerEnter",
      event,
      EventPriority::AsynchronousBatched,
      RawEvent::Category::ContinuousStart);
}

void TouchEventEmitter::onPointerLeave(const PointerEvent &event) const {
  dispatchPointerEvent(
      "pointerLeave",
      event,
      EventPriority::AsynchronousBatched,
      RawEvent::Category::ContinuousEnd);
}

void TouchEventEmitter::onPointerOver(const PointerEvent &event) const {
  dispatchPointerEvent(
      "pointerOver",
      event,
      EventPriority::AsynchronousBatched,
      RawEvent::Category::ContinuousStart);
}

void TouchEventEmitter::onPointerOut(const PointerEvent &event) const {
  dispatchPointerEvent(
      "pointerOut",
      event,
      EventPriority::AsynchronousBatched,
      RawEvent::Category::ContinuousStart);
}

} // namespace react
} // namespace facebook
<commit_msg>Add x/y & pageX/Y implementations to PointerEvent interface<commit_after>/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "TouchEventEmitter.h"

namespace facebook {
namespace react {

#pragma mark - Touches

static void setTouchPayloadOnObject(
    jsi::Object &object,
    jsi::Runtime &runtime,
    Touch const &touch) {
  object.setProperty(runtime, "locationX", touch.offsetPoint.x);
  object.setProperty(runtime, "locationY", touch.offsetPoint.y);
  object.setProperty(runtime, "pageX", touch.pagePoint.x);
  object.setProperty(runtime, "pageY", touch.pagePoint.y);
  object.setProperty(runtime, "screenX", touch.screenPoint.x);
  object.setProperty(runtime, "screenY", touch.screenPoint.y);
  object.setProperty(runtime, "identifier", touch.identifier);
  object.setProperty(runtime, "target", touch.target);
  object.setProperty(runtime, "timestamp", touch.timestamp * 1000);
  object.setProperty(runtime, "force", touch.force);
}

static jsi::Value touchesPayload(
    jsi::Runtime &runtime,
    Touches const &touches) {
  auto array = jsi::Array(runtime, touches.size());
  int i = 0;
  for (auto const &touch : touches) {
    auto object = jsi::Object(runtime);
    setTouchPayloadOnObject(object, runtime, touch);
    array.setValueAtIndex(runtime, i++, object);
  }
  return array;
}

static jsi::Value touchEventPayload(
    jsi::Runtime &runtime,
    TouchEvent const &event) {
  auto object = jsi::Object(runtime);
  object.setProperty(
      runtime, "touches", touchesPayload(runtime, event.touches));
  object.setProperty(
      runtime, "changedTouches", touchesPayload(runtime, event.changedTouches));
  object.setProperty(
      runtime, "targetTouches", touchesPayload(runtime, event.targetTouches));

  if (!event.changedTouches.empty()) {
    auto const &firstChangedTouch = *event.changedTouches.begin();
    setTouchPayloadOnObject(object, runtime, firstChangedTouch);
  }
  return object;
}

static jsi::Value pointerEventPayload(
    jsi::Runtime &runtime,
    PointerEvent const &event) {
  auto object = jsi::Object(runtime);
  object.setProperty(runtime, "pointerId", event.pointerId);
  object.setProperty(runtime, "pressure", event.pressure);
  object.setProperty(runtime, "pointerType", event.pointerType);
  object.setProperty(runtime, "clientX", event.clientPoint.x);
  object.setProperty(runtime, "clientY", event.clientPoint.y);
  // x/y are an alias to clientX/Y
  object.setProperty(runtime, "x", event.clientPoint.x);
  object.setProperty(runtime, "y", event.clientPoint.y);
  // since RN doesn't have a scrollable root, pageX/Y will always equal
  // clientX/Y
  object.setProperty(runtime, "pageX", event.clientPoint.x);
  object.setProperty(runtime, "pageY", event.clientPoint.y);
  object.setProperty(runtime, "width", event.width);
  object.setProperty(runtime, "height", event.height);
  object.setProperty(runtime, "tiltX", event.tiltX);
  object.setProperty(runtime, "tiltY", event.tiltY);
  object.setProperty(runtime, "detail", event.detail);
  object.setProperty(runtime, "buttons", event.buttons);
  object.setProperty(runtime, "tangentialPressure", event.tangentialPressure);
  object.setProperty(runtime, "twist", event.twist);
  return object;
}

void TouchEventEmitter::dispatchTouchEvent(
    std::string type,
    TouchEvent const &event,
    EventPriority priority,
    RawEvent::Category category) const {
  dispatchEvent(
      std::move(type),
      [event](jsi::Runtime &runtime) {
        return touchEventPayload(runtime, event);
      },
      priority,
      category);
}

void TouchEventEmitter::dispatchPointerEvent(
    std::string type,
    PointerEvent const &event,
    EventPriority priority,
    RawEvent::Category category) const {
  dispatchEvent(
      std::move(type),
      [event](jsi::Runtime &runtime) {
        return pointerEventPayload(runtime, event);
      },
      priority,
      category);
}

void TouchEventEmitter::onTouchStart(TouchEvent const &event) const {
  dispatchTouchEvent(
      "touchStart",
      event,
      EventPriority::AsynchronousBatched,
      RawEvent::Category::ContinuousStart);
}

void TouchEventEmitter::onTouchMove(TouchEvent const &event) const {
  dispatchUniqueEvent("touchMove", [event](jsi::Runtime &runtime) {
    return touchEventPayload(runtime, event);
  });
}

void TouchEventEmitter::onTouchEnd(TouchEvent const &event) const {
  dispatchTouchEvent(
      "touchEnd",
      event,
      EventPriority::AsynchronousBatched,
      RawEvent::Category::ContinuousEnd);
}

void TouchEventEmitter::onTouchCancel(TouchEvent const &event) const {
  dispatchTouchEvent(
      "touchCancel",
      event,
      EventPriority::AsynchronousBatched,
      RawEvent::Category::ContinuousEnd);
}

void TouchEventEmitter::onPointerCancel(const PointerEvent &event) const {
  dispatchPointerEvent(
      "pointerCancel",
      event,
      EventPriority::AsynchronousBatched,
      RawEvent::Category::ContinuousEnd);
}

void TouchEventEmitter::onPointerDown(const PointerEvent &event) const {
  dispatchPointerEvent(
      "pointerDown",
      event,
      EventPriority::AsynchronousBatched,
      RawEvent::Category::ContinuousStart);
}

void TouchEventEmitter::onPointerMove(const PointerEvent &event) const {
  dispatchUniqueEvent("pointerMove", [event](jsi::Runtime &runtime) {
    return pointerEventPayload(runtime, event);
  });
}

void TouchEventEmitter::onPointerUp(const PointerEvent &event) const {
  dispatchPointerEvent(
      "pointerUp",
      event,
      EventPriority::AsynchronousBatched,
      RawEvent::Category::ContinuousEnd);
}

void TouchEventEmitter::onPointerEnter(const PointerEvent &event) const {
  dispatchPointerEvent(
      "pointerEnter",
      event,
      EventPriority::AsynchronousBatched,
      RawEvent::Category::ContinuousStart);
}

void TouchEventEmitter::onPointerLeave(const PointerEvent &event) const {
  dispatchPointerEvent(
      "pointerLeave",
      event,
      EventPriority::AsynchronousBatched,
      RawEvent::Category::ContinuousEnd);
}

void TouchEventEmitter::onPointerOver(const PointerEvent &event) const {
  dispatchPointerEvent(
      "pointerOver",
      event,
      EventPriority::AsynchronousBatched,
      RawEvent::Category::ContinuousStart);
}

void TouchEventEmitter::onPointerOut(const PointerEvent &event) const {
  dispatchPointerEvent(
      "pointerOut",
      event,
      EventPriority::AsynchronousBatched,
      RawEvent::Category::ContinuousStart);
}

} // namespace react
} // namespace facebook
<|endoftext|>


<commit_before>#ifndef STAN_MATH_PRIM_FUN_LOWER_REG_INC_GAMMA_HPP
#define STAN_MATH_PRIM_FUN_LOWER_REG_INC_GAMMA_HPP

#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/err.hpp>
#include <stan/math/prim/fun/digamma.hpp>
#include <stan/math/prim/fun/exp.hpp>
#include <stan/math/prim/fun/gamma_p.hpp>
#include <stan/math/prim/fun/grad_reg_inc_gamma.hpp>
#include <stan/math/prim/fun/is_any_nan.hpp>
#include <stan/math/prim/fun/is_inf.hpp>
#include <stan/math/prim/fun/lgamma.hpp>
#include <stan/math/prim/fun/log.hpp>
#include <stan/math/prim/fun/log1p.hpp>
#include <stan/math/prim/fun/sqrt.hpp>
#include <stan/math/prim/fun/tgamma.hpp>
#include <stan/math/prim/fun/value_of_rec.hpp>
#include <limits>
#include <cmath>

namespace stan {
namespace math {

/**
 * Computes the gradient of the lower regularized incomplete
 * gamma function.
 *
 * The lower incomplete gamma function
 * derivative w.r.t its first parameter (a) seems to have no
 * standard source.  It also appears to have no widely known
 * approximate implementation.  Gautschi (1979) has a thorough
 * discussion of the calculation of the lower regularized
 * incomplete gamma function itself and some stability issues.
 *
 * Reference: Gautschi, Walter (1979) ACM Transactions on
 * mathematical software. 5(4):466-481
 *
 * We implemented calculations for d(gamma_p)/da by taking
 * derivatives of formulas suggested by Gauschi and others and
 * testing them against an outside source (Mathematica). We
 * took three implementations which can cover the range {a:[0,20],
 * z:[0,30]} with absolute error < 1e-10 with the exception of
 * values near (0,0) where the error is near 1e-5.  Relative error
 * is also <<1e-6 except for regions where the gradient approaches
 * zero.
 *
 * Gautschi suggests calculating the lower incomplete gamma
 * function for small to moderate values of $z$ using the
 * approximation:
 *
 * \f[
 *  \frac{\gamma(a,z)}{\Gamma(a)}=z^a e^-z
 *    \sum_n=0^\infty \frac{z^n}{\Gamma(a+n+1)}
 * \f]
 *
 * We write the derivative in the form:
 *
 * \f[
 *   \frac{d\gamma(a,z)\Gamma(a)}{da} = \frac{\log z}{e^z}
 *     \sum_n=0^\infty \frac{z^{a+n}}{\Gamma(a+n+1)}
 *   - \frac{1}{e^z}
 *     \sum_n=0^\infty \frac{z^{a+n}}{\Gamma(a+n+1)}\psi^0(a+n+1)
 * \f]
 *
 * This calculation is sufficiently accurate for small $a$ and
 * small $z$.  For larger values and $a$ and $z$ we use it in its
 * log form:
 *
 * \f[
 *   \frac{d \gamma(a,z)\Gamma(a)}{da} = \frac{\log z}{e^z}
 *     \sum_n=0^\infty \exp[(a+n)\log z - \log\Gamma(a+n+1)]
 *   - \sum_n=0^\infty \exp[(a+n)\log z - \log\Gamma(a+n+1) +
 *       \log\psi^0(a+n+1)]
 * \f]
 *
 * For large $z$, Gauschi recommends using the upper incomplete
 * Gamma instead and the negative of its derivative turns out to be
 * more stable and accurate for larger $z$ and for some combinations
 * of $a$ and $z$. This is a log-scale implementation of the
 * derivative of the formulation suggested by Gauschi (1979). For
 * some values it defers to the negative of the gradient
 * for the gamma_q function. This is based on the suggestion by Gauschi
 * (1979) that for large values of $z$ it is better to
 * carry out calculations using the upper incomplete Gamma function.
 *
 * Branching for choice of implementation for the lower incomplete
 * regularized gamma function gradient. The derivative based on
 * Gautschi's formulation appears to be sufficiently accurate
 * everywhere except for large z and small to moderate a. The
 * intersection between the two regions is a radius 12 quarter circle
 * centered at a=0, z=30 although both implementations are
 * satisfactory near the intersection.
 *
 * Some limits that could be treated, e.g., infinite z should
 * return tgamma(a) * digamma(a), throw instead to match the behavior of,
 * e.g., boost::math::gamma_p
 *
 * @tparam T1 type of a
 * @tparam T2 type of z
 * @param[in] a shared with complete Gamma
 * @param[in] z value to integrate up to
 * @param[in] precision series terminates when increment falls below
 * this value.
 * @param[in] max_steps number of terms to sum before throwing
 * @throw std::domain_error if the series does not converge to
 * requested precision before max_steps.
 *
 */
template <typename T1, typename T2>
return_type_t<T1, T2> grad_reg_lower_inc_gamma(const T1& a, const T2& z,
                                               double precision = 1e-10,
                                               int max_steps = 1e5) {
  using std::exp;
  using std::log;
  using std::pow;
  using std::sqrt;

  using TP = return_type_t<T1, T2>;

  if (is_any_nan(a, z)) {
    return std::numeric_limits<TP>::quiet_NaN();
  }

  check_positive_finite("grad_reg_lower_inc_gamma", "a", a);

  if (z == 0.0) {
    return 0.0;
  }
  check_positive_finite("grad_reg_lower_inc_gamma", "z", z);

  if ((a < 0.8 && z > 15.0) || (a < 12.0 && z > 30.0)
      || a < sqrt(-756 - value_of_rec(z) * value_of_rec(z)
                  + 60 * value_of_rec(z))) {
    T1 tg = tgamma(a);
    T1 dig = digamma(a);
    return -grad_reg_inc_gamma(a, z, tg, dig, max_steps, precision);
  }

  T2 log_z = log(z);
  T2 emz = exp(-z);

  int n = 0;
  T1 a_plus_n = a;
  TP sum_a = 0.0;
  T1 lgamma_a_plus_1 = lgamma(a + 1);
  T1 lgamma_a_plus_n_plus_1 = lgamma_a_plus_1;
  TP term;
  while (true) {
    term = exp(a_plus_n * log_z - lgamma_a_plus_n_plus_1);
    sum_a += term;
    if (term <= precision) {
      break;
    }
    if (n >= max_steps) {
      throw_domain_error("grad_reg_lower_inc_gamma", "n (internal counter)",
                         max_steps, "exceeded ",
                         " iterations, gamma_p(a,z) gradient (a) "
                         "did not converge.");
    }
    ++n;
    lgamma_a_plus_n_plus_1 += log1p(a_plus_n);
    ++a_plus_n;
  }

  n = 1;
  a_plus_n = a + 1;
  TP digammap1 = digamma(a + 1);
  TP sum_b = digammap1 * exp(a * log_z - lgamma_a_plus_1);
  lgamma_a_plus_n_plus_1 = lgamma_a_plus_1 + log(a_plus_n);
  while (true) {
    digammap1 += 1 / a_plus_n;
    term = exp(a_plus_n * log_z - lgamma_a_plus_n_plus_1)
           * digammap1;
    sum_b += term;
    if (term <= precision) {
      return emz * (log_z * sum_a - sum_b);
    }
    if (n >= max_steps) {
      throw_domain_error("grad_reg_lower_inc_gamma", "n (internal counter)",
                         max_steps, "exceeded ",
                         " iterations, gamma_p(a,z) gradient (a) "
                         "did not converge.");
    }
    ++n;
    lgamma_a_plus_n_plus_1 += log1p(a_plus_n);
    ++a_plus_n;
  }
}

}  // namespace math
}  // namespace stan

#endif
<commit_msg>[Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1<commit_after>#ifndef STAN_MATH_PRIM_FUN_LOWER_REG_INC_GAMMA_HPP
#define STAN_MATH_PRIM_FUN_LOWER_REG_INC_GAMMA_HPP

#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/err.hpp>
#include <stan/math/prim/fun/digamma.hpp>
#include <stan/math/prim/fun/exp.hpp>
#include <stan/math/prim/fun/gamma_p.hpp>
#include <stan/math/prim/fun/grad_reg_inc_gamma.hpp>
#include <stan/math/prim/fun/is_any_nan.hpp>
#include <stan/math/prim/fun/is_inf.hpp>
#include <stan/math/prim/fun/lgamma.hpp>
#include <stan/math/prim/fun/log.hpp>
#include <stan/math/prim/fun/log1p.hpp>
#include <stan/math/prim/fun/sqrt.hpp>
#include <stan/math/prim/fun/tgamma.hpp>
#include <stan/math/prim/fun/value_of_rec.hpp>
#include <limits>
#include <cmath>

namespace stan {
namespace math {

/**
 * Computes the gradient of the lower regularized incomplete
 * gamma function.
 *
 * The lower incomplete gamma function
 * derivative w.r.t its first parameter (a) seems to have no
 * standard source.  It also appears to have no widely known
 * approximate implementation.  Gautschi (1979) has a thorough
 * discussion of the calculation of the lower regularized
 * incomplete gamma function itself and some stability issues.
 *
 * Reference: Gautschi, Walter (1979) ACM Transactions on
 * mathematical software. 5(4):466-481
 *
 * We implemented calculations for d(gamma_p)/da by taking
 * derivatives of formulas suggested by Gauschi and others and
 * testing them against an outside source (Mathematica). We
 * took three implementations which can cover the range {a:[0,20],
 * z:[0,30]} with absolute error < 1e-10 with the exception of
 * values near (0,0) where the error is near 1e-5.  Relative error
 * is also <<1e-6 except for regions where the gradient approaches
 * zero.
 *
 * Gautschi suggests calculating the lower incomplete gamma
 * function for small to moderate values of $z$ using the
 * approximation:
 *
 * \f[
 *  \frac{\gamma(a,z)}{\Gamma(a)}=z^a e^-z
 *    \sum_n=0^\infty \frac{z^n}{\Gamma(a+n+1)}
 * \f]
 *
 * We write the derivative in the form:
 *
 * \f[
 *   \frac{d\gamma(a,z)\Gamma(a)}{da} = \frac{\log z}{e^z}
 *     \sum_n=0^\infty \frac{z^{a+n}}{\Gamma(a+n+1)}
 *   - \frac{1}{e^z}
 *     \sum_n=0^\infty \frac{z^{a+n}}{\Gamma(a+n+1)}\psi^0(a+n+1)
 * \f]
 *
 * This calculation is sufficiently accurate for small $a$ and
 * small $z$.  For larger values and $a$ and $z$ we use it in its
 * log form:
 *
 * \f[
 *   \frac{d \gamma(a,z)\Gamma(a)}{da} = \frac{\log z}{e^z}
 *     \sum_n=0^\infty \exp[(a+n)\log z - \log\Gamma(a+n+1)]
 *   - \sum_n=0^\infty \exp[(a+n)\log z - \log\Gamma(a+n+1) +
 *       \log\psi^0(a+n+1)]
 * \f]
 *
 * For large $z$, Gauschi recommends using the upper incomplete
 * Gamma instead and the negative of its derivative turns out to be
 * more stable and accurate for larger $z$ and for some combinations
 * of $a$ and $z$. This is a log-scale implementation of the
 * derivative of the formulation suggested by Gauschi (1979). For
 * some values it defers to the negative of the gradient
 * for the gamma_q function. This is based on the suggestion by Gauschi
 * (1979) that for large values of $z$ it is better to
 * carry out calculations using the upper incomplete Gamma function.
 *
 * Branching for choice of implementation for the lower incomplete
 * regularized gamma function gradient. The derivative based on
 * Gautschi's formulation appears to be sufficiently accurate
 * everywhere except for large z and small to moderate a. The
 * intersection between the two regions is a radius 12 quarter circle
 * centered at a=0, z=30 although both implementations are
 * satisfactory near the intersection.
 *
 * Some limits that could be treated, e.g., infinite z should
 * return tgamma(a) * digamma(a), throw instead to match the behavior of,
 * e.g., boost::math::gamma_p
 *
 * @tparam T1 type of a
 * @tparam T2 type of z
 * @param[in] a shared with complete Gamma
 * @param[in] z value to integrate up to
 * @param[in] precision series terminates when increment falls below
 * this value.
 * @param[in] max_steps number of terms to sum before throwing
 * @throw std::domain_error if the series does not converge to
 * requested precision before max_steps.
 *
 */
template <typename T1, typename T2>
return_type_t<T1, T2> grad_reg_lower_inc_gamma(const T1& a, const T2& z,
                                               double precision = 1e-10,
                                               int max_steps = 1e5) {
  using std::exp;
  using std::log;
  using std::pow;
  using std::sqrt;

  using TP = return_type_t<T1, T2>;

  if (is_any_nan(a, z)) {
    return std::numeric_limits<TP>::quiet_NaN();
  }

  check_positive_finite("grad_reg_lower_inc_gamma", "a", a);

  if (z == 0.0) {
    return 0.0;
  }
  check_positive_finite("grad_reg_lower_inc_gamma", "z", z);

  if ((a < 0.8 && z > 15.0) || (a < 12.0 && z > 30.0)
      || a < sqrt(-756 - value_of_rec(z) * value_of_rec(z)
                  + 60 * value_of_rec(z))) {
    T1 tg = tgamma(a);
    T1 dig = digamma(a);
    return -grad_reg_inc_gamma(a, z, tg, dig, max_steps, precision);
  }

  T2 log_z = log(z);
  T2 emz = exp(-z);

  int n = 0;
  T1 a_plus_n = a;
  TP sum_a = 0.0;
  T1 lgamma_a_plus_1 = lgamma(a + 1);
  T1 lgamma_a_plus_n_plus_1 = lgamma_a_plus_1;
  TP term;
  while (true) {
    term = exp(a_plus_n * log_z - lgamma_a_plus_n_plus_1);
    sum_a += term;
    if (term <= precision) {
      break;
    }
    if (n >= max_steps) {
      throw_domain_error("grad_reg_lower_inc_gamma", "n (internal counter)",
                         max_steps, "exceeded ",
                         " iterations, gamma_p(a,z) gradient (a) "
                         "did not converge.");
    }
    ++n;
    lgamma_a_plus_n_plus_1 += log1p(a_plus_n);
    ++a_plus_n;
  }

  n = 1;
  a_plus_n = a + 1;
  TP digammap1 = digamma(a + 1);
  TP sum_b = digammap1 * exp(a * log_z - lgamma_a_plus_1);
  lgamma_a_plus_n_plus_1 = lgamma_a_plus_1 + log(a_plus_n);
  while (true) {
    digammap1 += 1 / a_plus_n;
    term = exp(a_plus_n * log_z - lgamma_a_plus_n_plus_1) * digammap1;
    sum_b += term;
    if (term <= precision) {
      return emz * (log_z * sum_a - sum_b);
    }
    if (n >= max_steps) {
      throw_domain_error("grad_reg_lower_inc_gamma", "n (internal counter)",
                         max_steps, "exceeded ",
                         " iterations, gamma_p(a,z) gradient (a) "
                         "did not converge.");
    }
    ++n;
    lgamma_a_plus_n_plus_1 += log1p(a_plus_n);
    ++a_plus_n;
  }
}

}  // namespace math
}  // namespace stan

#endif
<|endoftext|>


<commit_before>#ifndef STAN_MATH_PRIM_FUNCTOR_COUPLED_ODE_OBSERVER_HPP
#define STAN_MATH_PRIM_FUNCTOR_COUPLED_ODE_OBSERVER_HPP

#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/err.hpp>
#include <stan/math/prim/fun/sum.hpp>

#include <vector>

namespace stan {
namespace math {

/**
 * Observer for the coupled states.  Holds a reference to an
 * externally defined vector of vectors passed in at construction time
 * which holds the final result on the AD stack. Thus, whenever any of
 * the inputs is varying, then the output will be varying as well. The
 * sensitivities of the initials and the parameters are taken from the
 * coupled state in the order as defined by the
 * coupled_ode_system. The sensitivities at each time-point is simply
 * the ODE RHS evaluated at that time point.
 *
 * The output of this class is for all time-points in the ts vector
 * which does not contain the initial time-point by the convention
 * used in stan-math.
 *
 */
template <typename F, typename T1, typename T2, typename T_t0, typename T_ts>
struct coupled_ode_observer {
  using return_t = return_type_t<T1, T2, T_t0, T_ts>;

  using ops_partials_t
      = operands_and_partials<std::vector<T1>, std::vector<T2>, T_t0, T_ts>;

  const F& f_;
  const std::vector<T1>& y0_;
  const T_t0& t0_;
  const std::vector<T_ts>& ts_;
  const std::vector<T2>& theta_;
  const std::vector<double>& x_;
  const std::vector<int>& x_int_;
  std::ostream* msgs_;
  std::vector<std::vector<return_t>>& y_;
  const std::size_t N_;
  const std::size_t M_;
  const std::size_t index_offset_theta_;
  std::vector<double> f_y0_t0_;
  int next_ts_index_;

  /**
   * Construct a coupled ODE observer for the specified coupled
   * vector.
   *
   * @tparam F type of ODE system function.
   * @tparam T1 type of scalars for initial values.
   * @tparam T2 type of scalars for parameters.
   * @tparam T_t0 type of scalar of initial time point.
   * @tparam T_ts type of time-points where ODE solution is returned.
   * @param[in] f functor for the base ordinary differential equation.
   * @param[in] y0 initial state.
   * @param[in] theta parameter vector for the ODE.
   * @param[in] t0 initial time.
   * @param[in] ts times of the desired solutions, in strictly
   * increasing order, all greater than the initial time.
   * @param[in] x continuous data vector for the ODE.
   * @param[in] x_int integer data vector for the ODE.
   * @param[out] msgs the print stream for warning messages.
   * @param[out] y reference to a vector of vector of the final return
   */
  coupled_ode_observer(const F& f, const std::vector<T1>& y0,
                       const std::vector<T2>& theta, const T_t0& t0,
                       const std::vector<T_ts>& ts,
                       const std::vector<double>& x,
                       const std::vector<int>& x_int, std::ostream* msgs,
                       std::vector<std::vector<return_t>>& y)
      : f_(f),
        y0_(y0),
        t0_(t0),
        ts_(ts),
        theta_(theta),
        x_(x),
        x_int_(x_int),
        msgs_(msgs),
        y_(y),
        N_(y0.size()),
        M_(theta.size()),
        index_offset_theta_(is_constant_all<T1>::value ? 0 : N_ * N_),
        next_ts_index_(0) {
    if (!is_constant_all<T_t0>::value) {
      f_y0_t0_
          = f(value_of(t0), value_of(y0), value_of(theta_), x_, x_int_, msgs_);
      check_size_match("coupled_ode_observer", "dy_dt", f_y0_t0_.size(),
                       "states", N_);
    }
  }

  /**
   * Callback function for ODE solvers to record values. The coupled
   * state returned from the solver is added directly to the AD tree.
   *
   * The coupled state follows the convention as defined in the
   * coupled_ode_system. In brief, the coupled state consists of {f,
   * df/dy0, df/dtheta}. Here df/dy0 and df/dtheta are only present if
   * their respective sensitivites have been requested.
   *
   * @param coupled_state solution at the specified time.
   * @param t time of solution. The time must correspond to the
   * element ts[next_ts_index_]
   */
  void operator()(const std::vector<double>& coupled_state, double t) {
    check_less("coupled_ode_observer", "time-state number", next_ts_index_,
               ts_.size());

    std::vector<return_t> yt;
    yt.reserve(N_);

    ops_partials_t ops_partials(y0_, theta_, t0_, ts_[next_ts_index_]);

    std::vector<double> dy_dt;
    if (!is_constant_all<T_ts>::value) {
      std::vector<double> y_dbl(coupled_state.begin(),
                                coupled_state.begin() + N_);
      dy_dt = f_(value_of(ts_[next_ts_index_]), y_dbl, value_of(theta_), x_,
                 x_int_, msgs_);
      check_size_match("coupled_ode_observer", "dy_dt", dy_dt.size(), "states",
                       N_);
    }

    for (size_t j = 0; j < N_; j++) {
      // iterate over parameters for each equation
      if (!is_constant_all<T1>::value) {
        for (std::size_t k = 0; k < N_; k++) {
          ops_partials.edge1_.partials_[k] = coupled_state[N_ + N_ * k + j];
        }
      }

      if (!is_constant_all<T2>::value) {
        for (std::size_t k = 0; k < M_; k++) {
          ops_partials.edge2_.partials_[k]
              = coupled_state[N_ + index_offset_theta_ + N_ * k + j];
        }
      }

      if (!is_constant_all<T_t0>::value) {
        ops_partials.edge3_.partials_[0] = -f_y0_t0_[j];
      }

      if (!is_constant_all<T_ts>::value) {
        ops_partials.edge4_.partials_[0] = dy_dt[j];
      }

      yt.emplace_back(ops_partials.build(coupled_state[j]));
    }

    y_.emplace_back(yt);
    next_ts_index_++;
  }
};

}  // namespace math

}  // namespace stan

#endif
<commit_msg>Updated naming in ode observer (Issue #1833)<commit_after>#ifndef STAN_MATH_PRIM_FUNCTOR_COUPLED_ODE_OBSERVER_HPP
#define STAN_MATH_PRIM_FUNCTOR_COUPLED_ODE_OBSERVER_HPP

#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/err.hpp>
#include <stan/math/prim/fun/sum.hpp>

#include <vector>

namespace stan {
namespace math {

/**
 * Observer for the coupled states.  Holds a reference to an
 * externally defined vector of vectors passed in at construction time
 * which holds the final result on the AD stack. Thus, whenever any of
 * the inputs is varying, then the output will be varying as well. The
 * sensitivities of the initials and the parameters are taken from the
 * coupled state in the order as defined by the
 * coupled_ode_system. The sensitivities at each time-point is simply
 * the ODE RHS evaluated at that time point.
 *
 * The output of this class is for all time-points in the ts vector
 * which does not contain the initial time-point by the convention
 * used in stan-math.
 *
 */
template <typename F, typename T1, typename T2, typename T_t0, typename T_ts>
struct coupled_ode_observer {
  using return_t = return_type_t<T1, T2, T_t0, T_ts>;

  using ops_partials_t
      = operands_and_partials<std::vector<T1>, std::vector<T2>, T_t0, T_ts>;

  const F& f_;
  const std::vector<T1>& y0_;
  const T_t0& t0_;
  const std::vector<T_ts>& ts_;
  const std::vector<T2>& theta_;
  const std::vector<double>& x_;
  const std::vector<int>& x_int_;
  std::ostream* msgs_;
  std::vector<std::vector<return_t>>& y_;
  const std::size_t N_;
  const std::size_t M_;
  const std::size_t index_offset_theta_;
  std::vector<double> initial_dy_dt_;
  int next_ts_index_;

  /**
   * Construct a coupled ODE observer for the specified coupled
   * vector.
   *
   * @tparam F type of ODE system function.
   * @tparam T1 type of scalars for initial values.
   * @tparam T2 type of scalars for parameters.
   * @tparam T_t0 type of scalar of initial time point.
   * @tparam T_ts type of time-points where ODE solution is returned.
   * @param[in] f functor for the base ordinary differential equation.
   * @param[in] y0 initial state.
   * @param[in] theta parameter vector for the ODE.
   * @param[in] t0 initial time.
   * @param[in] ts times of the desired solutions, in strictly
   * increasing order, all greater than the initial time.
   * @param[in] x continuous data vector for the ODE.
   * @param[in] x_int integer data vector for the ODE.
   * @param[out] msgs the print stream for warning messages.
   * @param[out] y reference to a vector of vector of the final return
   */
  coupled_ode_observer(const F& f, const std::vector<T1>& y0,
                       const std::vector<T2>& theta, const T_t0& t0,
                       const std::vector<T_ts>& ts,
                       const std::vector<double>& x,
                       const std::vector<int>& x_int, std::ostream* msgs,
                       std::vector<std::vector<return_t>>& y)
      : f_(f),
        y0_(y0),
        t0_(t0),
        ts_(ts),
        theta_(theta),
        x_(x),
        x_int_(x_int),
        msgs_(msgs),
        y_(y),
        N_(y0.size()),
        M_(theta.size()),
        index_offset_theta_(is_constant_all<T1>::value ? 0 : N_ * N_),
        next_ts_index_(0) {
    if (!is_constant_all<T_t0>::value) {
      initial_dy_dt_
          = f(value_of(t0), value_of(y0), value_of(theta_), x_, x_int_, msgs_);
      check_size_match("coupled_ode_observer", "dy_dt", initial_dy_dt_.size(),
                       "states", N_);
    }
  }

  /**
   * Callback function for ODE solvers to record values. The coupled
   * state returned from the solver is added directly to the AD tree.
   *
   * The coupled state follows the convention as defined in the
   * coupled_ode_system. In brief, the coupled state consists of {f,
   * df/dy0, df/dtheta}. Here df/dy0 and df/dtheta are only present if
   * their respective sensitivites have been requested.
   *
   * @param coupled_state solution at the specified time.
   * @param t time of solution. The time must correspond to the
   * element ts[next_ts_index_]
   */
  void operator()(const std::vector<double>& coupled_state, double t) {
    check_less("coupled_ode_observer", "time-state number", next_ts_index_,
               ts_.size());

    std::vector<return_t> yt;
    yt.reserve(N_);

    ops_partials_t ops_partials(y0_, theta_, t0_, ts_[next_ts_index_]);

    std::vector<double> dy_dt;
    if (!is_constant_all<T_ts>::value) {
      std::vector<double> y_dbl(coupled_state.begin(),
                                coupled_state.begin() + N_);
      dy_dt = f_(value_of(ts_[next_ts_index_]), y_dbl, value_of(theta_), x_,
                 x_int_, msgs_);
      check_size_match("coupled_ode_observer", "dy_dt", dy_dt.size(), "states",
                       N_);
    }

    for (size_t j = 0; j < N_; j++) {
      // iterate over parameters for each equation
      if (!is_constant_all<T1>::value) {
        for (std::size_t k = 0; k < N_; k++) {
          ops_partials.edge1_.partials_[k] = coupled_state[N_ + N_ * k + j];
        }
      }

      if (!is_constant_all<T2>::value) {
        for (std::size_t k = 0; k < M_; k++) {
          ops_partials.edge2_.partials_[k]
              = coupled_state[N_ + index_offset_theta_ + N_ * k + j];
        }
      }

      if (!is_constant_all<T_t0>::value) {
        ops_partials.edge3_.partials_[0] = -initial_dy_dt_[j];
      }

      if (!is_constant_all<T_ts>::value) {
        ops_partials.edge4_.partials_[0] = dy_dt[j];
      }

      yt.emplace_back(ops_partials.build(coupled_state[j]));
    }

    y_.emplace_back(yt);
    next_ts_index_++;
  }
};

}  // namespace math

}  // namespace stan

#endif
<|endoftext|>


<commit_before>#ifndef LUCE_HEADER_FUNCTIONAL_FUNCTION_HH
#define LUCE_HEADER_FUNCTIONAL_FUNCTION_HH
#include <Luce/Configuration.hh>

#include <Luce/Utility/NonComparable.hh>
#include <Luce/Utility/NonCopyable.hh>

#include <cstddef>

namespace Luce
{
	namespace Functional
	{
		namespace Detail
		{
			template<typename Result_>
			struct GetResultType_;
			template<typename Result_>
			struct GetResultType_<Result_()> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetResultType_)

			public:
				typedef Result_ Type;
			};
			template<typename Result_, typename Param_>
			struct GetResultType_<Result_(Param_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetResultType_)

			public:
				typedef Result_ Type;
			};

			template<typename Result_>
			struct GetParameterType_;
			template<typename Result_>
			struct GetParameterType_<Result_()> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef void Type0;
			};
			template<typename Result_, typename Param0_>
			struct GetParameterType_<Result_(Param0_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef Param0_ Type0;
			};
			template<typename Result_, typename Param0_, typename Param1_>
			struct GetParameterType_<Result_(Param0_, Param1_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef Param0_ Type0;
				typedef Param1_ Type1;
			};
			template<typename Result_, typename Param0_, typename Param1_,
				typename Param2_>
				struct GetParameterType_<Result_(Param0_, Param1_, Param2_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef Param0_ Type0;
				typedef Param1_ Type1;
				typedef Param2_ Type2;
			};
			template<typename Result_, typename Param0_, typename Param1_,
				typename Param2_, typename Param3_>
				struct GetParameterType_<Result_(Param0_, Param1_, Param2_,
												 Param3_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef Param0_ Type0;
				typedef Param1_ Type1;
				typedef Param2_ Type2;
				typedef Param3_ Type3;
			};
			template<typename Result_, typename Param0_, typename Param1_,
				typename Param2_, typename Param3_, typename Param4_>
				struct GetParameterType_<Result_(Param0_, Param1_, Param2_,
												 Param3_, Param4_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef Param0_ Type0;
				typedef Param1_ Type1;
				typedef Param2_ Type2;
				typedef Param3_ Type3;
				typedef Param4_ Type4;
			};
			template<typename Result_, typename Param0_, typename Param1_,
				typename Param2_, typename Param3_, typename Param4_,
				typename Param5_>
				struct GetParameterType_<Result_(Param0_, Param1_, Param2_,
												 Param3_, Param4_, Param5_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef Param0_ Type0;
				typedef Param1_ Type1;
				typedef Param2_ Type2;
				typedef Param3_ Type3;
				typedef Param4_ Type4;
				typedef Param5_ Type5;
			};
			template<typename Result_, typename Param0_, typename Param1_,
				typename Param2_, typename Param3_, typename Param4_,
				typename Param5_, typename Param6_>
				struct GetParameterType_<Result_(Param0_, Param1_, Param2_,
												 Param3_, Param4_, Param5_,
												 Param6_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef Param0_ Type0;
				typedef Param1_ Type1;
				typedef Param2_ Type2;
				typedef Param3_ Type3;
				typedef Param4_ Type4;
				typedef Param5_ Type5;
				typedef Param6_ Type6;
			};
			template<typename Result_, typename Param0_, typename Param1_,
				typename Param2_, typename Param3_, typename Param4_,
				typename Param5_, typename Param6_, typename Param7_>
				struct GetParameterType_<Result_(Param0_, Param1_, Param2_,
												 Param3_, Param4_, Param5_,
												 Param6_, Param7_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef Param0_ Type0;
				typedef Param1_ Type1;
				typedef Param2_ Type2;
				typedef Param3_ Type3;
				typedef Param4_ Type4;
				typedef Param5_ Type5;
				typedef Param6_ Type6;
				typedef Param7_ Type7;
			};
			template<typename Result_, typename Param0_, typename Param1_,
				typename Param2_, typename Param3_, typename Param4_,
				typename Param5_, typename Param6_, typename Param7_,
				typename Param8_>
				struct GetParameterType_<Result_(Param0_, Param1_, Param2_,
												 Param3_, Param4_, Param5_,
												 Param6_, Param7_, Param8_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef Param0_ Type0;
				typedef Param1_ Type1;
				typedef Param2_ Type2;
				typedef Param3_ Type3;
				typedef Param4_ Type4;
				typedef Param5_ Type5;
				typedef Param6_ Type6;
				typedef Param7_ Type7;
				typedef Param8_ Type8;
			};
			template<typename Result_, typename Param0_, typename Param1_,
				typename Param2_, typename Param3_, typename Param4_,
				typename Param5_, typename Param6_, typename Param7_,
				typename Param8_, typename Param9_>
				struct GetParameterType_<Result_(Param0_, Param1_, Param2_,
												 Param3_, Param4_, Param5_,
												 Param6_, Param7_, Param8_,
												 Param9_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef Param0_ Type0;
				typedef Param1_ Type1;
				typedef Param2_ Type2;
				typedef Param3_ Type3;
				typedef Param4_ Type4;
				typedef Param5_ Type5;
				typedef Param6_ Type6;
				typedef Param7_ Type7;
				typedef Param8_ Type8;
				typedef Param9_ Type9;
			};
		}

		template<typename Ty_>
		class Function
		{

		};
	}
}

#endif<commit_msg>Update Function<commit_after>#ifndef LUCE_HEADER_FUNCTIONAL_FUNCTION_HH
#define LUCE_HEADER_FUNCTIONAL_FUNCTION_HH
#include <Luce/Configuration.hh>

#include <Luce/Utility/NonComparable.hh>
#include <Luce/Utility/NonCopyable.hh>

#include <cstddef>

namespace Luce
{
	namespace Functional
	{
		namespace Detail
		{
			template<typename Result_>
			struct GetResultType_;
			template<typename Result_>
			struct GetResultType_<Result_()> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetResultType_)

			public:
				typedef Result_ Type;
			};
			template<typename Result_, typename Param_>
			struct GetResultType_<Result_(Param_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetResultType_)

			public:
				typedef Result_ Type;
			};

			template<typename Result_>
			struct GetParameterType_;
			template<typename Result_>
			struct GetParameterType_<Result_()> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef void Type0;
			};
			template<typename Result_, typename Param0_>
			struct GetParameterType_<Result_(Param0_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef Param0_ Type0;
			};
			template<typename Result_, typename Param0_, typename Param1_>
			struct GetParameterType_<Result_(Param0_, Param1_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef Param0_ Type0;
				typedef Param1_ Type1;
			};
			template<typename Result_, typename Param0_, typename Param1_,
				typename Param2_>
				struct GetParameterType_<Result_(Param0_, Param1_, Param2_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef Param0_ Type0;
				typedef Param1_ Type1;
				typedef Param2_ Type2;
			};
			template<typename Result_, typename Param0_, typename Param1_,
				typename Param2_, typename Param3_>
				struct GetParameterType_<Result_(Param0_, Param1_, Param2_,
												 Param3_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef Param0_ Type0;
				typedef Param1_ Type1;
				typedef Param2_ Type2;
				typedef Param3_ Type3;
			};
			template<typename Result_, typename Param0_, typename Param1_,
				typename Param2_, typename Param3_, typename Param4_>
				struct GetParameterType_<Result_(Param0_, Param1_, Param2_,
												 Param3_, Param4_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef Param0_ Type0;
				typedef Param1_ Type1;
				typedef Param2_ Type2;
				typedef Param3_ Type3;
				typedef Param4_ Type4;
			};
			template<typename Result_, typename Param0_, typename Param1_,
				typename Param2_, typename Param3_, typename Param4_,
				typename Param5_>
				struct GetParameterType_<Result_(Param0_, Param1_, Param2_,
												 Param3_, Param4_, Param5_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef Param0_ Type0;
				typedef Param1_ Type1;
				typedef Param2_ Type2;
				typedef Param3_ Type3;
				typedef Param4_ Type4;
				typedef Param5_ Type5;
			};
			template<typename Result_, typename Param0_, typename Param1_,
				typename Param2_, typename Param3_, typename Param4_,
				typename Param5_, typename Param6_>
				struct GetParameterType_<Result_(Param0_, Param1_, Param2_,
												 Param3_, Param4_, Param5_,
												 Param6_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef Param0_ Type0;
				typedef Param1_ Type1;
				typedef Param2_ Type2;
				typedef Param3_ Type3;
				typedef Param4_ Type4;
				typedef Param5_ Type5;
				typedef Param6_ Type6;
			};
			template<typename Result_, typename Param0_, typename Param1_,
				typename Param2_, typename Param3_, typename Param4_,
				typename Param5_, typename Param6_, typename Param7_>
				struct GetParameterType_<Result_(Param0_, Param1_, Param2_,
												 Param3_, Param4_, Param5_,
												 Param6_, Param7_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef Param0_ Type0;
				typedef Param1_ Type1;
				typedef Param2_ Type2;
				typedef Param3_ Type3;
				typedef Param4_ Type4;
				typedef Param5_ Type5;
				typedef Param6_ Type6;
				typedef Param7_ Type7;
			};
			template<typename Result_, typename Param0_, typename Param1_,
				typename Param2_, typename Param3_, typename Param4_,
				typename Param5_, typename Param6_, typename Param7_,
				typename Param8_>
				struct GetParameterType_<Result_(Param0_, Param1_, Param2_,
												 Param3_, Param4_, Param5_,
												 Param6_, Param7_, Param8_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef Param0_ Type0;
				typedef Param1_ Type1;
				typedef Param2_ Type2;
				typedef Param3_ Type3;
				typedef Param4_ Type4;
				typedef Param5_ Type5;
				typedef Param6_ Type6;
				typedef Param7_ Type7;
				typedef Param8_ Type8;
			};
			template<typename Result_, typename Param0_, typename Param1_,
				typename Param2_, typename Param3_, typename Param4_,
				typename Param5_, typename Param6_, typename Param7_,
				typename Param8_, typename Param9_>
				struct GetParameterType_<Result_(Param0_, Param1_, Param2_,
												 Param3_, Param4_, Param5_,
												 Param6_, Param7_, Param8_,
												 Param9_)> LUCE_MACRO_FINAL
				: private Utility::NonComparable, private Utility::NonCopyable
			{
				LUCE_MACRO_CANNOT_PARENT(GetParameterType_)

			public:
				typedef Param0_ Type0;
				typedef Param1_ Type1;
				typedef Param2_ Type2;
				typedef Param3_ Type3;
				typedef Param4_ Type4;
				typedef Param5_ Type5;
				typedef Param6_ Type6;
				typedef Param7_ Type7;
				typedef Param8_ Type8;
				typedef Param9_ Type9;
			};
		}

		template<typename Ty_>
		class Function
		{
		public:
			typedef typename Detail::GetResultType_<Ty_>::Type ReturnType;

		private:
			typedef Function<Ty_> My_;
		};
	}

	using Luce::Functional::Function;
}

#endif<|endoftext|>


<commit_before>// RegisterTypes_osimCommon.cpp
// author: Frank C. Anderson
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/*
 * Copyright (c) 2007, Stanford University. All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  - Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *  - Neither the name of the Stanford University nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "Object.h"
#include "VisibleObject.h"
#include "RegisterTypes_osimCommon.h"
#include "FunctionSet.h"
#include "GCVSplineSet.h"
#include "ScaleSet.h"
#include "GCVSpline.h"
#include "VectorGCVSplineR1R3.h"
#include "Scale.h"
#include "SimmSpline.h"
#include "Constant.h"
#include "Sine.h"
#include "StepFunction.h"
#include "LinearFunction.h"
#include "PiecewiseLinearFunction.h"
#include "MultiplierFunction.h"
#include "DisplayGeometry.h"
#include "GeometrySet.h"
#include "VisibleObject.h"
#include "ObjectGroup.h"
#include "StateFunction.h"

#include <string>
#include <iostream>
#include <exception>

using namespace OpenSim;
using namespace std;

//_____________________________________________________________________________
/**
 * The purpose of this routine is to register all class types exported by
 * the osimCommon library.
 */
OSIMCOMMON_API void RegisterTypes_osimCommon()
{
  try {

	Object::registerType( FunctionSet() );
	Object::registerType( GCVSplineSet() );
	Object::registerType( ScaleSet() );

	Object::registerType( GCVSpline() );
	Object::registerType( VectorGCVSplineR1R3() );
	Object::registerType( Scale() );
	Object::registerType( SimmSpline() );
	Object::registerType( Constant() );
	Object::registerType( Sine() );
	Object::registerType( StepFunction() );
	Object::registerType( LinearFunction() );
	Object::registerType( PiecewiseLinearFunction() );
	Object::registerType( MultiplierFunction() );
	Object::registerType( DisplayGeometry() );
	Object::registerType( GeometrySet() );
	Object::registerType( VisibleObject() );
	Object::registerType( ObjectGroup() );

	// To support old type name of "natCubicSpline"
	Object::renameType("natCubicSpline", "SimmSpline");

  } catch (const std::exception& e) {
    std::cerr
        << "ERROR during osimCommon Object registration:\n"
        << e.what() << "\n";
  }
}

<commit_msg>per Matt M: temporarily map NaturalCubicSpline to SimmSpline. Later we'll add a real natural cubic spline.<commit_after>// RegisterTypes_osimCommon.cpp
// author: Frank C. Anderson
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/*
 * Copyright (c) 2007, Stanford University. All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  - Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *  - Neither the name of the Stanford University nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "Object.h"
#include "VisibleObject.h"
#include "RegisterTypes_osimCommon.h"
#include "FunctionSet.h"
#include "GCVSplineSet.h"
#include "ScaleSet.h"
#include "GCVSpline.h"
#include "VectorGCVSplineR1R3.h"
#include "Scale.h"
#include "SimmSpline.h"
#include "Constant.h"
#include "Sine.h"
#include "StepFunction.h"
#include "LinearFunction.h"
#include "PiecewiseLinearFunction.h"
#include "MultiplierFunction.h"
#include "DisplayGeometry.h"
#include "GeometrySet.h"
#include "VisibleObject.h"
#include "ObjectGroup.h"
#include "StateFunction.h"

#include <string>
#include <iostream>
#include <exception>

using namespace OpenSim;
using namespace std;

//_____________________________________________________________________________
/**
 * The purpose of this routine is to register all class types exported by
 * the osimCommon library.
 */
OSIMCOMMON_API void RegisterTypes_osimCommon()
{
  try {

	Object::registerType( FunctionSet() );
	Object::registerType( GCVSplineSet() );
	Object::registerType( ScaleSet() );

	Object::registerType( GCVSpline() );
	Object::registerType( VectorGCVSplineR1R3() );
	Object::registerType( Scale() );
	Object::registerType( SimmSpline() );
	Object::registerType( Constant() );
	Object::registerType( Sine() );
	Object::registerType( StepFunction() );
	Object::registerType( LinearFunction() );
	Object::registerType( PiecewiseLinearFunction() );
	Object::registerType( MultiplierFunction() );
	Object::registerType( DisplayGeometry() );
	Object::registerType( GeometrySet() );
	Object::registerType( VisibleObject() );
	Object::registerType( ObjectGroup() );

    // TODO: temporarily map old NaturalCubicSpline (which wasn't a
    // natural cubic spline) to renamed SimmSpline class. Later we
    // will replace this with an actual natural cubic spline.
	Object::renameType("NaturalCubicSpline", "SimmSpline");
	// To support older type name of "natCubicSpline"
	Object::renameType("natCubicSpline", "SimmSpline");

  } catch (const std::exception& e) {
    std::cerr
        << "ERROR during osimCommon Object registration:\n"
        << e.what() << "\n";
  }
}

<|endoftext|>