<commit_before>// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/

#ifndef TAO_PEGTL_MEMORY_INPUT_HPP
#define TAO_PEGTL_MEMORY_INPUT_HPP

#include <cstddef>
#include <cstdint>
#include <cstring>
#include <string>
#include <type_traits>
#include <utility>

#include "config.hpp"
#include "eol.hpp"
#include "normal.hpp"
#include "nothing.hpp"
#include "position.hpp"
#include "tracking_mode.hpp"

#include "internal/action_input.hpp"
#include "internal/at.hpp"
#include "internal/bump_impl.hpp"
#include "internal/eolf.hpp"
#include "internal/iterator.hpp"
#include "internal/marker.hpp"
#include "internal/until.hpp"

namespace tao
{
   namespace TAO_PEGTL_NAMESPACE
   {
      namespace internal
      {
         template< tracking_mode, typename Eol, typename Source >
         class memory_input_base;

         template< typename Eol, typename Source >
         class memory_input_base< tracking_mode::IMMEDIATE, Eol, Source >
         {
         public:
            using iterator_t = internal::iterator;

            template< typename T >
            memory_input_base( const iterator_t& in_begin, const char* in_end, T&& in_source ) noexcept( std::is_nothrow_constructible< Source, T&& >::value )
               : m_begin( in_begin.data ),
                 m_current( in_begin ),
                 m_end( in_end ),
                 m_source( std::forward< T >( in_source ) )
            {
            }

            template< typename T >
            memory_input_base( const char* in_begin, const char* in_end, T&& in_source ) noexcept( std::is_nothrow_constructible< Source, T&& >::value )
               : m_begin( in_begin ),
                 m_current( in_begin ),
                 m_end( in_end ),
                 m_source( std::forward< T >( in_source ) )
            {
            }

            memory_input_base( const memory_input_base& ) = delete;
            memory_input_base( memory_input_base&& ) = delete;

            ~memory_input_base() = default;

            memory_input_base operator=( const memory_input_base& ) = delete;
            memory_input_base operator=( memory_input_base&& ) = delete;

            const char* current() const noexcept
            {
               return m_current.data;
            }

            const char* begin() const noexcept
            {
               return m_begin;
            }

            const char* end( const std::size_t /*unused*/ = 0 ) const noexcept
            {
               return m_end;
            }

            std::size_t byte() const noexcept
            {
               return m_current.byte;
            }

            std::size_t line() const noexcept
            {
               return m_current.line;
            }

            std::size_t byte_in_line() const noexcept
            {
               return m_current.byte_in_line;
            }

            void bump( const std::size_t in_count = 1 ) noexcept
            {
               internal::bump( m_current, in_count, Eol::ch );
            }

            void bump_in_this_line( const std::size_t in_count = 1 ) noexcept
            {
               internal::bump_in_this_line( m_current, in_count );
            }

            void bump_to_next_line( const std::size_t in_count = 1 ) noexcept
            {
               internal::bump_to_next_line( m_current, in_count );
            }

            TAO_PEGTL_NAMESPACE::position position( const iterator_t& it ) const
            {
               return TAO_PEGTL_NAMESPACE::position( it, m_source );
            }

            void restart( const std::size_t in_byte = 0, const std::size_t in_line = 1, const std::size_t in_byte_in_line = 0 )
            {
               m_current.data = m_begin;
               m_current.byte = in_byte;
               m_current.line = in_line;
               m_current.byte_in_line = in_byte_in_line;
            }

         protected:
            const char* const m_begin;
            iterator_t m_current;
            const char* const m_end;
            const Source m_source;
         };

         template< typename Eol, typename Source >
         class memory_input_base< tracking_mode::LAZY, Eol, Source >
         {
         public:
            using iterator_t = const char*;

            template< typename T >
            memory_input_base( const internal::iterator& in_begin, const char* in_end, T&& in_source ) noexcept( std::is_nothrow_constructible< Source, T&& >::value )
               : m_begin( in_begin ),
                 m_current( in_begin.data ),
                 m_end( in_end ),
                 m_source( std::forward< T >( in_source ) )
            {
            }

            template< typename T >
            memory_input_base( const char* in_begin, const char* in_end, T&& in_source ) noexcept( std::is_nothrow_constructible< Source, T&& >::value )
               : m_begin( in_begin ),
                 m_current( in_begin ),
                 m_end( in_end ),
                 m_source( std::forward< T >( in_source ) )
            {
            }

            memory_input_base( const memory_input_base& ) = delete;
            memory_input_base( memory_input_base&& ) = delete;

            ~memory_input_base() = default;

            memory_input_base operator=( const memory_input_base& ) = delete;
            memory_input_base operator=( memory_input_base&& ) = delete;

            const char* current() const noexcept
            {
               return m_current;
            }

            const char* begin() const noexcept
            {
               return m_begin.data;
            }

            const char* end( const std::size_t /*unused*/ = 0 ) const noexcept
            {
               return m_end;
            }

            std::size_t byte() const noexcept
            {
               return std::size_t( current() - m_begin.data );
            }

            void bump( const std::size_t in_count = 1 ) noexcept
            {
               m_current += in_count;
            }

            void bump_in_this_line( const std::size_t in_count = 1 ) noexcept
            {
               m_current += in_count;
            }

            void bump_to_next_line( const std::size_t in_count = 1 ) noexcept
            {
               m_current += in_count;
            }

            TAO_PEGTL_NAMESPACE::position position( const iterator_t it ) const
            {
               internal::iterator c( m_begin );
               internal::bump( c, std::size_t( it - m_begin.data ), Eol::ch );
               return TAO_PEGTL_NAMESPACE::position( c, m_source );
            }

            void restart()
            {
               m_current = m_begin.data;
            }

         protected:
            const internal::iterator m_begin;
            iterator_t m_current;
            const char* const m_end;
            const Source m_source;
         };

      }  // namespace internal

      template< tracking_mode P = tracking_mode::IMMEDIATE, typename Eol = eol::lf_crlf, typename Source = std::string >
      class memory_input
         : public internal::memory_input_base< P, Eol, Source >
      {
      public:
         static constexpr tracking_mode tracking_mode_v = P;

         using eol_t = Eol;
         using source_t = Source;

         using typename internal::memory_input_base< P, Eol, Source >::iterator_t;

         using action_t = internal::action_input< memory_input >;

         using internal::memory_input_base< P, Eol, Source >::memory_input_base;

         template< typename T >
         memory_input( const char* in_begin, const std::size_t in_size, T&& in_source ) noexcept( std::is_nothrow_constructible< Source, T&& >::value )
            : memory_input( in_begin, in_begin + in_size, std::forward< T >( in_source ) )
         {
         }

         template< typename T >
         memory_input( const std::string& in_string, T&& in_source ) noexcept( std::is_nothrow_constructible< Source, T&& >::value )
            : memory_input( in_string.data(), in_string.size(), std::forward< T >( in_source ) )
         {
         }

         template< typename T >
         memory_input( std::string&&, T&& ) = delete;

         template< typename T >
         memory_input( const char* in_begin, T&& in_source ) noexcept( std::is_nothrow_constructible< Source, T&& >::value )
            : memory_input( in_begin, std::strlen( in_begin ), std::forward< T >( in_source ) )
         {
         }

         template< typename T >
         memory_input( const char* in_begin, const char* in_end, T&& in_source, const std::size_t in_byte, const std::size_t in_line, const std::size_t in_byte_in_line ) noexcept( std::is_nothrow_constructible< Source, T&& >::value )
            : memory_input( { in_begin, in_byte, in_line, in_byte_in_line }, in_end, std::forward< T >( in_source ) )
         {
         }

         memory_input( const memory_input& ) = delete;
         memory_input( memory_input&& ) = delete;

         ~memory_input() = default;

         memory_input operator=( const memory_input& ) = delete;
         memory_input operator=( memory_input&& ) = delete;

         const Source& source() const noexcept
         {
            return this->m_source;
         }

         bool empty() const noexcept
         {
            return this->current() == this->end();
         }

         std::size_t size( const std::size_t /*unused*/ = 0 ) const noexcept
         {
            return std::size_t( this->end() - this->current() );
         }

         char peek_char( const std::size_t offset = 0 ) const noexcept
         {
            return this->current()[ offset ];
         }

         std::uint8_t peek_byte( const std::size_t offset = 0 ) const noexcept
         {
            return static_cast< std::uint8_t >( peek_char( offset ) );
         }

         iterator_t& iterator() noexcept
         {
            return this->m_current;
         }

         const iterator_t& iterator() const noexcept
         {
            return this->m_current;
         }

         using internal::memory_input_base< P, Eol, Source >::position;

         TAO_PEGTL_NAMESPACE::position position() const
         {
            return position( iterator() );
         }

         void discard() const noexcept
         {
         }

         void require( const std::size_t /*unused*/ ) const noexcept
         {
         }

         template< rewind_mode M >
         internal::marker< iterator_t, M > mark() noexcept
         {
            return internal::marker< iterator_t, M >( iterator() );
         }

         const char* at( const TAO_PEGTL_NAMESPACE::position& p ) const noexcept
         {
            return this->begin() + p.byte;
         }

         const char* begin_of_line( const TAO_PEGTL_NAMESPACE::position& p ) const noexcept
         {
            return at( p ) - p.byte_in_line;
         }

         const char* end_of_line( const TAO_PEGTL_NAMESPACE::position& p ) const noexcept;

         std::string line_as_string( const TAO_PEGTL_NAMESPACE::position& p ) const
         {
            return std::string( begin_of_line( p ), end_of_line( p ) );
         }
      };

      template< tracking_mode P, typename Eol, typename Source >
      const char* memory_input< P, Eol, Source >::end_of_line( const TAO_PEGTL_NAMESPACE::position& p ) const noexcept
      {
         TAO_PEGTL_NAMESPACE::memory_input< tracking_mode::LAZY, Eol, const char* > in( at( p ), this->end(), nullptr );
         normal< internal::until< internal::at< internal::eolf > > >::match< apply_mode::NOTHING, rewind_mode::DONTCARE, nothing, normal >( in );
         return in.current();
      }

   }  // namespace TAO_PEGTL_NAMESPACE

}  // namespace tao

#endif
<commit_msg>Try fix MSVC ICE<commit_after>// Copyright (c) 2014-2018 Dr. Colin Hirsch and Daniel Frey
// Please see LICENSE for license or visit https://github.com/taocpp/PEGTL/

#ifndef TAO_PEGTL_MEMORY_INPUT_HPP
#define TAO_PEGTL_MEMORY_INPUT_HPP

#include <cstddef>
#include <cstdint>
#include <cstring>
#include <string>
#include <type_traits>
#include <utility>

#include "config.hpp"
#include "eol.hpp"
#include "normal.hpp"
#include "nothing.hpp"
#include "position.hpp"
#include "tracking_mode.hpp"

#include "internal/action_input.hpp"
#include "internal/at.hpp"
#include "internal/bump_impl.hpp"
#include "internal/eolf.hpp"
#include "internal/iterator.hpp"
#include "internal/marker.hpp"
#include "internal/until.hpp"

namespace tao
{
   namespace TAO_PEGTL_NAMESPACE
   {
      namespace internal
      {
         template< typename Eol >
         const char* find_end_of_line( const char* begin, const char* end ) noexcept;

         template< tracking_mode, typename Eol, typename Source >
         class memory_input_base;

         template< typename Eol, typename Source >
         class memory_input_base< tracking_mode::IMMEDIATE, Eol, Source >
         {
         public:
            using iterator_t = internal::iterator;

            template< typename T >
            memory_input_base( const iterator_t& in_begin, const char* in_end, T&& in_source ) noexcept( std::is_nothrow_constructible< Source, T&& >::value )
               : m_begin( in_begin.data ),
                 m_current( in_begin ),
                 m_end( in_end ),
                 m_source( std::forward< T >( in_source ) )
            {
            }

            template< typename T >
            memory_input_base( const char* in_begin, const char* in_end, T&& in_source ) noexcept( std::is_nothrow_constructible< Source, T&& >::value )
               : m_begin( in_begin ),
                 m_current( in_begin ),
                 m_end( in_end ),
                 m_source( std::forward< T >( in_source ) )
            {
            }

            memory_input_base( const memory_input_base& ) = delete;
            memory_input_base( memory_input_base&& ) = delete;

            ~memory_input_base() = default;

            memory_input_base operator=( const memory_input_base& ) = delete;
            memory_input_base operator=( memory_input_base&& ) = delete;

            const char* current() const noexcept
            {
               return m_current.data;
            }

            const char* begin() const noexcept
            {
               return m_begin;
            }

            const char* end( const std::size_t /*unused*/ = 0 ) const noexcept
            {
               return m_end;
            }

            std::size_t byte() const noexcept
            {
               return m_current.byte;
            }

            std::size_t line() const noexcept
            {
               return m_current.line;
            }

            std::size_t byte_in_line() const noexcept
            {
               return m_current.byte_in_line;
            }

            void bump( const std::size_t in_count = 1 ) noexcept
            {
               internal::bump( m_current, in_count, Eol::ch );
            }

            void bump_in_this_line( const std::size_t in_count = 1 ) noexcept
            {
               internal::bump_in_this_line( m_current, in_count );
            }

            void bump_to_next_line( const std::size_t in_count = 1 ) noexcept
            {
               internal::bump_to_next_line( m_current, in_count );
            }

            TAO_PEGTL_NAMESPACE::position position( const iterator_t& it ) const
            {
               return TAO_PEGTL_NAMESPACE::position( it, m_source );
            }

            void restart( const std::size_t in_byte = 0, const std::size_t in_line = 1, const std::size_t in_byte_in_line = 0 )
            {
               m_current.data = m_begin;
               m_current.byte = in_byte;
               m_current.line = in_line;
               m_current.byte_in_line = in_byte_in_line;
            }

         protected:
            const char* const m_begin;
            iterator_t m_current;
            const char* const m_end;
            const Source m_source;
         };

         template< typename Eol, typename Source >
         class memory_input_base< tracking_mode::LAZY, Eol, Source >
         {
         public:
            using iterator_t = const char*;

            template< typename T >
            memory_input_base( const internal::iterator& in_begin, const char* in_end, T&& in_source ) noexcept( std::is_nothrow_constructible< Source, T&& >::value )
               : m_begin( in_begin ),
                 m_current( in_begin.data ),
                 m_end( in_end ),
                 m_source( std::forward< T >( in_source ) )
            {
            }

            template< typename T >
            memory_input_base( const char* in_begin, const char* in_end, T&& in_source ) noexcept( std::is_nothrow_constructible< Source, T&& >::value )
               : m_begin( in_begin ),
                 m_current( in_begin ),
                 m_end( in_end ),
                 m_source( std::forward< T >( in_source ) )
            {
            }

            memory_input_base( const memory_input_base& ) = delete;
            memory_input_base( memory_input_base&& ) = delete;

            ~memory_input_base() = default;

            memory_input_base operator=( const memory_input_base& ) = delete;
            memory_input_base operator=( memory_input_base&& ) = delete;

            const char* current() const noexcept
            {
               return m_current;
            }

            const char* begin() const noexcept
            {
               return m_begin.data;
            }

            const char* end( const std::size_t /*unused*/ = 0 ) const noexcept
            {
               return m_end;
            }

            std::size_t byte() const noexcept
            {
               return std::size_t( current() - m_begin.data );
            }

            void bump( const std::size_t in_count = 1 ) noexcept
            {
               m_current += in_count;
            }

            void bump_in_this_line( const std::size_t in_count = 1 ) noexcept
            {
               m_current += in_count;
            }

            void bump_to_next_line( const std::size_t in_count = 1 ) noexcept
            {
               m_current += in_count;
            }

            TAO_PEGTL_NAMESPACE::position position( const iterator_t it ) const
            {
               internal::iterator c( m_begin );
               internal::bump( c, std::size_t( it - m_begin.data ), Eol::ch );
               return TAO_PEGTL_NAMESPACE::position( c, m_source );
            }

            void restart()
            {
               m_current = m_begin.data;
            }

         protected:
            const internal::iterator m_begin;
            iterator_t m_current;
            const char* const m_end;
            const Source m_source;
         };

      }  // namespace internal

      template< tracking_mode P = tracking_mode::IMMEDIATE, typename Eol = eol::lf_crlf, typename Source = std::string >
      class memory_input
         : public internal::memory_input_base< P, Eol, Source >
      {
      public:
         static constexpr tracking_mode tracking_mode_v = P;

         using eol_t = Eol;
         using source_t = Source;

         using typename internal::memory_input_base< P, Eol, Source >::iterator_t;

         using action_t = internal::action_input< memory_input >;

         using internal::memory_input_base< P, Eol, Source >::memory_input_base;

         template< typename T >
         memory_input( const char* in_begin, const std::size_t in_size, T&& in_source ) noexcept( std::is_nothrow_constructible< Source, T&& >::value )
            : memory_input( in_begin, in_begin + in_size, std::forward< T >( in_source ) )
         {
         }

         template< typename T >
         memory_input( const std::string& in_string, T&& in_source ) noexcept( std::is_nothrow_constructible< Source, T&& >::value )
            : memory_input( in_string.data(), in_string.size(), std::forward< T >( in_source ) )
         {
         }

         template< typename T >
         memory_input( std::string&&, T&& ) = delete;

         template< typename T >
         memory_input( const char* in_begin, T&& in_source ) noexcept( std::is_nothrow_constructible< Source, T&& >::value )
            : memory_input( in_begin, std::strlen( in_begin ), std::forward< T >( in_source ) )
         {
         }

         template< typename T >
         memory_input( const char* in_begin, const char* in_end, T&& in_source, const std::size_t in_byte, const std::size_t in_line, const std::size_t in_byte_in_line ) noexcept( std::is_nothrow_constructible< Source, T&& >::value )
            : memory_input( { in_begin, in_byte, in_line, in_byte_in_line }, in_end, std::forward< T >( in_source ) )
         {
         }

         memory_input( const memory_input& ) = delete;
         memory_input( memory_input&& ) = delete;

         ~memory_input() = default;

         memory_input operator=( const memory_input& ) = delete;
         memory_input operator=( memory_input&& ) = delete;

         const Source& source() const noexcept
         {
            return this->m_source;
         }

         bool empty() const noexcept
         {
            return this->current() == this->end();
         }

         std::size_t size( const std::size_t /*unused*/ = 0 ) const noexcept
         {
            return std::size_t( this->end() - this->current() );
         }

         char peek_char( const std::size_t offset = 0 ) const noexcept
         {
            return this->current()[ offset ];
         }

         std::uint8_t peek_byte( const std::size_t offset = 0 ) const noexcept
         {
            return static_cast< std::uint8_t >( peek_char( offset ) );
         }

         iterator_t& iterator() noexcept
         {
            return this->m_current;
         }

         const iterator_t& iterator() const noexcept
         {
            return this->m_current;
         }

         using internal::memory_input_base< P, Eol, Source >::position;

         TAO_PEGTL_NAMESPACE::position position() const
         {
            return position( iterator() );
         }

         void discard() const noexcept
         {
         }

         void require( const std::size_t /*unused*/ ) const noexcept
         {
         }

         template< rewind_mode M >
         internal::marker< iterator_t, M > mark() noexcept
         {
            return internal::marker< iterator_t, M >( iterator() );
         }

         const char* at( const TAO_PEGTL_NAMESPACE::position& p ) const noexcept
         {
            return this->begin() + p.byte;
         }

         const char* begin_of_line( const TAO_PEGTL_NAMESPACE::position& p ) const noexcept
         {
            return at( p ) - p.byte_in_line;
         }

         const char* end_of_line( const TAO_PEGTL_NAMESPACE::position& p ) const noexcept
         {
            return internal::find_end_of_line< Eol >( at( p ), this->end() );
         }

         std::string line_as_string( const TAO_PEGTL_NAMESPACE::position& p ) const
         {
            return std::string( begin_of_line( p ), end_of_line( p ) );
         }
      };

      namespace internal
      {
         template< typename Eol >
         const char* find_end_of_line( const char* begin, const char* end ) noexcept
         {
            memory_input< tracking_mode::LAZY, Eol, const char* > in( begin, end, nullptr );
            normal< internal::until< internal::at< internal::eolf > > >::match< apply_mode::NOTHING, rewind_mode::DONTCARE, nothing, normal >( in );
            return in.current();
         }

      }  // namespace internal

   }  // namespace TAO_PEGTL_NAMESPACE

}  // namespace tao

#endif
<|endoftext|>


<commit_before>#include "opt/ssa/condition_value_range.h"

#include "design/design_util.h"
#include "iroha/i_design.h"
#include "iroha/stl_util.h"
#include "opt/opt_util.h"
#include "opt/optimizer_log.h"

namespace iroha {
namespace opt {
namespace ssa {

ConditionValueRange::ConditionValueRange(ITable *table, OptimizerLog *opt_log)
    : table_(table), opt_log_(opt_log) {}

ConditionValueRange::~ConditionValueRange() {
  STLDeleteSecondElements(&per_cond_);
  STLDeleteSecondElements(&per_state_);
}

void ConditionValueRange::Build() {
  set<IState *> reachable;
  OptUtil::CollectReachableStates(table_, &reachable);
  vector<pair<IState *, IInsn *>> branches;
  set<IRegister *> cond_regs;
  for (IState *st : reachable) {
    IInsn *tr_insn = DesignUtil::FindTransitionInsn(st);
    if (tr_insn == nullptr) {
      continue;
    }
    if (tr_insn->target_states_.size() < 2) {
      continue;
    }
    branches.push_back(make_pair(st, tr_insn));
    cond_regs.insert(tr_insn->inputs_[0]);
  }
  if (branches.size() != cond_regs.size()) {
    // cond regs are reused by multiple branch insns. gives up.
    return;
  }
  for (auto &p : branches) {
    BuildForTransition(p.first, p.second);
  }
  for (auto &pc : per_cond_) {
    BuildForState(pc.first, pc.second);
  }
  BuildRegToAssignState(reachable);
  DumpToLog();
}

ConditionResult ConditionValueRange::Query(const vector<IRegister *> &regs) {
  ConditionResult res;
  res.cond_reg = nullptr;
  return res;
}

void ConditionValueRange::BuildForTransition(IState *st, IInsn *insn) {
  IRegister *cond = insn->inputs_[0];
  PerCondition *pc = new PerCondition();
  pc->st = st;
  per_cond_[cond] = pc;
  map<IState *, set<int>> values;
  for (int i = 0; i < insn->target_states_.size(); ++i) {
    set<IState *> sts;
    PropagateConditionValue(pc, i, &sts);
    for (IState *st : sts) {
      values[st].insert(i);
    }
  }
  for (auto &p : values) {
    if (p.second.size() == 1) {
      int v = *(p.second.begin());
      IState *s = p.first;
      pc->value[s] = v;
    }
  }
}

void ConditionValueRange::PropagateConditionValue(PerCondition *pc, int nth,
                                                  set<IState *> *sts) {
  set<IState *> seen;
  set<IState *> frontier;
  IInsn *initial_tr_insn = DesignUtil::FindTransitionInsn(pc->st);
  frontier.insert(initial_tr_insn->target_states_[nth]);
  while (frontier.size() > 0) {
    IState *st = *(frontier.begin());
    frontier.erase(st);
    if (st == pc->st) {
      continue;
    }
    if (seen.find(st) != seen.end()) {
      continue;
    }
    seen.insert(st);
    IInsn *tr_insn = DesignUtil::FindTransitionInsn(st);
    if (tr_insn == nullptr) {
      continue;
    }
    for (IState *next_st : tr_insn->target_states_) {
      frontier.insert(next_st);
    }
  }
}

void ConditionValueRange::BuildForState(IRegister *cond, PerCondition *pc) {
  for (auto &sv : pc->value) {
    PerState *ps = GetPerState(sv.first);
    ps->cond_regs.insert(cond);
  }
}

PerState *ConditionValueRange::GetPerState(IState *st) {
  auto it = per_state_.find(st);
  if (it != per_state_.end()) {
    return it->second;
  }
  PerState *ps = new PerState();
  per_state_[st] = ps;
  return ps;
}

void ConditionValueRange::BuildRegToAssignState(set<IState *> reachable) {
  map<IRegister *, set<IState *>> raw;
  for (IState *st : reachable) {
    for (IInsn *insn : st->insns_) {
      for (IRegister *oreg : insn->outputs_) {
        raw[oreg].insert(st);
      }
    }
  }
  for (auto &p : raw) {
    auto &s = p.second;
    if (s.size() == 1) {
      reg_to_assign_state_[p.first] = *(s.begin());
    }
  }
}

void ConditionValueRange::DumpToLog() {
  for (auto &p : per_state_) {
    PerState *ps = p.second;
    if (ps->cond_regs.size() == 0) {
      continue;
    }
    ostream &os = opt_log_->State(p.first);
    os << "[";
    for (IRegister *reg : ps->cond_regs) {
      os << "r" << reg->GetId() << " ";
    }
    os << "]";
  }
}

}  // namespace ssa
}  // namespace opt
}  // namespace iroha
<commit_msg>Fix value propagation.<commit_after>#include "opt/ssa/condition_value_range.h"

#include "design/design_util.h"
#include "iroha/i_design.h"
#include "iroha/stl_util.h"
#include "opt/opt_util.h"
#include "opt/optimizer_log.h"

namespace iroha {
namespace opt {
namespace ssa {

ConditionValueRange::ConditionValueRange(ITable *table, OptimizerLog *opt_log)
    : table_(table), opt_log_(opt_log) {}

ConditionValueRange::~ConditionValueRange() {
  STLDeleteSecondElements(&per_cond_);
  STLDeleteSecondElements(&per_state_);
}

void ConditionValueRange::Build() {
  set<IState *> reachable;
  OptUtil::CollectReachableStates(table_, &reachable);
  vector<pair<IState *, IInsn *>> branches;
  set<IRegister *> cond_regs;
  for (IState *st : reachable) {
    IInsn *tr_insn = DesignUtil::FindTransitionInsn(st);
    if (tr_insn == nullptr) {
      continue;
    }
    if (tr_insn->target_states_.size() < 2) {
      continue;
    }
    branches.push_back(make_pair(st, tr_insn));
    cond_regs.insert(tr_insn->inputs_[0]);
  }
  if (branches.size() != cond_regs.size()) {
    // cond regs are reused by multiple branch insns. gives up.
    return;
  }
  for (auto &p : branches) {
    BuildForTransition(p.first, p.second);
  }
  for (auto &pc : per_cond_) {
    BuildForState(pc.first, pc.second);
  }
  BuildRegToAssignState(reachable);
  DumpToLog();
}

ConditionResult ConditionValueRange::Query(const vector<IRegister *> &regs) {
  ConditionResult res;
  res.cond_reg = nullptr;
  return res;
}

void ConditionValueRange::BuildForTransition(IState *st, IInsn *insn) {
  IRegister *cond = insn->inputs_[0];
  PerCondition *pc = new PerCondition();
  pc->st = st;
  per_cond_[cond] = pc;
  map<IState *, set<int>> values;
  for (int i = 0; i < insn->target_states_.size(); ++i) {
    set<IState *> sts;
    PropagateConditionValue(pc, i, &sts);
    for (IState *st : sts) {
      values[st].insert(i);
    }
  }
  for (auto &p : values) {
    if (p.second.size() == 1) {
      int v = *(p.second.begin());
      IState *s = p.first;
      pc->value[s] = v;
    }
  }
}

void ConditionValueRange::PropagateConditionValue(PerCondition *pc, int nth,
                                                  set<IState *> *sts) {
  set<IState *> seen;
  set<IState *> frontier;
  IInsn *initial_tr_insn = DesignUtil::FindTransitionInsn(pc->st);
  frontier.insert(initial_tr_insn->target_states_[nth]);
  while (frontier.size() > 0) {
    IState *st = *(frontier.begin());
    frontier.erase(st);
    if (st == pc->st) {
      continue;
    }
    if (seen.find(st) != seen.end()) {
      continue;
    }
    seen.insert(st);
    IInsn *tr_insn = DesignUtil::FindTransitionInsn(st);
    if (tr_insn == nullptr) {
      continue;
    }
    sts->insert(st);
    for (IState *next_st : tr_insn->target_states_) {
      frontier.insert(next_st);
    }
  }
}

void ConditionValueRange::BuildForState(IRegister *cond, PerCondition *pc) {
  for (auto &sv : pc->value) {
    PerState *ps = GetPerState(sv.first);
    ps->cond_regs.insert(cond);
  }
}

PerState *ConditionValueRange::GetPerState(IState *st) {
  auto it = per_state_.find(st);
  if (it != per_state_.end()) {
    return it->second;
  }
  PerState *ps = new PerState();
  per_state_[st] = ps;
  return ps;
}

void ConditionValueRange::BuildRegToAssignState(set<IState *> reachable) {
  map<IRegister *, set<IState *>> raw;
  for (IState *st : reachable) {
    for (IInsn *insn : st->insns_) {
      for (IRegister *oreg : insn->outputs_) {
        raw[oreg].insert(st);
      }
    }
  }
  for (auto &p : raw) {
    auto &s = p.second;
    if (s.size() == 1) {
      reg_to_assign_state_[p.first] = *(s.begin());
    }
  }
}

void ConditionValueRange::DumpToLog() {
  for (auto &p : per_state_) {
    PerState *ps = p.second;
    if (ps->cond_regs.size() == 0) {
      continue;
    }
    IState *st = p.first;
    ostream &os = opt_log_->State(p.first);
    os << "[";
    for (IRegister *reg : ps->cond_regs) {
      PerCondition *pc = per_cond_[reg];
      int value = pc->value[st];
      os << "r" << reg->GetId() << ":" << value << " ";
    }
    os << "]";
  }
}

}  // namespace ssa
}  // namespace opt
}  // namespace iroha
<|endoftext|>


<commit_before>#include <Qt3DLogic>

#include "phantomblockcontroller.h"

namespace TMC {

PhantomBlockController::PhantomBlockController(Qt3DCore::QEntity *parent, const Qt3DRender::QCamera *playerCamera)
    : Qt3DCore::QEntity(parent)
    , m_phantomBlock(new PhantomBlock(parent))
    , m_camera(playerCamera)
    , m_frameAction(new Qt3DLogic::QFrameAction()) {

    QObject::connect(m_frameAction, SIGNAL(triggered(float)),
                     this, SLOT(onTriggered(float)));

    this->addComponent(m_frameAction);

}

PhantomBlockController::~PhantomBlockController() {
}

void PhantomBlockController::onTriggered(float) {
    if (m_camera != nullptr) {
        m_phantomBlock->setHided(BLOCK_VISIBLE);
        m_phantomBlock->setPos(Vec3i(m_camera->position() + m_camera->viewVector() / 7.0));
    }
}

}
<commit_msg>Fixed PhantomBlock coordinates.<commit_after>#include <Qt3DLogic>

#include "phantomblockcontroller.h"

namespace TMC {

PhantomBlockController::PhantomBlockController(Qt3DCore::QEntity *parent, const Qt3DRender::QCamera *playerCamera)
    : Qt3DCore::QEntity(parent)
    , m_phantomBlock(new PhantomBlock(parent))
    , m_camera(playerCamera)
    , m_frameAction(new Qt3DLogic::QFrameAction()) {

    QObject::connect(m_frameAction, SIGNAL(triggered(float)),
                     this, SLOT(onTriggered(float)));

    this->addComponent(m_frameAction);

}

PhantomBlockController::~PhantomBlockController() {
}

void PhantomBlockController::onTriggered(float) {
    if (m_camera != nullptr) {
        m_phantomBlock->setHided(BLOCK_VISIBLE);
        m_phantomBlock->setPos(Vec3i(m_camera->position() + m_camera->viewVector() / m_camera->viewVector().length() * 2.5f));
    }
}

}
<|endoftext|>


<commit_before>#include "ThermalContactAction.h"
#include "FEProblem.h"
#include "Factory.h"
#include "ActionFactory.h"
#include "AddSlaveFluxVectorAction.h"
#include "Conversion.h"
#include "MooseApp.h"

static unsigned int n = 0;                                  // numbering for gap heat transfer objects (we can have them on multiple interfaces)
static const std::string GAP_VALUE_VAR_NAME = "gap_value";
static const std::string PENETRATION_VAR_NAME = "penetration";

template<>
InputParameters validParams<ThermalContactAction>()
{
  MooseEnum orders("CONSTANT, FIRST, SECOND, THIRD, FORTH", "FIRST");

  InputParameters params = validParams<Action>();
  params.addRequiredParam<std::string>("type", "A string representing the Moose object that will be used for heat conduction over the gap");
  params.addParam<std::string>("gap_type", "GapValueAux", "A string representing the Moose object that will be used for computing the gap size");
  params.addRequiredParam<NonlinearVariableName>("variable", "The variable for thermal contact");
  params.addRequiredParam<BoundaryName>("master", "The master surface");
  params.addRequiredParam<BoundaryName>("slave", "The slave surface");
  params.addParam<NonlinearVariableName>("disp_x", "The x displacement");
  params.addParam<NonlinearVariableName>("disp_y", "The y displacement");
  params.addParam<NonlinearVariableName>("disp_z", "The z displacement");
  params.addParam<Real>("tangential_tolerance", "Tangential distance to extend edges of contact surfaces");
  params.addParam<MooseEnum>("order", orders, "The finite element order");
  params.addParam<bool>("warnings", false, "Whether to output warning messages concerning nodes not being found");
  params.addParam<std::vector<std::string> >("save_in", "The Auxiliary Variable to (optionally) save the boundary flux in");

  return params;
}

ThermalContactAction::ThermalContactAction(const std::string & name, InputParameters params) :
    Action(name, params)
{
}

void
ThermalContactAction::addBcs()
{
  /*
   * [./gap2]
   *   type = GapHeatTransfer
   *   variable = temp
   *   boundary = 10
   *   gap_distance = penetration
   *   gap_temp = gap_value
   *   disp_x = disp_x
   *   disp_y = disp_y
   *   disp_z = disp_z
   * [../]
   */

  InputParameters action_params = ActionFactory::instance()->getValidParams("AddBCAction");
  action_params.set<ActionWarehouse *>("awh") = getParam<ActionWarehouse *>("awh");
  action_params.set<std::string>("type") = getParam<std::string>("type");
  Action *action = ActionFactory::instance()->create("AddBCAction", "BCs/gap_bc_" + Moose::stringify(n), action_params);
  MooseObjectAction *moose_object_action = dynamic_cast<MooseObjectAction *>(action);
  mooseAssert (moose_object_action, "Dynamic Cast failed");

  InputParameters & params = moose_object_action->getObjectParams();

  // get valid params for the BC specified in 'type' field
  InputParameters bc_params = Factory::instance()->getValidParams(getParam<std::string>("type"));
  _parser->extractParams(_name, bc_params);
  params += bc_params;

  if(isParamValid("save_in"))
    params.set<std::vector<std::string> >("save_in") = getParam<std::vector<std::string> >("save_in");

  params.set<NonlinearVariableName>("variable") = getParam<NonlinearVariableName>("variable");
  std::vector<AuxVariableName> vars(1);
  vars[0] = PENETRATION_VAR_NAME;
  params.set<std::vector<AuxVariableName> >("gap_distance") = vars;
  vars[0] = GAP_VALUE_VAR_NAME;
  params.set<std::vector<AuxVariableName> >("gap_temp") = vars;
  std::vector<BoundaryName> bnds(1, getParam<BoundaryName>("slave"));
  params.set<std::vector<BoundaryName> >("boundary") = bnds;

  if (isParamValid("disp_x"))
  {
    params.addCoupledVar("disp_x", "The x displacement");
    std::vector<NonlinearVariableName> disp_x(1, getParam<NonlinearVariableName>("disp_x"));
    params.set< std::vector<NonlinearVariableName> >("disp_x") = disp_x;
  }
  if (isParamValid("disp_y"))
  {
    params.addCoupledVar("disp_y", "The y displacement");
    std::vector<NonlinearVariableName> disp_y(1, getParam<NonlinearVariableName>("disp_y"));
    params.set< std::vector<NonlinearVariableName> >("disp_y") = disp_y;
  }
  if (isParamValid("disp_z"))
  {
    params.addCoupledVar("disp_z", "The z displacement");
    std::vector<NonlinearVariableName> disp_z(1, getParam<NonlinearVariableName>("disp_z"));
    params.set< std::vector<NonlinearVariableName> >("disp_z") = disp_z;
  }

  // add it to the warehouse
  _awh.addActionBlock(action);

}

void
ThermalContactAction::addAuxVariables()
{
  /*
  [./gap_value]
    order = FIRST
    family = LAGRANGE
  [../]
  [./penetration]
    order = FIRST
    family = LAGRANGE
  [../]
  */

  // We need to add the variables only once
  if (n == 0)
  {
      InputParameters action_params = ActionFactory::instance()->getValidParams("AddVariableAction");

      action_params.set<ActionWarehouse *>("awh") = getParam<ActionWarehouse *>("awh");
      action_params.set<std::string>("action") = "add_aux_variable";
      action_params.set<MooseEnum>("order") = getParam<MooseEnum>("order");
      // gap_value
      Action *action = ActionFactory::instance()->create("AddVariableAction", "AuxVariables/" + GAP_VALUE_VAR_NAME, action_params);
      _awh.addActionBlock(action);
      // penetration
      action = ActionFactory::instance()->create("AddVariableAction", "AuxVariables/" + PENETRATION_VAR_NAME, action_params);
      _awh.addActionBlock(action);

      action_params = ActionFactory::instance()->getValidParams("CopyNodalVarsAction");
      action_params.set<ActionWarehouse *>("awh") = getParam<ActionWarehouse *>("awh");
      action_params.set<std::string>("action") = "copy_nodal_aux_vars";
      // gap_value
      action = ActionFactory::instance()->create("CopyNodalVarsAction", "AuxVariables/" + GAP_VALUE_VAR_NAME, action_params);
      _awh.addActionBlock(action);
      // penetration
      action = ActionFactory::instance()->create("CopyNodalVarsAction", "AuxVariables/" + PENETRATION_VAR_NAME, action_params);
      _awh.addActionBlock(action);
  }
}

void
ThermalContactAction::addAuxBcs()
{
  /*
  [./gapvalue]
    type = GapValueAux
    variable = gap_value
    boundary = 10
    paired_boundary = 5
    paired_variable = temp
  [../]
  [./penetration]
    type = PenetrationAux
    variable = penetration
    boundary = 10
    paired_boundary = 5
  [../]
  */

  InputParameters action_params = ActionFactory::instance()->getValidParams("AddBCAction");
  action_params.set<ActionWarehouse *>("awh") = getParam<ActionWarehouse *>("awh");
  action_params.set<std::string>("action") = "add_aux_bc";

  {
    action_params.set<std::string>("type") = getParam<std::string>("gap_type");
    Action *action = ActionFactory::instance()->create("AddBCAction", "AuxBCs/gap_value_" + Moose::stringify(n), action_params);
    MooseObjectAction *moose_object_action = dynamic_cast<MooseObjectAction *>(action);
    mooseAssert (moose_object_action, "Dynamic Cast failed");

    InputParameters & params = moose_object_action->getObjectParams();
    params.set<AuxVariableName>("variable") = GAP_VALUE_VAR_NAME;
    std::vector<BoundaryName> bnds(1, getParam<BoundaryName>("slave"));
    params.set<std::vector<BoundaryName> >("boundary") = bnds;
    params.set<BoundaryName>("paired_boundary") = getParam<BoundaryName>("master");

    std::vector<VariableName> vars(1, getParam<NonlinearVariableName>("variable"));
    params.set<std::vector<VariableName> >("paired_variable") = vars;

    params.set<MooseEnum>("order") = getParam<MooseEnum>("order");
    if (isParamValid("tangential_tolerance"))
    {
      params.set<Real>("tangential_tolerance") = getParam<Real>("tangential_tolerance");
    }
    params.set<bool>("warnings") = getParam<bool>("warnings");
    // add it to the warehouse
    _awh.addActionBlock(action);
  }

  std::vector<BoundaryName> bnds(1, getParam<BoundaryName>("slave"));
  {
    action_params.set<std::string>("type") = "PenetrationAux";
    Action *action = ActionFactory::instance()->create("AddBCAction", "AuxBCs/penetration_" + Moose::stringify(n), action_params);
    MooseObjectAction *moose_object_action = dynamic_cast<MooseObjectAction *>(action);
    mooseAssert (moose_object_action, "Dynamic Cast failed");

    InputParameters & params = moose_object_action->getObjectParams();
    params.set<AuxVariableName>("variable") = PENETRATION_VAR_NAME;
    params.set<std::vector<BoundaryName> >("boundary") = bnds;
    params.set<BoundaryName>("paired_boundary") = getParam<BoundaryName>("master");
    if (isParamValid("tangential_tolerance"))
    {
      params.set<Real>("tangential_tolerance") = getParam<Real>("tangential_tolerance");
    }
    // add it to the warehouse
    _awh.addActionBlock(action);
  }

}

void
ThermalContactAction::addMaterials()
{
  InputParameters action_params = ActionFactory::instance()->getValidParams("AddMaterialAction");
  action_params.set<ActionWarehouse *>("awh") = getParam<ActionWarehouse *>("awh");
  action_params.set<std::string>("action") = "add_material";

  {
    std::string type("GapConductance");
    if (getParam<std::string>("type") == "GapHeatTransferLWR")
    {
      type += "LWR";
    }
    action_params.set<std::string>("type") = type;
    Action *action = ActionFactory::instance()->create("AddMaterialAction", "Materials/gap_value_" + Moose::stringify(n), action_params);
    MooseObjectAction *moose_object_action = dynamic_cast<MooseObjectAction *>(action);
    mooseAssert (moose_object_action, "Dynamic Cast failed");

    InputParameters & params = moose_object_action->getObjectParams();

    // get valid params for the Material
    InputParameters material_params = Factory::instance()->getValidParams(type);
    _parser->extractParams(_name, material_params);
    params += material_params;

    params.set<std::vector<VariableName> >("variable") = std::vector<VariableName>(1, getParam<NonlinearVariableName>("variable"));
    params.set<std::vector<AuxVariableName> >("gap_temp") = std::vector<AuxVariableName>(1, GAP_VALUE_VAR_NAME);
    std::vector<AuxVariableName> vars(1);
    vars[0] = PENETRATION_VAR_NAME;
    params.set<std::vector<AuxVariableName> >("gap_distance") = vars;

    std::vector<BoundaryName> bnds(1, getParam<BoundaryName>("slave"));
    params.set<std::vector<BoundaryName> >("boundary") = bnds;

    // add it to the warehouse
    _awh.addActionBlock(action);
  }

}
void
ThermalContactAction::addDiracKernels()
{
  /*
  [./thermal_master]
    type = GapHeatPointSourceMaster
    variable = temp
    boundary = 5
    slave = 10
  [../]
  */

  InputParameters action_params = ActionFactory::instance()->getValidParams("AddDiracKernelAction");
  action_params.set<ActionWarehouse *>("awh") = getParam<ActionWarehouse *>("awh");
  action_params.set<std::string>("type") = "GapHeatPointSourceMaster";
  Action *action = ActionFactory::instance()->create("AddDiracKernelAction", "DiracKernels/thermal_master_" + Moose::stringify(n), action_params);
  MooseObjectAction *moose_object_action = dynamic_cast<MooseObjectAction *>(action);
  mooseAssert (moose_object_action, "Dynamic Cast failed");

  InputParameters & params = moose_object_action->getObjectParams();
  params.set<NonlinearVariableName>("variable") = getParam<NonlinearVariableName>("variable");
  params.set<BoundaryName>("boundary") = getParam<BoundaryName>("master");
  params.set<BoundaryName>("slave") = getParam<BoundaryName>("slave");
  if (isParamValid("tangential_tolerance"))
  {
    params.set<Real>("tangential_tolerance") = getParam<Real>("tangential_tolerance");
  }

  // add it to the warehouse
  _awh.addActionBlock(action);
}

void
ThermalContactAction::addVectors()
{
  // We need only one instance of flux vector
  if (n == 0)
  {
    InputParameters action_params = validParams<AddSlaveFluxVectorAction>();
    action_params.set<ActionWarehouse *>("awh") = getParam<ActionWarehouse *>("awh");
    Action *action = ActionFactory::instance()->create("AddSlaveFluxVectorAction", "add_slave_flux_vector", action_params);
    // add it to the warehouse
    _awh.addActionBlock(action);
  }
}

void
ThermalContactAction::act()
{
  addBcs();
  addAuxVariables();
  addAuxBcs();
  addMaterials();
  if (getParam<std::string>("gap_type") != "NearestNodeValueAux")
  {
    addDiracKernels();
  }
  addVectors();
  n++;
}
<commit_msg>Boundary id on material<commit_after>#include "ThermalContactAction.h"
#include "FEProblem.h"
#include "Factory.h"
#include "ActionFactory.h"
#include "AddSlaveFluxVectorAction.h"
#include "Conversion.h"
#include "MooseApp.h"

static unsigned int n = 0;                                  // numbering for gap heat transfer objects (we can have them on multiple interfaces)
static const std::string GAP_VALUE_VAR_NAME = "gap_value";
static const std::string PENETRATION_VAR_NAME = "penetration";

template<>
InputParameters validParams<ThermalContactAction>()
{
  MooseEnum orders("CONSTANT, FIRST, SECOND, THIRD, FOURTH", "FIRST");

  InputParameters params = validParams<Action>();
  params.addRequiredParam<std::string>("type", "A string representing the Moose object that will be used for heat conduction over the gap");
  params.addParam<std::string>("gap_type", "GapValueAux", "A string representing the Moose object that will be used for computing the gap size");
  params.addRequiredParam<NonlinearVariableName>("variable", "The variable for thermal contact");
  params.addRequiredParam<BoundaryName>("master", "The master surface");
  params.addRequiredParam<BoundaryName>("slave", "The slave surface");
  params.addParam<NonlinearVariableName>("disp_x", "The x displacement");
  params.addParam<NonlinearVariableName>("disp_y", "The y displacement");
  params.addParam<NonlinearVariableName>("disp_z", "The z displacement");
  params.addParam<Real>("tangential_tolerance", "Tangential distance to extend edges of contact surfaces");
  params.addParam<MooseEnum>("order", orders, "The finite element order");
  params.addParam<bool>("warnings", false, "Whether to output warning messages concerning nodes not being found");
  params.addParam<std::vector<std::string> >("save_in", "The Auxiliary Variable to (optionally) save the boundary flux in");

  return params;
}

ThermalContactAction::ThermalContactAction(const std::string & name, InputParameters params) :
    Action(name, params)
{
}

void
ThermalContactAction::addBcs()
{
  /*
   * [./gap2]
   *   type = GapHeatTransfer
   *   variable = temp
   *   boundary = 10
   *   gap_distance = penetration
   *   gap_temp = gap_value
   *   disp_x = disp_x
   *   disp_y = disp_y
   *   disp_z = disp_z
   * [../]
   */

  InputParameters action_params = ActionFactory::instance()->getValidParams("AddBCAction");
  action_params.set<ActionWarehouse *>("awh") = getParam<ActionWarehouse *>("awh");
  action_params.set<std::string>("type") = getParam<std::string>("type");
  Action *action = ActionFactory::instance()->create("AddBCAction", "BCs/gap_bc_" + Moose::stringify(n), action_params);
  MooseObjectAction *moose_object_action = dynamic_cast<MooseObjectAction *>(action);
  mooseAssert (moose_object_action, "Dynamic Cast failed");

  InputParameters & params = moose_object_action->getObjectParams();

  // get valid params for the BC specified in 'type' field
  InputParameters bc_params = Factory::instance()->getValidParams(getParam<std::string>("type"));
  _parser->extractParams(_name, bc_params);
  params += bc_params;

  if(isParamValid("save_in"))
  {
    params.set<std::vector<std::string> >("save_in") = getParam<std::vector<std::string> >("save_in");
  }

  params.set<NonlinearVariableName>("variable") = getParam<NonlinearVariableName>("variable");
  std::vector<AuxVariableName> vars(1);
  vars[0] = PENETRATION_VAR_NAME;
  params.set<std::vector<AuxVariableName> >("gap_distance") = vars;
  vars[0] = GAP_VALUE_VAR_NAME;
  params.set<std::vector<AuxVariableName> >("gap_temp") = vars;
  std::vector<BoundaryName> bnds(1, getParam<BoundaryName>("slave"));
  params.set<std::vector<BoundaryName> >("boundary") = bnds;

  if (isParamValid("disp_x"))
  {
    params.addCoupledVar("disp_x", "The x displacement");
    std::vector<NonlinearVariableName> disp_x(1, getParam<NonlinearVariableName>("disp_x"));
    params.set< std::vector<NonlinearVariableName> >("disp_x") = disp_x;
  }
  if (isParamValid("disp_y"))
  {
    params.addCoupledVar("disp_y", "The y displacement");
    std::vector<NonlinearVariableName> disp_y(1, getParam<NonlinearVariableName>("disp_y"));
    params.set< std::vector<NonlinearVariableName> >("disp_y") = disp_y;
  }
  if (isParamValid("disp_z"))
  {
    params.addCoupledVar("disp_z", "The z displacement");
    std::vector<NonlinearVariableName> disp_z(1, getParam<NonlinearVariableName>("disp_z"));
    params.set< std::vector<NonlinearVariableName> >("disp_z") = disp_z;
  }

  // add it to the warehouse
  _awh.addActionBlock(action);

}

void
ThermalContactAction::addAuxVariables()
{
  /*
  [./gap_value]
    order = FIRST
    family = LAGRANGE
  [../]
  [./penetration]
    order = FIRST
    family = LAGRANGE
  [../]
  */

  // We need to add the variables only once
  if (n == 0)
  {
      InputParameters action_params = ActionFactory::instance()->getValidParams("AddVariableAction");

      action_params.set<ActionWarehouse *>("awh") = getParam<ActionWarehouse *>("awh");
      action_params.set<std::string>("action") = "add_aux_variable";
      action_params.set<MooseEnum>("order") = getParam<MooseEnum>("order");
      // gap_value
      Action *action = ActionFactory::instance()->create("AddVariableAction", "AuxVariables/" + GAP_VALUE_VAR_NAME, action_params);
      _awh.addActionBlock(action);
      // penetration
      action = ActionFactory::instance()->create("AddVariableAction", "AuxVariables/" + PENETRATION_VAR_NAME, action_params);
      _awh.addActionBlock(action);

      action_params = ActionFactory::instance()->getValidParams("CopyNodalVarsAction");
      action_params.set<ActionWarehouse *>("awh") = getParam<ActionWarehouse *>("awh");
      action_params.set<std::string>("action") = "copy_nodal_aux_vars";
      // gap_value
      action = ActionFactory::instance()->create("CopyNodalVarsAction", "AuxVariables/" + GAP_VALUE_VAR_NAME, action_params);
      _awh.addActionBlock(action);
      // penetration
      action = ActionFactory::instance()->create("CopyNodalVarsAction", "AuxVariables/" + PENETRATION_VAR_NAME, action_params);
      _awh.addActionBlock(action);
  }
}

void
ThermalContactAction::addAuxBcs()
{
  /*
  [./gapvalue]
    type = GapValueAux
    variable = gap_value
    boundary = 10
    paired_boundary = 5
    paired_variable = temp
  [../]
  [./penetration]
    type = PenetrationAux
    variable = penetration
    boundary = 10
    paired_boundary = 5
  [../]
  */

  InputParameters action_params = ActionFactory::instance()->getValidParams("AddBCAction");
  action_params.set<ActionWarehouse *>("awh") = getParam<ActionWarehouse *>("awh");
  action_params.set<std::string>("action") = "add_aux_bc";

  {
    action_params.set<std::string>("type") = getParam<std::string>("gap_type");
    Action *action = ActionFactory::instance()->create("AddBCAction", "AuxBCs/gap_value_" + Moose::stringify(n), action_params);
    MooseObjectAction *moose_object_action = dynamic_cast<MooseObjectAction *>(action);
    mooseAssert (moose_object_action, "Dynamic Cast failed");

    InputParameters & params = moose_object_action->getObjectParams();
    params.set<AuxVariableName>("variable") = GAP_VALUE_VAR_NAME;
    std::vector<BoundaryName> bnds(1, getParam<BoundaryName>("slave"));
    params.set<std::vector<BoundaryName> >("boundary") = bnds;
    params.set<BoundaryName>("paired_boundary") = getParam<BoundaryName>("master");

    std::vector<VariableName> vars(1, getParam<NonlinearVariableName>("variable"));
    params.set<std::vector<VariableName> >("paired_variable") = vars;

    params.set<MooseEnum>("order") = getParam<MooseEnum>("order");
    if (isParamValid("tangential_tolerance"))
    {
      params.set<Real>("tangential_tolerance") = getParam<Real>("tangential_tolerance");
    }
    params.set<bool>("warnings") = getParam<bool>("warnings");
    // add it to the warehouse
    _awh.addActionBlock(action);
  }

  std::vector<BoundaryName> bnds(1, getParam<BoundaryName>("slave"));
  {
    action_params.set<std::string>("type") = "PenetrationAux";
    Action *action = ActionFactory::instance()->create("AddBCAction", "AuxBCs/penetration_" + Moose::stringify(n), action_params);
    MooseObjectAction *moose_object_action = dynamic_cast<MooseObjectAction *>(action);
    mooseAssert (moose_object_action, "Dynamic Cast failed");

    InputParameters & params = moose_object_action->getObjectParams();
    params.set<AuxVariableName>("variable") = PENETRATION_VAR_NAME;
    params.set<std::vector<BoundaryName> >("boundary") = bnds;
    params.set<BoundaryName>("paired_boundary") = getParam<BoundaryName>("master");
    if (isParamValid("tangential_tolerance"))
    {
      params.set<Real>("tangential_tolerance") = getParam<Real>("tangential_tolerance");
    }
    // add it to the warehouse
    _awh.addActionBlock(action);
  }

}

void
ThermalContactAction::addMaterials()
{
  InputParameters action_params = ActionFactory::instance()->getValidParams("AddMaterialAction");
  action_params.set<ActionWarehouse *>("awh") = getParam<ActionWarehouse *>("awh");
  action_params.set<std::string>("action") = "add_material";

  {
    std::string type("GapConductance");
    if (getParam<std::string>("type") == "GapHeatTransferLWR")
    {
      type += "LWR";
    }
    action_params.set<std::string>("type") = type;
    Action *action = ActionFactory::instance()->create("AddMaterialAction", "Materials/gap_value_" + Moose::stringify(n), action_params);
    MooseObjectAction *moose_object_action = dynamic_cast<MooseObjectAction *>(action);
    mooseAssert (moose_object_action, "Dynamic Cast failed");

    InputParameters & params = moose_object_action->getObjectParams();

    // get valid params for the Material
    InputParameters material_params = Factory::instance()->getValidParams(type);
    _parser->extractParams(_name, material_params);
    params += material_params;

    params.set<std::vector<VariableName> >("variable") = std::vector<VariableName>(1, getParam<NonlinearVariableName>("variable"));
    params.set<std::vector<AuxVariableName> >("gap_temp") = std::vector<AuxVariableName>(1, GAP_VALUE_VAR_NAME);
    std::vector<AuxVariableName> vars(1);
    vars[0] = PENETRATION_VAR_NAME;
    params.set<std::vector<AuxVariableName> >("gap_distance") = vars;

    std::vector<BoundaryName> bnds(1, getParam<BoundaryName>("slave"));
    params.set<std::vector<BoundaryName> >("boundary") = bnds;

    // add it to the warehouse
    _awh.addActionBlock(action);
  }

}
void
ThermalContactAction::addDiracKernels()
{
  /*
  [./thermal_master]
    type = GapHeatPointSourceMaster
    variable = temp
    boundary = 5
    slave = 10
  [../]
  */

  InputParameters action_params = ActionFactory::instance()->getValidParams("AddDiracKernelAction");
  action_params.set<ActionWarehouse *>("awh") = getParam<ActionWarehouse *>("awh");
  action_params.set<std::string>("type") = "GapHeatPointSourceMaster";
  Action *action = ActionFactory::instance()->create("AddDiracKernelAction", "DiracKernels/thermal_master_" + Moose::stringify(n), action_params);
  MooseObjectAction *moose_object_action = dynamic_cast<MooseObjectAction *>(action);
  mooseAssert (moose_object_action, "Dynamic Cast failed");

  InputParameters & params = moose_object_action->getObjectParams();
  params.set<NonlinearVariableName>("variable") = getParam<NonlinearVariableName>("variable");
  params.set<BoundaryName>("boundary") = getParam<BoundaryName>("master");
  params.set<BoundaryName>("slave") = getParam<BoundaryName>("slave");
  if (isParamValid("tangential_tolerance"))
  {
    params.set<Real>("tangential_tolerance") = getParam<Real>("tangential_tolerance");
  }

  // add it to the warehouse
  _awh.addActionBlock(action);
}

void
ThermalContactAction::addVectors()
{
  // We need only one instance of flux vector
  if (n == 0)
  {
    InputParameters action_params = validParams<AddSlaveFluxVectorAction>();
    action_params.set<ActionWarehouse *>("awh") = getParam<ActionWarehouse *>("awh");
    Action *action = ActionFactory::instance()->create("AddSlaveFluxVectorAction", "add_slave_flux_vector", action_params);
    // add it to the warehouse
    _awh.addActionBlock(action);
  }
}

void
ThermalContactAction::act()
{
  addBcs();
  addAuxVariables();
  addAuxBcs();
  addMaterials();
  if (getParam<std::string>("gap_type") != "NearestNodeValueAux")
  {
    addDiracKernels();
  }
  addVectors();
  n++;
}
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2011-2012, John Haddon. All rights reserved.
//  Copyright (c) 2011, Image Engine Design Inc. 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 John Haddon nor the names of
//        any other contributors to this software 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 <stack>

#include "tbb/enumerable_thread_specific.h"

#include "boost/bind.hpp"
#include "boost/format.hpp"

#include "Gaffer/ValuePlug.h"
#include "Gaffer/Node.h"
#include "Gaffer/Context.h"
#include "Gaffer/Action.h"

using namespace Gaffer;

//////////////////////////////////////////////////////////////////////////
// Computation implementation
// The computation class is responsible for managing the transient storage
// necessary for computed results, and for managing the call to Node::compute().
// One day it may also be responsible for managing a cache of previous
// results and maybe even shipping some computations off over the network
// to a special computation server of some sort.
//////////////////////////////////////////////////////////////////////////

class ValuePlug::Computation
{

	public :

		Computation( const ValuePlug *resultPlug )
			:	m_resultPlug( resultPlug ), m_resultWritten( false )
		{
			g_threadComputations.local().push( this );
		}

		~Computation()
		{
			g_threadComputations.local().pop();
		}

		bool compute()
		{
			if( const ValuePlug *input = m_resultPlug->getInput<ValuePlug>() )
			{
				// cast is ok, because we know that the resulting setValue() call won't
				// actually modify the plug, but will just place the value in our m_resultValue.
				const_cast<ValuePlug *>( m_resultPlug )->setFrom( input );
			}
			else
			{
				assert( m_resultPlug->direction()==Out );
				const Node *n = m_resultPlug->node();
				if( !n )
				{
					throw IECore::Exception( boost::str( boost::format( "Unable to compute value for orphan Plug \"%s\"." ) % m_resultPlug->fullName() ) );
				}
				// cast is ok, because we know that the resulting setValue() call won't
				// actually modify the plug, but will just place the value in our m_resultValue.
				n->compute( const_cast<ValuePlug *>( m_resultPlug ), Context::current() );
			}

			// the call to compute() or setFromInput() above should cause setValue() to be called
			// on the result plug, which in turn will call ValuePlug::setObjectValue, which will
			// then store the result in the current computation.

			return m_resultWritten;
		}

		static Computation *current()
		{
			ComputationStack &s = g_threadComputations.local();
			if( !s.size() )
			{
				return 0;
			}
			return s.top();
		}

	/// \todo Make accessors
	//private :

		const ValuePlug *m_resultPlug;
		IECore::ConstObjectPtr m_resultValue;
		bool m_resultWritten;

		typedef std::stack<Computation *> ComputationStack;
		typedef tbb::enumerable_thread_specific<ComputationStack> ThreadSpecificComputationStack;

		static ThreadSpecificComputationStack g_threadComputations;

};

ValuePlug::Computation::ThreadSpecificComputationStack ValuePlug::Computation::g_threadComputations;

//////////////////////////////////////////////////////////////////////////
// ValuePlug implementation
//////////////////////////////////////////////////////////////////////////

IE_CORE_DEFINERUNTIMETYPED( ValuePlug );

ValuePlug::ValuePlug( const std::string &name, Direction direction, unsigned flags )
	:	Plug( name, direction, flags )
{
}

ValuePlug::~ValuePlug()
{
}

bool ValuePlug::acceptsInput( const Plug *input ) const
{
	if( !Plug::acceptsInput( input ) )
	{
		return false;
	}
	if( input )
	{
		return input->isInstanceOf( staticTypeId() );
	}
	return true;
}

void ValuePlug::setInput( PlugPtr input )
{
	if( input.get() == getInput<Plug>() )
	{
		return;
	}

	Plug::setInput( input );
	if( input )
	{
		emitDirtiness();
		propagateDirtiness();
	}
	else
	{
		// set value back to what it was before
		// we received a connection.
		setValueInternal( m_staticValue );
	}
}

IECore::ConstObjectPtr ValuePlug::getObjectValue() const
{
	bool haveInput = getInput<Plug>();
	if( direction()==In && !haveInput )
	{
		// input plug with no input connection. there can only ever be a single value,
		// which is stored directly on the plug.
		return m_staticValue;
	}

	// an input plug with an input connection or an output plug. there can be many values -
	// one per context. the computation class is responsible for providing storage for the result
	// and also actually managing the computation.
	Computation computation( this );

	if( !computation.compute() )
	{
		throw IECore::Exception( boost::str( boost::format( "Value for Plug \"%s\" not set as expected." ) % fullName() ) );
	}

	return computation.m_resultValue;
}

void ValuePlug::setObjectValue( IECore::ConstObjectPtr value )
{
	bool haveInput = getInput<Plug>();
	if( direction()==In && !haveInput )
	{
		// input plug with no input connection. there can only ever be a single value,
		// which we store directly on the plug. when setting this we need to take care
		// of undo, and also of triggering the plugValueSet signal and propagating the
		// plugDirtiedSignal.
		if( ( (bool)value != (bool)m_staticValue ) ||
			( value && value->isNotEqualTo( m_staticValue ) )
		)
		{
			Action::enact(
				this,
				boost::bind( &ValuePlug::setValueInternal, Ptr( this ), value ),
				boost::bind( &ValuePlug::setValueInternal, Ptr( this ), m_staticValue )
			);
		}
		return;
	}

	// an input plug with an input connection or an output plug. we must be currently in a computation
	// triggered by getObjectValue() for a setObjectValue() call to be valid. we never trigger plugValueSet
	// or plugDirtiedSignals during computation.

	Computation *computation = Computation::current();
	if( !computation )
	{
		throw IECore::Exception( boost::str( boost::format( "Cannot set value for plug \"%s\" except during computation." ) % fullName() ) );
	}

	if( computation->m_resultPlug != this )
	{
		throw IECore::Exception( boost::str( boost::format( "Cannot set value for plug \"%s\" during computation for plug \"%s\"." ) % fullName() % computation->m_resultPlug->fullName() ) );
	}

	computation->m_resultValue = value;
	computation->m_resultWritten = true;
}

bool ValuePlug::inCompute() const
{
	return Computation::current();
}

void ValuePlug::setValueInternal( IECore::ConstObjectPtr value )
{
	m_staticValue = value;
	Node *n = node();
	if( n )
	{
		// it is important that we emit the plug set signal before
		// we emit dirty signals for any dependent plugs. this is
		// because the node may wish to perform some internal setup when plugs
		// are set, and listeners on output plugs may pull to get new
		// output values as soon as the dirty signal is emitted.
		ValuePlug *p = this;
		while( p )
		{
			n->plugSetSignal()( p );
			p = p->parent<ValuePlug>();
		}
	}
	propagateDirtiness();
}

void ValuePlug::emitDirtiness( Node *n )
{
	n = n ? n : node();
	if( !n )
	{
		return;
	}

	ValuePlug *p = this;
	while( p )
	{
		n->plugDirtiedSignal()( p );
		p = p->parent<ValuePlug>();
	}
}

void ValuePlug::propagateDirtiness()
{
	Node *n = node();
	if( n )
	{
		if( direction()==In )
		{
			Node::AffectedPlugsContainer affected;
			n->affects( this, affected );
			for( Node::AffectedPlugsContainer::const_iterator it=affected.begin(); it!=affected.end(); it++ )
			{
				const_cast<ValuePlug *>( *it )->emitDirtiness( n );
				const_cast<ValuePlug *>( *it )->propagateDirtiness();
			}
		}
	}

	for( OutputContainer::const_iterator it=outputs().begin(); it!=outputs().end(); it++ )
	{
		ValuePlugPtr o = IECore::runTimeCast<ValuePlug>( *it );
		if( o )
		{
			o->emitDirtiness();
			o->propagateDirtiness();
		}
	}
}<commit_msg>Tidied up ValuePlug computation code, by moving all the logic inside the Computation class, and making all Computation class members private.<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2011-2012, John Haddon. All rights reserved.
//  Copyright (c) 2011, Image Engine Design Inc. 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 John Haddon nor the names of
//        any other contributors to this software 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 <stack>

#include "tbb/enumerable_thread_specific.h"

#include "boost/bind.hpp"
#include "boost/format.hpp"

#include "Gaffer/ValuePlug.h"
#include "Gaffer/Node.h"
#include "Gaffer/Context.h"
#include "Gaffer/Action.h"

using namespace Gaffer;

//////////////////////////////////////////////////////////////////////////
// Computation implementation
// The computation class is responsible for managing the transient storage
// necessary for computed results, and for managing the call to Node::compute().
// One day it may also be responsible for managing a cache of previous
// results and maybe even shipping some computations off over the network
// to a special computation server of some sort.
//////////////////////////////////////////////////////////////////////////

class ValuePlug::Computation
{

	public :

		Computation( const ValuePlug *resultPlug )
			:	m_resultPlug( resultPlug ), m_resultWritten( false )
		{
			g_threadComputations.local().push( this );
		}

		~Computation()
		{
			g_threadComputations.local().pop();
		}

		IECore::ConstObjectPtr compute()
		{
			if( const ValuePlug *input = m_resultPlug->getInput<ValuePlug>() )
			{
				// cast is ok, because we know that the resulting setValue() call won't
				// actually modify the plug, but will just place the value in our m_resultValue.
				const_cast<ValuePlug *>( m_resultPlug )->setFrom( input );
			}
			else
			{
				assert( m_resultPlug->direction()==Out );
				const Node *n = m_resultPlug->node();
				if( !n )
				{
					throw IECore::Exception( boost::str( boost::format( "Unable to compute value for orphan Plug \"%s\"." ) % m_resultPlug->fullName() ) );
				}
				// cast is ok, because we know that the resulting setValue() call won't
				// actually modify the plug, but will just place the value in our m_resultValue.
				n->compute( const_cast<ValuePlug *>( m_resultPlug ), Context::current() );
			}

			// the call to compute() or setFromInput() above should cause setValue() to be called
			// on the result plug, which in turn will call ValuePlug::setObjectValue(), which will
			// then store the result in the current computation by calling receiveResult().
			if( !m_resultWritten )
			{
				throw IECore::Exception( boost::str( boost::format( "Value for Plug \"%s\" not set as expected." ) % m_resultPlug->fullName() ) );
			}
			return m_resultValue;
		}

		static void receiveResult( const ValuePlug *plug, IECore::ConstObjectPtr result )
		{
			Computation *computation = Computation::current();
			if( !computation )
			{
				throw IECore::Exception( boost::str( boost::format( "Cannot set value for plug \"%s\" except during computation." ) % plug->fullName() ) );
			}

			if( computation->m_resultPlug != plug )
			{
				throw IECore::Exception( boost::str( boost::format( "Cannot set value for plug \"%s\" during computation for plug \"%s\"." ) % plug->fullName() % computation->m_resultPlug->fullName() ) );
			}

			computation->m_resultValue = result;
			computation->m_resultWritten = true;
		}

		static Computation *current()
		{
			ComputationStack &s = g_threadComputations.local();
			if( !s.size() )
			{
				return 0;
			}
			return s.top();
		}

	private :

		const ValuePlug *m_resultPlug;
		IECore::ConstObjectPtr m_resultValue;
		bool m_resultWritten;

		typedef std::stack<Computation *> ComputationStack;
		typedef tbb::enumerable_thread_specific<ComputationStack> ThreadSpecificComputationStack;

		static ThreadSpecificComputationStack g_threadComputations;

};

ValuePlug::Computation::ThreadSpecificComputationStack ValuePlug::Computation::g_threadComputations;

//////////////////////////////////////////////////////////////////////////
// ValuePlug implementation
//////////////////////////////////////////////////////////////////////////

IE_CORE_DEFINERUNTIMETYPED( ValuePlug );

ValuePlug::ValuePlug( const std::string &name, Direction direction, unsigned flags )
	:	Plug( name, direction, flags )
{
}

ValuePlug::~ValuePlug()
{
}

bool ValuePlug::acceptsInput( const Plug *input ) const
{
	if( !Plug::acceptsInput( input ) )
	{
		return false;
	}
	if( input )
	{
		return input->isInstanceOf( staticTypeId() );
	}
	return true;
}

void ValuePlug::setInput( PlugPtr input )
{
	if( input.get() == getInput<Plug>() )
	{
		return;
	}

	Plug::setInput( input );
	if( input )
	{
		emitDirtiness();
		propagateDirtiness();
	}
	else
	{
		// set value back to what it was before
		// we received a connection.
		setValueInternal( m_staticValue );
	}
}

IECore::ConstObjectPtr ValuePlug::getObjectValue() const
{
	bool haveInput = getInput<Plug>();
	if( direction()==In && !haveInput )
	{
		// input plug with no input connection. there can only ever be a single value,
		// which is stored directly on the plug.
		return m_staticValue;
	}

	// an input plug with an input connection or an output plug. there can be many values -
	// one per context. the computation class is responsible for providing storage for the result
	// and also actually managing the computation.
	Computation computation( this );
	return computation.compute();
}

void ValuePlug::setObjectValue( IECore::ConstObjectPtr value )
{
	bool haveInput = getInput<Plug>();
	if( direction()==In && !haveInput )
	{
		// input plug with no input connection. there can only ever be a single value,
		// which we store directly on the plug. when setting this we need to take care
		// of undo, and also of triggering the plugValueSet signal and propagating the
		// plugDirtiedSignal.
		if( ( (bool)value != (bool)m_staticValue ) ||
			( value && value->isNotEqualTo( m_staticValue ) )
		)
		{
			Action::enact(
				this,
				boost::bind( &ValuePlug::setValueInternal, Ptr( this ), value ),
				boost::bind( &ValuePlug::setValueInternal, Ptr( this ), m_staticValue )
			);
		}
		return;
	}

	// an input plug with an input connection or an output plug. we must be currently in a computation
	// triggered by getObjectValue() for a setObjectValue() call to be valid (receiveResult will check this).
	// we never trigger plugValueSet or plugDirtiedSignals during computation.
	Computation::receiveResult( this, value );
}

bool ValuePlug::inCompute() const
{
	return Computation::current();
}

void ValuePlug::setValueInternal( IECore::ConstObjectPtr value )
{
	m_staticValue = value;
	Node *n = node();
	if( n )
	{
		// it is important that we emit the plug set signal before
		// we emit dirty signals for any dependent plugs. this is
		// because the node may wish to perform some internal setup when plugs
		// are set, and listeners on output plugs may pull to get new
		// output values as soon as the dirty signal is emitted.
		ValuePlug *p = this;
		while( p )
		{
			n->plugSetSignal()( p );
			p = p->parent<ValuePlug>();
		}
	}
	propagateDirtiness();
}

void ValuePlug::emitDirtiness( Node *n )
{
	n = n ? n : node();
	if( !n )
	{
		return;
	}

	ValuePlug *p = this;
	while( p )
	{
		n->plugDirtiedSignal()( p );
		p = p->parent<ValuePlug>();
	}
}

void ValuePlug::propagateDirtiness()
{
	Node *n = node();
	if( n )
	{
		if( direction()==In )
		{
			Node::AffectedPlugsContainer affected;
			n->affects( this, affected );
			for( Node::AffectedPlugsContainer::const_iterator it=affected.begin(); it!=affected.end(); it++ )
			{
				const_cast<ValuePlug *>( *it )->emitDirtiness( n );
				const_cast<ValuePlug *>( *it )->propagateDirtiness();
			}
		}
	}

	for( OutputContainer::const_iterator it=outputs().begin(); it!=outputs().end(); it++ )
	{
		ValuePlugPtr o = IECore::runTimeCast<ValuePlug>( *it );
		if( o )
		{
			o->emitDirtiness();
			o->propagateDirtiness();
		}
	}
}<|endoftext|>


<commit_before>#include <string>
#include <cmath>

class NucPepXform
{
    std::string baseDNA = "ACGT";
    std::string baseRNA = "ACGU";
    std::string basePEP = "KNKNTTTTRSRSIIMIQHQHPPPPRRRRLLLLEDEDAAAAGGGGVVVV.Y.YSSSS.CWCLFLF";

    int strToInt(std::string inStr, std::string inBase)
    {
        int retNum = 0;
        for (auto i:inStr)
        {
            retNum += pow(inBase.length(), inStr.length()-i-1) * (inBase.at(inStr.at(i)));
        }

        return retNum;
     };

    std::string intToStr(){};
};

<commit_msg>add int to std::string conversion<commit_after>#include <string>
#include <cmath>

class NucPepXform
{
    std::string baseDNA = "ACGT";
    std::string baseRNA = "ACGU";
    std::string basePEP = "KNKNTTTTRSRSIIMIQHQHPPPPRRRRLLLLEDEDAAAAGGGGVVVV.Y.YSSSS.CWCLFLF";

    int strToInt(std::string inStr, std::string inBase)
    {
        int retNum = 0;
        for (auto i:inStr)
        {
            retNum += pow(inBase.length(), inStr.length()-i-1) * (inBase.at(inStr.at(i)));
        }

        return retNum;
     };

    std::string intToStr(int inInt, std::string outBase, int maxDigits)
    {
        int remainder = inInt;
        std::string retStr = "";

        for (int i = maxDigits; i >= 0; --i)
        {
            retStr += outBase.at(trunc(remainder / (int)pow(outBase.length(), i)));
            remainder = trunc(remainder % (int)pow(outBase.length(), i));
        }

        return retStr;
    };
};

<|endoftext|>


<commit_before>// Copyright © 2016, Prosoft Engineering, Inc. (A.K.A "Prosoft")
// 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 Prosoft 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 PROSOFT ENGINEERING, INC. 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 <fstream>

namespace {
    template<typename T>
    const T& create_file(const T& p, std::ios::openmode mode = std::ios::binary) {
        std::ofstream stream(p.c_str(), mode);
        REQUIRE(stream);
        return p;
    }

    // Microsoft's compiler offers std::ofstream with wide character support as an extension, but Mingw posix does not.
    // Since Mingw is currently only for compiling, always fail. Could use CreateFile() instead for both compilers.
#ifdef __MINGW32__
    template<>
    const filesystem::basic_path<prosoft::u16string>& create_file(const filesystem::basic_path<prosoft::u16string>& p, std::ios::openmode) {
        REQUIRE(false); // always fail
        return p;
    }
#endif
}
<commit_msg>Add RAII remove<commit_after>// Copyright © 2016, Prosoft Engineering, Inc. (A.K.A "Prosoft")
// 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 Prosoft 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 PROSOFT ENGINEERING, INC. 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 <fstream>

namespace {
    template<typename T>
    const T& create_file(const T& p, std::ios::openmode mode = std::ios::binary) {
        std::ofstream stream(p.c_str(), mode);
        REQUIRE(stream);
        return p;
    }

    // Microsoft's compiler offers std::ofstream with wide character support as an extension, but Mingw posix does not.
    // Since Mingw is currently only for compiling, always fail. Could use CreateFile() instead for both compilers.
#ifdef __MINGW32__
    template<>
    const filesystem::basic_path<prosoft::u16string>& create_file(const filesystem::basic_path<prosoft::u16string>& p, std::ios::openmode) {
        REQUIRE(false); // always fail
        return p;
    }
#endif

    class RAII_remove { // cleanup for test cases
        using path_type = prosoft::filesystem::path;
        const path_type& m_p;
    public:
        RAII_remove(const path_type& p) : m_p(p) {}
        RAII_remove(path_type&&) = delete;
        RAII_remove(const RAII_remove&) = delete;
        RAII_remove(RAII_remove&&) = delete;
        ~RAII_remove() {
            prosoft::filesystem::error_code ec;
            prosoft::filesystem::remove(m_p, ec);
            CHECK(!ec); // REQUIRE throws an exception on failure
        }
    };
    #define PS_RAII_REMOVE___(p,R,C) RAII_remove  R##C(p)
    #define PS_RAII_REMOVE__(p,R,C) PS_RAII_REMOVE___(p,R,C)
    #define PS_RAII_REMOVE(p) PS_RAII_REMOVE__(p, r, __COUNTER__)
}
<|endoftext|>