<commit_before>// Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// 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.

/**
 * @file LocatorSelectorEntry.hpp
 */

#ifndef FASTRTPS_RTPS_COMMON_LOCATORSELECTORENTRY_HPP_
#define FASTRTPS_RTPS_COMMON_LOCATORSELECTORENTRY_HPP_

#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC

#include "./Guid.h"
#include "./Locator.h"
#include "../../utils/collections/ResourceLimitedVector.hpp"

namespace eprosima {
namespace fastrtps {
namespace rtps {

/**
 * An entry for the @ref LocatorSelector.
 *
 * This class holds the locators of a remote endpoint along with data required for the locator selection algorithm.
 * Can be easyly integrated inside other classes, such as @ref ReaderProxyData and @ref WriterProxyData.
 */
struct LocatorSelectorEntry
{
    /**
     * Holds the selection state of the locators held by a LocatorSelectorEntry
     */
    struct EntryState
    {
        /**
         * Construct an EntryState object.
         *
         * @param max_unicast_locators    Maximum number of unicast locators to held by parent LocatorSelectorEntry.
         * @param max_multicast_locators  Maximum number of multicast locators to held by parent LocatorSelectorEntry.
         */
        EntryState(
                size_t max_unicast_locators,
                size_t max_multicast_locators)
            : unicast(ResourceLimitedContainerConfig::fixed_size_configuration(max_unicast_locators))
            , multicast(ResourceLimitedContainerConfig::fixed_size_configuration(max_multicast_locators))
        {
        }

        //! Unicast locators selection state
        ResourceLimitedVector<size_t> unicast;
        //! Multicast locators selection state
        ResourceLimitedVector<size_t> multicast;
    };

    /**
     * Construct a LocatorSelectorEntry.
     *
     * @param max_unicast_locators    Maximum number of unicast locators to hold.
     * @param max_multicast_locators  Maximum number of multicast locators to hold.
     */
    LocatorSelectorEntry(
            size_t max_unicast_locators,
            size_t max_multicast_locators)
        : remote_guid(c_Guid_Unknown)
        , unicast(ResourceLimitedContainerConfig::fixed_size_configuration(max_unicast_locators))
        , multicast(ResourceLimitedContainerConfig::fixed_size_configuration(max_multicast_locators))
        , state(max_unicast_locators, max_multicast_locators)
        , transport_should_process(false)
    {
    }

    /**
     * Set the enabled value.
     *
     * @param should_enable Whether this entry should be enabled.
     */
    void enable(bool should_enable)
    {
        enabled = should_enable && remote_guid != c_Guid_Unknown;
    }

    /**
     * Reset the selections.
     */
    void reset()
    {
        state.unicast.clear();
        state.multicast.clear();
    }

    //! GUID of the remote entity.
    GUID_t remote_guid;
    //! List of unicast locators to send data to the remote entity.
    ResourceLimitedVector<Locator_t> unicast;
    //! List of multicast locators to send data to the remote entity.
    ResourceLimitedVector<Locator_t> multicast;
    //! State of the entry
    EntryState state;
    //! Indicates whether this entry should be taken into consideration.
    bool enabled;
    //! A temporary value for each transport to help optimizing some use cases.
    bool transport_should_process;
};

} /* namespace rtps */
} /* namespace fastrtps */
} /* namespace eprosima */

#endif /* DOXYGEN_SHOULD_SKIP_THIS_PUBLIC */
#endif /* FASTRTPS_RTPS_COMMON_LOCATORSELECTORENTRY_HPP_ */
<commit_msg>Refs #6108. Setting value for enabled on LocatorSelectorEntry ctor. (#635)<commit_after>// Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// 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.

/**
 * @file LocatorSelectorEntry.hpp
 */

#ifndef FASTRTPS_RTPS_COMMON_LOCATORSELECTORENTRY_HPP_
#define FASTRTPS_RTPS_COMMON_LOCATORSELECTORENTRY_HPP_

#ifndef DOXYGEN_SHOULD_SKIP_THIS_PUBLIC

#include "./Guid.h"
#include "./Locator.h"
#include "../../utils/collections/ResourceLimitedVector.hpp"

namespace eprosima {
namespace fastrtps {
namespace rtps {

/**
 * An entry for the @ref LocatorSelector.
 *
 * This class holds the locators of a remote endpoint along with data required for the locator selection algorithm.
 * Can be easyly integrated inside other classes, such as @ref ReaderProxyData and @ref WriterProxyData.
 */
struct LocatorSelectorEntry
{
    /**
     * Holds the selection state of the locators held by a LocatorSelectorEntry
     */
    struct EntryState
    {
        /**
         * Construct an EntryState object.
         *
         * @param max_unicast_locators    Maximum number of unicast locators to held by parent LocatorSelectorEntry.
         * @param max_multicast_locators  Maximum number of multicast locators to held by parent LocatorSelectorEntry.
         */
        EntryState(
                size_t max_unicast_locators,
                size_t max_multicast_locators)
            : unicast(ResourceLimitedContainerConfig::fixed_size_configuration(max_unicast_locators))
            , multicast(ResourceLimitedContainerConfig::fixed_size_configuration(max_multicast_locators))
        {
        }

        //! Unicast locators selection state
        ResourceLimitedVector<size_t> unicast;
        //! Multicast locators selection state
        ResourceLimitedVector<size_t> multicast;
    };

    /**
     * Construct a LocatorSelectorEntry.
     *
     * @param max_unicast_locators    Maximum number of unicast locators to hold.
     * @param max_multicast_locators  Maximum number of multicast locators to hold.
     */
    LocatorSelectorEntry(
            size_t max_unicast_locators,
            size_t max_multicast_locators)
        : remote_guid(c_Guid_Unknown)
        , unicast(ResourceLimitedContainerConfig::fixed_size_configuration(max_unicast_locators))
        , multicast(ResourceLimitedContainerConfig::fixed_size_configuration(max_multicast_locators))
        , state(max_unicast_locators, max_multicast_locators)
        , enabled(false)
        , transport_should_process(false)
    {
    }

    /**
     * Set the enabled value.
     *
     * @param should_enable Whether this entry should be enabled.
     */
    void enable(bool should_enable)
    {
        enabled = should_enable && remote_guid != c_Guid_Unknown;
    }

    /**
     * Reset the selections.
     */
    void reset()
    {
        state.unicast.clear();
        state.multicast.clear();
    }

    //! GUID of the remote entity.
    GUID_t remote_guid;
    //! List of unicast locators to send data to the remote entity.
    ResourceLimitedVector<Locator_t> unicast;
    //! List of multicast locators to send data to the remote entity.
    ResourceLimitedVector<Locator_t> multicast;
    //! State of the entry
    EntryState state;
    //! Indicates whether this entry should be taken into consideration.
    bool enabled;
    //! A temporary value for each transport to help optimizing some use cases.
    bool transport_should_process;
};

} /* namespace rtps */
} /* namespace fastrtps */
} /* namespace eprosima */

#endif /* DOXYGEN_SHOULD_SKIP_THIS_PUBLIC */
#endif /* FASTRTPS_RTPS_COMMON_LOCATORSELECTORENTRY_HPP_ */
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "AutoSynthesizer.h"

#include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Sema/Sema.h"

using namespace clang;

namespace cling {
  class AutoFixer : public RecursiveASTVisitor<AutoFixer> {
  private:
    Sema* m_Sema;
    DeclRefExpr* m_FoundDRE;
    llvm::DenseSet<NamedDecl*> m_HandledDecls;
  private:
  public:
    AutoFixer(Sema* S) : m_Sema(S), m_FoundDRE(0) {}

    void Fix(CompoundStmt* CS) {
      if (!CS->size())
        return;
      typedef llvm::SmallVector<Stmt*, 32> Statements;
      Statements Stmts;
      Stmts.append(CS->body_begin(), CS->body_end());
      for (Statements::iterator I = Stmts.begin(); I != Stmts.end(); ++I) {
        if (!TraverseStmt(*I) && !m_HandledDecls.count(m_FoundDRE->getDecl())) {
          Sema::DeclGroupPtrTy VDPtrTy
            = m_Sema->ConvertDeclToDeclGroup(m_FoundDRE->getDecl());
          StmtResult DS = m_Sema->ActOnDeclStmt(VDPtrTy,
                                                m_FoundDRE->getLocStart(),
                                                m_FoundDRE->getLocEnd());
          assert(!DS.isInvalid() && "Invalid DeclStmt.");
          I = Stmts.insert(I, DS.get());
          m_HandledDecls.insert(m_FoundDRE->getDecl());
        }
      }
      CS->setStmts(m_Sema->getASTContext(), Stmts);
    }

    void Fix(CXXTryStmt* TS) {
      Fix(TS->getTryBlock());
      for(unsigned int h = 0; h < TS->getNumHandlers(); ++h) {
        Stmt *s = TS->getHandler(h)->getHandlerBlock();
        if (CompoundStmt* CS = dyn_cast_or_null<CompoundStmt>(s))
          Fix(CS);
        else if (CXXTryStmt *TS = dyn_cast_or_null<CXXTryStmt>(s))
          Fix(TS);
      }
    }

    bool VisitDeclRefExpr(DeclRefExpr* DRE) {
      const Decl* D = DRE->getDecl();
      if (const AnnotateAttr* A = D->getAttr<AnnotateAttr>())
        if (A->getAnnotation().equals("__Auto")) {
          m_FoundDRE = DRE;
          return false; // we abort on the first found candidate.
        }
      return true; // returning false will abort the in-depth traversal.
    }
  };
} // end namespace cling

namespace cling {
  AutoSynthesizer::AutoSynthesizer(clang::Sema* S)
    : ASTTransformer(S) {
    // TODO: We would like to keep that local without keeping track of all
    // decls that were handled in the AutoFixer. This can be done by removing
    // the __Auto attribute, but for now I am still hesitant to do it. Having
    // the __Auto attribute is very useful for debugging because it localize the
    // the problem if exists.
    m_AutoFixer.reset(new AutoFixer(S));
  }

  // pin the vtable here.
  AutoSynthesizer::~AutoSynthesizer()
  { }

  ASTTransformer::Result AutoSynthesizer::Transform(Decl* D) {
    if (FunctionDecl* FD = dyn_cast<FunctionDecl>(D)) {
      // getBody() might return nullptr even though hasBody() is true for
      // late template parsed functions. We simply don't do auto auto on
      // those.
      Stmt *Body = FD->getBody();
      if (CompoundStmt* CS = dyn_cast_or_null<CompoundStmt>(Body))
        m_AutoFixer->Fix(CS);
      else if (CXXTryStmt *TS = dyn_cast_or_null<CXXTryStmt>(Body))
        m_AutoFixer->Fix(TS);
    }
    return Result(D, true);
  }
} // end namespace cling
<commit_msg>Fix Coverity CID66882 - clash with parameter name.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Vassil Vassilev <vasil.georgiev.vasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "AutoSynthesizer.h"

#include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Sema/Sema.h"

using namespace clang;

namespace cling {
  class AutoFixer : public RecursiveASTVisitor<AutoFixer> {
  private:
    Sema* m_Sema;
    DeclRefExpr* m_FoundDRE;
    llvm::DenseSet<NamedDecl*> m_HandledDecls;
  private:
  public:
    AutoFixer(Sema* S) : m_Sema(S), m_FoundDRE(0) {}

    void Fix(CompoundStmt* CS) {
      if (!CS->size())
        return;
      typedef llvm::SmallVector<Stmt*, 32> Statements;
      Statements Stmts;
      Stmts.append(CS->body_begin(), CS->body_end());
      for (Statements::iterator I = Stmts.begin(); I != Stmts.end(); ++I) {
        if (!TraverseStmt(*I) && !m_HandledDecls.count(m_FoundDRE->getDecl())) {
          Sema::DeclGroupPtrTy VDPtrTy
            = m_Sema->ConvertDeclToDeclGroup(m_FoundDRE->getDecl());
          StmtResult DS = m_Sema->ActOnDeclStmt(VDPtrTy,
                                                m_FoundDRE->getLocStart(),
                                                m_FoundDRE->getLocEnd());
          assert(!DS.isInvalid() && "Invalid DeclStmt.");
          I = Stmts.insert(I, DS.get());
          m_HandledDecls.insert(m_FoundDRE->getDecl());
        }
      }
      CS->setStmts(m_Sema->getASTContext(), Stmts);
    }

    void Fix(CXXTryStmt* TS) {
      Fix(TS->getTryBlock());
      for(unsigned int h = 0; h < TS->getNumHandlers(); ++h) {
        Stmt *s = TS->getHandler(h)->getHandlerBlock();
        if (CompoundStmt* CS = dyn_cast_or_null<CompoundStmt>(s))
          Fix(CS);
        else if (CXXTryStmt *HandlerTS = dyn_cast_or_null<CXXTryStmt>(s))
          Fix(HandlerTS);
      }
    }

    bool VisitDeclRefExpr(DeclRefExpr* DRE) {
      const Decl* D = DRE->getDecl();
      if (const AnnotateAttr* A = D->getAttr<AnnotateAttr>())
        if (A->getAnnotation().equals("__Auto")) {
          m_FoundDRE = DRE;
          return false; // we abort on the first found candidate.
        }
      return true; // returning false will abort the in-depth traversal.
    }
  };
} // end namespace cling

namespace cling {
  AutoSynthesizer::AutoSynthesizer(clang::Sema* S)
    : ASTTransformer(S) {
    // TODO: We would like to keep that local without keeping track of all
    // decls that were handled in the AutoFixer. This can be done by removing
    // the __Auto attribute, but for now I am still hesitant to do it. Having
    // the __Auto attribute is very useful for debugging because it localize the
    // the problem if exists.
    m_AutoFixer.reset(new AutoFixer(S));
  }

  // pin the vtable here.
  AutoSynthesizer::~AutoSynthesizer()
  { }

  ASTTransformer::Result AutoSynthesizer::Transform(Decl* D) {
    if (FunctionDecl* FD = dyn_cast<FunctionDecl>(D)) {
      // getBody() might return nullptr even though hasBody() is true for
      // late template parsed functions. We simply don't do auto auto on
      // those.
      Stmt *Body = FD->getBody();
      if (CompoundStmt* CS = dyn_cast_or_null<CompoundStmt>(Body))
        m_AutoFixer->Fix(CS);
      else if (CXXTryStmt *TS = dyn_cast_or_null<CXXTryStmt>(Body))
        m_AutoFixer->Fix(TS);
    }
    return Result(D, true);
  }
} // end namespace cling
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: chips/p9/procedures/hwp/memory/lib/utils/conversions.H $      */
/*                                                                        */
/* IBM CONFIDENTIAL                                                       */
/*                                                                        */
/* EKB Project                                                            */
/*                                                                        */
/* COPYRIGHT 2015,2016                                                    */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* The source code for this program is not published or otherwise         */
/* divested of its trade secrets, irrespective of what has been           */
/* deposited with the U.S. Copyright Office.                              */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file conversions.H
/// @brief Functions to convert units
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: HB:FSP

#ifndef _MSS_CONVERSIONS_H_
#define _MSS_CONVERSIONS_H_

#include <vector>
#include <fapi2.H>
#include <lib/mss_attribute_accessors.H>
#include <lib/shared/mss_const.H>
#include <lib/utils/find.H>

///
/// @brief Dereferences pointer of the vector's underlying data
//  and casts it to uint8_t[Y] that FAPI_ATTR_SET is expecting by deduction
/// @param[in] X is the input vector
/// @param[in] Y is the size of the vector
/// @warn compiler doesn't like the use of vector method size() for the second param
///
#define UINT8_VECTOR_TO_1D_ARRAY(X, Y)\
    {\
        reinterpret_cast<uint8_t(&)[Y]>(*X.data())\
    }

///
/// @brief Dereferences pointer of the vector's underlying data
//  and casts it to uint16_t[Y] that FAPI_ATTR_SET is expecting by deduction
/// @param[in] X is the input vector
/// @param[in] Y is the size of the vector
/// @warn compiler doesn't like the use of vector method size() for the second param
///
#define UINT16_VECTOR_TO_1D_ARRAY(X, Y)\
    {\
        reinterpret_cast<uint16_t(&)[Y]>(*X.data())\
    }

///
/// @brief Dereferences pointer of the vector's underlying data
//  and casts it to uint32_t[Y] that FAPI_ATTR_SET is expecting by deduction
/// @param[in] X is the input vector
/// @param[in] Y is the size of the vector
/// @warn compiler doesn't like the use of vector method size() for the second param
///
#define UINT32_VECTOR_TO_1D_ARRAY(X, Y)\
    {\
        reinterpret_cast<uint32_t(&)[Y]>(*X.data())\
    }

// Mutiplication factor to go from clocks to simcycles.
// Is this just 2400 speed or does this hold for all? BRS
static const uint64_t SIM_CYCLES_PER_CYCLE = 8;

namespace mss
{

///
/// @brief     Return the number of picoseconds
/// @tparam    T input and output type
/// @param[in] i_transfer_rate input in MegaTransfers per second (MT/s)
/// @return    timing in picoseconds
/// @note      clock periods are defined to 1 ps of accuracy, so
///            so 1.0714 ns is defined as 1071 ps as defined by JEDEC's
///            SPD rounding algorithm. This concept is used for this calculation.
///
template<typename T>
inline T freq_to_ps(const T i_transfer_rate)
{
    // ATTR_MSS_FREQ is in MT/s, and we know microsecond per clock is 1/(freq/2)
    // actual dimm_freq is 1/2 of the speed bin
    T l_dimm_freq = i_transfer_rate / 2;

    // ps per clock (note value is rounded down)
    return CONVERT_PS_IN_A_US / l_dimm_freq;
}

///
/// @brief      Return the number in MT/s
/// @tparam     T input and output type
/// @param[in]  i_time_in_ps time in picoseconds
/// @return     speed in MT/s
///
template<typename T>
inline T ps_to_freq(const T i_time_in_ps)
{
    // reverse of freq_to_ps function, solving for freq
    // since running at DDR, data is transferred on both rising & falling edges
    // hence the 2X factor
    return (2 * CONVERT_PS_IN_A_US) / i_time_in_ps;
}

///
/// @brief Translate from cycles to sim cycles
/// @param[in] i_cycles the cycles to translate
/// @return uint64_t, the number of sim cycles.
///
inline uint64_t cycles_to_simcycles( const uint64_t i_cycles )
{
    // Is this always the case or do we need the freq to really figure this out?
    return i_cycles * SIM_CYCLES_PER_CYCLE;
}

///
/// @brief Return the number of cycles contained in a count of picoseconds
/// @param[in] i_target target for the frequency attribute
/// @param[in] i_ps the number of picoseconds to convert
/// @return uint64_t, the number of cycles
///
template< fapi2::TargetType T >
inline uint64_t ps_to_cycles(const fapi2::Target<T>& i_target, const uint64_t i_ps)
{
    // The frequency in mHZ
    uint64_t l_freq = 0;
    uint64_t l_divisor = 0;
    uint64_t l_quotient = 0;
    uint64_t l_remainder = 0;

    FAPI_TRY( mss::freq( find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq) );

    // Hoping the compiler figures out how to do these together.
    l_divisor = freq_to_ps(l_freq);
    l_quotient = i_ps / l_divisor;
    l_remainder = i_ps % l_divisor;

    // Make sure we add a cycle if there wasn't an even number of cycles in the input
    FAPI_DBG("converting %llups to %llu cycles", i_ps, l_quotient + (l_remainder == 0 ? 0 : 1));

    return l_quotient + (l_remainder == 0 ? 0 : 1);

fapi_try_exit:

    // We simply can't work if we can't get the frequency - so this should be ok
    FAPI_ERR("Can't get MSS_FREQ - stopping");
    fapi2::Assert(false);

    // Keeps compiler happy
    return 0;
}

///
/// @brief Return the number of ps contained in a count of cycles
/// @param[in] i_target target for the frequency attribute
/// @param[in] i_cycles the number of cycles to convert
/// @return uint64_t, the number of picoseconds
///
template< fapi2::TargetType T >
inline uint64_t cycles_to_ps(const fapi2::Target<T>& i_target, const uint64_t i_cycles)
{
    // The frequency in mHZ
    uint64_t l_freq = 0;

    FAPI_TRY( mss::freq( find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq) );

    FAPI_DBG("converting %llu cycles to %llups", i_cycles, i_cycles * freq_to_ps(l_freq));
    return i_cycles * freq_to_ps(l_freq);

fapi_try_exit:

    // We simply can't work if we can't get the frequency - so this should be ok
    FAPI_ERR("Can't get MSS_FREQ - stopping");
    fapi2::Assert(false);

    // Keeps compiler happy
    return 0;
}

///
/// @brief Return the number of cycles contained in a count of microseconds
/// @param[in] i_target target for the frequency attribute
/// @param[in] i_us the number of microseconds to convert
/// @return uint64_t, the number of cycles
///
template< fapi2::TargetType T >
inline uint64_t us_to_cycles(const fapi2::Target<T>& i_target, const uint64_t i_us)
{
    return ps_to_cycles(i_target, i_us * CONVERT_PS_IN_A_US);
}

///
/// @brief Return the number of cycles contained in a count of nanoseconds
/// @param[in] i_target target for the frequency attribute
/// @param[in] i_ps the number of nanoseconds to convert
/// @return uint64_t, the number of cycles
///
template< fapi2::TargetType T >
inline uint64_t ns_to_cycles(const fapi2::Target<T>& i_target, const uint64_t i_ns)
{
    return ps_to_cycles(i_target, i_ns * CONVERT_PS_IN_A_NS);
}

///
/// @brief Return the number of microseconds contained in a count of cycles
/// @tparam T the target type
/// @tparam D the time conversion (NS_IN_PS, etc)
/// @param[in] i_target target for the frequency attribute
/// @param[in] i_cycles the number of cycles to convert
/// @return uint64_t, the number of microseconds
///
template< fapi2::TargetType T, uint64_t D >
inline uint64_t cycles_to_time(const fapi2::Target<T>& i_target, const uint64_t i_cycles)
{
    // Hoping the compiler figures out how to do these together.
    uint64_t l_dividend = cycles_to_ps(i_target, i_cycles);
    uint64_t l_quotient = l_dividend / D;
    uint64_t l_remainder = l_dividend % D;

    // Make sure we add time if there wasn't an even number of cycles
    return  l_quotient + (l_remainder == 0 ? 0 : 1);
}

///
/// @brief Return the number of nanoseconds contained in a count of cycles
/// @param[in] i_target target for the frequency attribute
/// @param[in] i_cycles the number of cycles to convert
/// @return uint64_t, the number of nanoseconds
///
template< fapi2::TargetType T >
inline uint64_t cycles_to_ns(const fapi2::Target<T>& i_target, const uint64_t i_cycles)
{
    uint64_t l_ns = cycles_to_time<T, CONVERT_PS_IN_A_NS>(i_target, i_cycles);
    FAPI_DBG("converting %llu cycles to %lluns", i_cycles, l_ns);

    return l_ns;
}

///
/// @brief Return the number of microseconds contained in a count of cycles
/// @param[in] i_target target for the frequency attribute
/// @param[in] i_cycles the number of cycles to convert
/// @return uint64_t, the number of microseconds
///
template< fapi2::TargetType T >
inline uint64_t cycles_to_us(const fapi2::Target<T>& i_target, const uint64_t i_cycles)
{
    uint64_t l_us = cycles_to_time<T, CONVERT_PS_IN_A_US>(i_target, i_cycles);
    FAPI_DBG("converting %llu cycles to %lluus", i_cycles, l_us);

    return l_us;
}

///
/// @brief Calculate TWLO_TWLOE - this needs to go in to eff_config and be an attribute
/// @tparam T fapi2::TargetType of the target used to calculate cycles from ns
/// @param[in] i_target the target used to get DIMM clocks
/// @return uint64_t, TWLO_TWLOE in cycles
///
template< fapi2::TargetType T >
inline uint64_t twlo_twloe(const fapi2::Target<T>& i_target)
{
    return 12 + mss::ns_to_cycles(i_target, tWLO - tWLOE);
}

///
/// @brief     Convert nanoseconds to picoseconds
/// @tparam    T input and output type
/// @param[in] i_time_in_ns time in nanoseconds
/// @return    time in picoseconds
///
template<typename T>
inline T ns_to_ps(const T i_time_in_ns)
{
    return i_time_in_ns * CONVERT_PS_IN_A_NS;
}

///
/// @brief     Convert nanoseconds to picoseconds
/// @tparam    T input and output type
/// @param[in] i_time_in_ps time in picoseconds
/// @return    time in nanoseconds
///
template<typename T>
inline T ps_to_ns(const T i_time_in_ps)
{
    T remainder = i_time_in_ps % CONVERT_PS_IN_A_NS;
    T l_time_in_ns = i_time_in_ps / CONVERT_PS_IN_A_NS;

    // Round up if remainder isn't even
    return l_time_in_ns + ( remainder == 0 ? 0 : 1 );
}

};// mss namespace

#endif
<commit_msg>Remove curly brackets for VECTOR_TO_1D_ARRAY macros<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: chips/p9/procedures/hwp/memory/lib/utils/conversions.H $      */
/*                                                                        */
/* IBM CONFIDENTIAL                                                       */
/*                                                                        */
/* EKB Project                                                            */
/*                                                                        */
/* COPYRIGHT 2015,2016                                                    */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* The source code for this program is not published or otherwise         */
/* divested of its trade secrets, irrespective of what has been           */
/* deposited with the U.S. Copyright Office.                              */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file conversions.H
/// @brief Functions to convert units
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: HB:FSP

#ifndef _MSS_CONVERSIONS_H_
#define _MSS_CONVERSIONS_H_

#include <vector>
#include <fapi2.H>
#include <lib/mss_attribute_accessors.H>
#include <lib/shared/mss_const.H>
#include <lib/utils/find.H>

///
/// @brief Dereferences pointer of the vector's underlying data
//  and casts it to uint8_t[Y] that FAPI_ATTR_SET is expecting by deduction
/// @param[in] X is the input vector
/// @param[in] Y is the size of the vector
/// @warn compiler doesn't like the use of vector method size() for the second param
///
#define UINT8_VECTOR_TO_1D_ARRAY(X, Y)\
    reinterpret_cast<uint8_t(&)[Y]>(*X.data())

///
/// @brief Dereferences pointer of the vector's underlying data
//  and casts it to uint16_t[Y] that FAPI_ATTR_SET is expecting by deduction
/// @param[in] X is the input vector
/// @param[in] Y is the size of the vector
/// @warn compiler doesn't like the use of vector method size() for the second param
///
#define UINT16_VECTOR_TO_1D_ARRAY(X, Y)\
    reinterpret_cast<uint16_t(&)[Y]>(*X.data())

///
/// @brief Dereferences pointer of the vector's underlying data
//  and casts it to uint32_t[Y] that FAPI_ATTR_SET is expecting by deduction
/// @param[in] X is the input vector
/// @param[in] Y is the size of the vector
/// @warn compiler doesn't like the use of vector method size() for the second param
///
#define UINT32_VECTOR_TO_1D_ARRAY(X, Y)\
    reinterpret_cast<uint32_t(&)[Y]>(*X.data())

// Mutiplication factor to go from clocks to simcycles.
// Is this just 2400 speed or does this hold for all? BRS
static const uint64_t SIM_CYCLES_PER_CYCLE = 8;

namespace mss
{

///
/// @brief     Return the number of picoseconds
/// @tparam    T input and output type
/// @param[in] i_transfer_rate input in MegaTransfers per second (MT/s)
/// @return    timing in picoseconds
/// @note      clock periods are defined to 1 ps of accuracy, so
///            so 1.0714 ns is defined as 1071 ps as defined by JEDEC's
///            SPD rounding algorithm. This concept is used for this calculation.
///
template<typename T>
inline T freq_to_ps(const T i_transfer_rate)
{
    // ATTR_MSS_FREQ is in MT/s, and we know microsecond per clock is 1/(freq/2)
    // actual dimm_freq is 1/2 of the speed bin
    T l_dimm_freq = i_transfer_rate / 2;

    // ps per clock (note value is rounded down)
    return CONVERT_PS_IN_A_US / l_dimm_freq;
}

///
/// @brief      Return the number in MT/s
/// @tparam     T input and output type
/// @param[in]  i_time_in_ps time in picoseconds
/// @return     speed in MT/s
///
template<typename T>
inline T ps_to_freq(const T i_time_in_ps)
{
    // reverse of freq_to_ps function, solving for freq
    // since running at DDR, data is transferred on both rising & falling edges
    // hence the 2X factor
    return (2 * CONVERT_PS_IN_A_US) / i_time_in_ps;
}

///
/// @brief Translate from cycles to sim cycles
/// @param[in] i_cycles the cycles to translate
/// @return uint64_t, the number of sim cycles.
///
inline uint64_t cycles_to_simcycles( const uint64_t i_cycles )
{
    // Is this always the case or do we need the freq to really figure this out?
    return i_cycles * SIM_CYCLES_PER_CYCLE;
}

///
/// @brief Return the number of cycles contained in a count of picoseconds
/// @param[in] i_target target for the frequency attribute
/// @param[in] i_ps the number of picoseconds to convert
/// @return uint64_t, the number of cycles
///
template< fapi2::TargetType T >
inline uint64_t ps_to_cycles(const fapi2::Target<T>& i_target, const uint64_t i_ps)
{
    // The frequency in mHZ
    uint64_t l_freq = 0;
    uint64_t l_divisor = 0;
    uint64_t l_quotient = 0;
    uint64_t l_remainder = 0;

    FAPI_TRY( mss::freq( find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq) );

    // Hoping the compiler figures out how to do these together.
    l_divisor = freq_to_ps(l_freq);
    l_quotient = i_ps / l_divisor;
    l_remainder = i_ps % l_divisor;

    // Make sure we add a cycle if there wasn't an even number of cycles in the input
    FAPI_DBG("converting %llups to %llu cycles", i_ps, l_quotient + (l_remainder == 0 ? 0 : 1));

    return l_quotient + (l_remainder == 0 ? 0 : 1);

fapi_try_exit:

    // We simply can't work if we can't get the frequency - so this should be ok
    FAPI_ERR("Can't get MSS_FREQ - stopping");
    fapi2::Assert(false);

    // Keeps compiler happy
    return 0;
}

///
/// @brief Return the number of ps contained in a count of cycles
/// @param[in] i_target target for the frequency attribute
/// @param[in] i_cycles the number of cycles to convert
/// @return uint64_t, the number of picoseconds
///
template< fapi2::TargetType T >
inline uint64_t cycles_to_ps(const fapi2::Target<T>& i_target, const uint64_t i_cycles)
{
    // The frequency in mHZ
    uint64_t l_freq = 0;

    FAPI_TRY( mss::freq( find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_freq) );

    FAPI_DBG("converting %llu cycles to %llups", i_cycles, i_cycles * freq_to_ps(l_freq));
    return i_cycles * freq_to_ps(l_freq);

fapi_try_exit:

    // We simply can't work if we can't get the frequency - so this should be ok
    FAPI_ERR("Can't get MSS_FREQ - stopping");
    fapi2::Assert(false);

    // Keeps compiler happy
    return 0;
}

///
/// @brief Return the number of cycles contained in a count of microseconds
/// @param[in] i_target target for the frequency attribute
/// @param[in] i_us the number of microseconds to convert
/// @return uint64_t, the number of cycles
///
template< fapi2::TargetType T >
inline uint64_t us_to_cycles(const fapi2::Target<T>& i_target, const uint64_t i_us)
{
    return ps_to_cycles(i_target, i_us * CONVERT_PS_IN_A_US);
}

///
/// @brief Return the number of cycles contained in a count of nanoseconds
/// @param[in] i_target target for the frequency attribute
/// @param[in] i_ps the number of nanoseconds to convert
/// @return uint64_t, the number of cycles
///
template< fapi2::TargetType T >
inline uint64_t ns_to_cycles(const fapi2::Target<T>& i_target, const uint64_t i_ns)
{
    return ps_to_cycles(i_target, i_ns * CONVERT_PS_IN_A_NS);
}

///
/// @brief Return the number of microseconds contained in a count of cycles
/// @tparam T the target type
/// @tparam D the time conversion (NS_IN_PS, etc)
/// @param[in] i_target target for the frequency attribute
/// @param[in] i_cycles the number of cycles to convert
/// @return uint64_t, the number of microseconds
///
template< fapi2::TargetType T, uint64_t D >
inline uint64_t cycles_to_time(const fapi2::Target<T>& i_target, const uint64_t i_cycles)
{
    // Hoping the compiler figures out how to do these together.
    uint64_t l_dividend = cycles_to_ps(i_target, i_cycles);
    uint64_t l_quotient = l_dividend / D;
    uint64_t l_remainder = l_dividend % D;

    // Make sure we add time if there wasn't an even number of cycles
    return  l_quotient + (l_remainder == 0 ? 0 : 1);
}

///
/// @brief Return the number of nanoseconds contained in a count of cycles
/// @param[in] i_target target for the frequency attribute
/// @param[in] i_cycles the number of cycles to convert
/// @return uint64_t, the number of nanoseconds
///
template< fapi2::TargetType T >
inline uint64_t cycles_to_ns(const fapi2::Target<T>& i_target, const uint64_t i_cycles)
{
    uint64_t l_ns = cycles_to_time<T, CONVERT_PS_IN_A_NS>(i_target, i_cycles);
    FAPI_DBG("converting %llu cycles to %lluns", i_cycles, l_ns);

    return l_ns;
}

///
/// @brief Return the number of microseconds contained in a count of cycles
/// @param[in] i_target target for the frequency attribute
/// @param[in] i_cycles the number of cycles to convert
/// @return uint64_t, the number of microseconds
///
template< fapi2::TargetType T >
inline uint64_t cycles_to_us(const fapi2::Target<T>& i_target, const uint64_t i_cycles)
{
    uint64_t l_us = cycles_to_time<T, CONVERT_PS_IN_A_US>(i_target, i_cycles);
    FAPI_DBG("converting %llu cycles to %lluus", i_cycles, l_us);

    return l_us;
}

///
/// @brief Calculate TWLO_TWLOE - this needs to go in to eff_config and be an attribute
/// @tparam T fapi2::TargetType of the target used to calculate cycles from ns
/// @param[in] i_target the target used to get DIMM clocks
/// @return uint64_t, TWLO_TWLOE in cycles
///
template< fapi2::TargetType T >
inline uint64_t twlo_twloe(const fapi2::Target<T>& i_target)
{
    return 12 + mss::ns_to_cycles(i_target, tWLO - tWLOE);
}

///
/// @brief     Convert nanoseconds to picoseconds
/// @tparam    T input and output type
/// @param[in] i_time_in_ns time in nanoseconds
/// @return    time in picoseconds
///
template<typename T>
inline T ns_to_ps(const T i_time_in_ns)
{
    return i_time_in_ns * CONVERT_PS_IN_A_NS;
}

///
/// @brief     Convert nanoseconds to picoseconds
/// @tparam    T input and output type
/// @param[in] i_time_in_ps time in picoseconds
/// @return    time in nanoseconds
///
template<typename T>
inline T ps_to_ns(const T i_time_in_ps)
{
    T remainder = i_time_in_ps % CONVERT_PS_IN_A_NS;
    T l_time_in_ns = i_time_in_ps / CONVERT_PS_IN_A_NS;

    // Round up if remainder isn't even
    return l_time_in_ns + ( remainder == 0 ? 0 : 1 );
}

};// mss namespace

#endif
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/nest/p9_exit_cache_contained.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///----------------------------------------------------------------------------
/// @file p9_exit_cache_contained.C
///
/// @brief  Contains inits to be performed before Hostboot expanded from
///         running inside the confines of the L3 cache out to main memory.
///----------------------------------------------------------------------------

// *HWP HWP Owner: Joe McGill <jmcgill@us.ibm.com>
// *HWP FW Owner: Thi Tran <thi@us.ibm.com>
// *HWP Team: Nest
// *HWP Level: 2
// *HWP Consumed by: HB

//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include <p9_exit_cache_contained.H>

extern "C"
{
///
/// p9_exit_cache_contained HWP entry point (Defined in .H file)
///
    fapi2::ReturnCode p9_exit_cache_contained(const
            fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>
            & i_target)
    {
        fapi2::ReturnCode rc;

        // Mark Entry
        FAPI_INF("Entering ...");

        // This procedure is a placeholder to add inits that might need to be
        // performed before Hostboot expanded from running inside the confines
        // of the L3 cache out to main memory.
        // There is nothing specific to be added for P9 at this point.

        // Mark Exit
        FAPI_INF("Exiting ...");

        return rc;
    }
} // extern "C"
/* End: */
<commit_msg>L3 updates -- shell HWPs<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/nest/p9_exit_cache_contained.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_exit_cache_contained.C
/// @brief Placeholder to apply inits needed prior to HB expansion from L3
/// cache to main memory (FAPI2)
///
/// @author Joe McGill <jmcgill@us.ibm.com>
///

//
// *HWP HWP Owner: Joe McGill <jmcgill@us.ibm.com>
// *HWP FW Owner: Thi Tran <thi@us.ibm.com>
// *HWP Team: Nest
// *HWP Level: 3
// *HWP Consumed by: HB
//

//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include <p9_exit_cache_contained.H>

//------------------------------------------------------------------------------
// Function definitions
//------------------------------------------------------------------------------

fapi2::ReturnCode
p9_exit_cache_contained(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
    // This procedure is a placeholder to add inits that might need to be
    // performed before Hostboot expanded from running inside the confines
    // of the L3 cache out to main memory.
    // There is nothing specific to be added for P9 at this point.

    FAPI_INF("Start");
    FAPI_INF("End");

    return fapi2::FAPI2_RC_SUCCESS;
}
<|endoftext|>


<commit_before>#ifndef VIENNAGRID_DETAIL_LOWER_LEVEL_HOLDER_HPP
#define VIENNAGRID_DETAIL_LOWER_LEVEL_HOLDER_HPP

/* =======================================================================
   Copyright (c) 2011-2012, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.

                            -----------------
                     ViennaGrid - The Vienna Grid Library
                            -----------------

   Authors:      Karl Rupp                           rupp@iue.tuwien.ac.at
                 Josef Weinbub                    weinbub@iue.tuwien.ac.at

   (A list of additional contributors can be found in the PDF manual)

   License:      MIT (X11), see file LICENSE in the base directory
======================================================================= */

#include <iostream>

#include "viennagrid/forwards.h"
//#include "viennagrid/topology/point.hpp"
//#include "viennagrid/iterators.hpp"
#include "viennagrid/detail/element_orientation.hpp"

#include <vector>

/** @file boundary_ncell_layer.hpp
    @brief Provides the topological layers for n-cells
*/

namespace viennagrid
{

  /************** Level 1: Elements contained by a higher-level element *******/

  /** @brief A class holding all information about boundary k-cells of a n-cell
   *
   * @tparam ConfigType       The configuration class
   * @tparam ElementTag       The n-cell tag
   * @tparam dim              Topological dimension k of the boundary k-cells
   * @tparam handling_tag     Whether or not to store references to boundary k-cells
   * @tparam orienter_tag     Whether or not to store orientations of k-cells with respect to the n-cell
   * @tparam LevelNull        Helper parameter to avoid ambiguities at vertex level.
   */
  template <typename ConfigType,
              typename ElementTag,
              unsigned long dim,
              typename handling_tag = typename result_of::bndcell_handling<ConfigType, ElementTag, dim>::type,
              typename orienter_tag = typename result_of::bndcell_orientation<ConfigType, ElementTag, dim>::type,
              bool LevelNull = (dim == 0)>
  class boundary_ncell_layer  { };

  //
  // Full storage of boundary cell, including orientation
  //
  /** @brief Implementation of full storage of k-cells including orientations */
  template <typename ConfigType, typename ElementTag, unsigned long dim>
  class boundary_ncell_layer <ConfigType, ElementTag, dim, full_handling_tag, full_handling_tag, false> :
    public boundary_ncell_layer <ConfigType, ElementTag, dim - 1>
  {
    //requirements:
    //array of pointers to elements of class 'dim' and a integer representing the orientation within the cell relative to the element it points to.
    typedef topology::bndcells<ElementTag, dim>                         LevelSpecs;
    typedef topology::bndcells<typename LevelSpecs::tag, 0>  VertexOnElementSpecs;
    typedef boundary_ncell_layer <ConfigType, ElementTag, dim - 1 >      Base;

    typedef element_t<ConfigType, typename LevelSpecs::tag>  LevelElementType;
    typedef element_orientation<VertexOnElementSpecs::num>     ElementOrientationType;
    typedef typename result_of::element_container<element_t<ConfigType, ElementTag>, dim, ElementTag::dim>::type      container_type;

    protected:
      template <typename DomainType>
      void fill_level(DomainType & dom)
      {
        //fill lower level first:
        Base::fill_level(dom);

        //for (long i=0; i<LevelSpecs::num; ++i)
        //  orientations_[i].resize(VertexOnElementSpecs::num);

        topology::bndcell_filler<ElementTag, dim>::fill(&(elements_[0]),
                                                           &(Base::vertices_[0]),
                                                           &(orientations_[0]),
                                                           dom);
      }

    public:

      boundary_ncell_layer( )
      {
        for (long i=0; i < LevelSpecs::num; ++i)
          elements_[i] = NULL;
      };

      boundary_ncell_layer( const boundary_ncell_layer & llh) : Base (llh)
      {
        for (long i=0; i < LevelSpecs::num; ++i)
          elements_[i] = llh.elements_[i];
      }

      /////////////////// access container: ////////////////////

      using Base::container;

      //non-const:
      container_type *
      container(dimension_tag<dim>)
      {
        return &(elements_[0]);
      }

      //const:

      const container_type *
      container(dimension_tag<dim>) const
      {
        return &(elements_[0]);
      }

      ////////////////// orientation: ////////////////////
      std::size_t global_to_local_orientation(LevelElementType const & el, long index) const
      {
        for (std::size_t i=0; i<LevelSpecs::num; ++i)
        {
          if (elements_[i] == &el)
            return orientations_[i](index);
        }
        assert(false && "Provided k-cell is not a boundary element of the hosting n-cell!");
        return index;
      }

    private:
      container_type elements_[LevelSpecs::num];
      ElementOrientationType orientations_[LevelSpecs::num];
  };

  //
  // Full storage of boundary cell, but no orientation
  //
  /** @brief Implementation of boundary k-cell storage without orientation */
  template <typename ConfigType, typename ElementTag, unsigned long dim>
  class boundary_ncell_layer <ConfigType, ElementTag, dim, full_handling_tag, no_handling_tag, false> :
    public boundary_ncell_layer <ConfigType, ElementTag, dim - 1>
  {
    //requirements:
    //array of pointers to elements of class 'dim' and a integer representing the orientation within the cell relative to the element it points to.
    typedef topology::bndcells<ElementTag, dim>                         LevelSpecs;
    typedef topology::bndcells<typename LevelSpecs::tag, 0>  VertexOnElementSpecs;
    typedef boundary_ncell_layer <ConfigType, ElementTag, dim - 1 >      Base;

    typedef element_t<ConfigType, typename LevelSpecs::tag>  LevelElementType;
    typedef element_orientation<VertexOnElementSpecs::num>     ElementOrientationType;
    typedef typename result_of::element_container<element_t<ConfigType, ElementTag>, dim, ElementTag::dim>::type      container_type;

    protected:
      template <typename DomainType>
      void fill_level(DomainType & dom)
      {
        typedef ElementOrientationType *    OrientationPointer;
        //fill lower level first:
        Base::fill_level(dom);

        topology::bndcell_filler<ElementTag, dim>::fill(&(elements_[0]),
                                                           &(Base::vertices_[0]),
                                                           OrientationPointer(NULL),
                                                           dom);
      }

    public:

      boundary_ncell_layer( )
      {
        for (long i=0; i < LevelSpecs::num; ++i)
          elements_[i] = NULL;
      };

      boundary_ncell_layer( const boundary_ncell_layer & llh) : Base (llh)
      {
        for (long i=0; i < LevelSpecs::num; ++i)
          elements_[i] = llh.elements_[i];
      }

      /////////////////// access container: ////////////////////

      using Base::container;

      //non-const:
      container_type *
      container(dimension_tag<dim>)
      {
        return &(elements_[0]);
      }

      //const:
      const container_type *
      container(dimension_tag<dim>) const
      {
        return &(elements_[0]);
      }

    private:
      container_type elements_[LevelSpecs::num];
  };

  //
  // No storage of boundary elements:
  //
  /** @brief Implementation of the case that boundary k-cells are not stored at all */
  template <typename ConfigType, typename ElementTag, unsigned long dim, typename orienter_tag>
  class boundary_ncell_layer <ConfigType, ElementTag, dim, no_handling_tag, orienter_tag, false> :
    public boundary_ncell_layer < ConfigType, ElementTag, dim - 1 >
  {
    //requirements:
    //array of pointers to elements of class 'dim' and a integer representing the orientation within the cell relative to the element it points to.
    //typedef typename DomainTypes<ConfigType>::segment_type        SegmentType;
    typedef topology::bndcells<ElementTag, dim>                                LevelSpecs;
    typedef boundary_ncell_layer < ConfigType, ElementTag, dim - 1 >      Base;

    typedef element_t<ConfigType, typename LevelSpecs::tag>  LevelElementType;

    protected:
      template <typename DomainType>
      void fill_level(DomainType & dom)
      {
        //fill lower topological levels only:
        Base::fill_level(dom);
      }

    public:

      boundary_ncell_layer( ) {};

      boundary_ncell_layer( const boundary_ncell_layer & llh) : Base (llh) {}

  };

  //at level 0, i.e. vertex level, recursion ends:
  /** @brief Specialization for the vertex level. Recursion ends here */
  template <typename ConfigType, typename ElementTag, typename handling_tag, typename orienter_tag>
  class boundary_ncell_layer <ConfigType, ElementTag, 0, handling_tag, orienter_tag, true>
  {
    //array of pointers to elements of class 'dim' and a integer representing the orientation within the cell relative to the element it points to.
    //typedef typename DomainTypes<ConfigType>::segment_type               SegmentType;
    typedef topology::bndcells<ElementTag, 0>                                      LevelSpecs;

    typedef element_t<ConfigType, typename LevelSpecs::tag>         VertexType;
    typedef typename result_of::point<ConfigType>::type              PointType;

    typedef typename result_of::iterator< element_t<ConfigType, ElementTag>, 0>::type         VertexIterator;

    protected:
      //end recursion:
      template <typename DomainType>
      void fill_level(DomainType & dom) {}

    public:
      boundary_ncell_layer() {};

      boundary_ncell_layer( const boundary_ncell_layer & llh)
      {
        for (long i=0; i < LevelSpecs::num; ++i)
          vertices_[i] = llh.vertices_[i];
      }

      ////////////////// container access: /////////////////////////

      //non-const:
      VertexType * *
      container(dimension_tag<0>)
      {
        return &(vertices_[0]);
      }

      //const:
      VertexType * const *
      container(dimension_tag<0>) const
      {
        return &(vertices_[0]);
      }

    protected:
      VertexType * vertices_[LevelSpecs::num];
  };

}

#endif

<commit_msg>added support for STL like container (instead of TYPE*)<commit_after>#ifndef VIENNAGRID_DETAIL_LOWER_LEVEL_HOLDER_HPP
#define VIENNAGRID_DETAIL_LOWER_LEVEL_HOLDER_HPP

/* =======================================================================
   Copyright (c) 2011-2012, Institute for Microelectronics,
                            Institute for Analysis and Scientific Computing,
                            TU Wien.

                            -----------------
                     ViennaGrid - The Vienna Grid Library
                            -----------------

   Authors:      Karl Rupp                           rupp@iue.tuwien.ac.at
                 Josef Weinbub                    weinbub@iue.tuwien.ac.at

   (A list of additional contributors can be found in the PDF manual)

   License:      MIT (X11), see file LICENSE in the base directory
======================================================================= */

#include <iostream>

#include "viennagrid/forwards.h"
//#include "viennagrid/topology/point.hpp"
//#include "viennagrid/iterators.hpp"
#include "viennagrid/detail/element_orientation.hpp"

namespace viennagrid
{

  /************** Level 1: Elements contained by a higher-level element *******/

  /** @brief A class holding all information about boundary k-cells of a n-cell
   *
   * @tparam ConfigType       The configuration class
   * @tparam ElementTag       The n-cell tag
   * @tparam dim              Topological dimension k of the boundary k-cells
   * @tparam handling_tag     Whether or not to store references to boundary k-cells
   * @tparam orienter_tag     Whether or not to store orientations of k-cells with respect to the n-cell
   * @tparam LevelNull        Helper parameter to avoid ambiguities at vertex level.
   */
  template <typename ConfigType,
              typename ElementTag,
              unsigned long dim,
              typename handling_tag = typename result_of::bndcell_handling<ConfigType, ElementTag, dim>::type,
              typename orienter_tag = typename result_of::bndcell_orientation<ConfigType, ElementTag, dim>::type,
              bool LevelNull = (dim == 0)>
  class boundary_ncell_layer  { };

  //
  // Full storage of boundary cell, including orientation
  //

  /** @brief Implementation of full storage of k-cells including orientations */
  template <typename ConfigType, typename ElementTag, unsigned long dim>
  class boundary_ncell_layer <ConfigType, ElementTag, dim, full_handling_tag, full_handling_tag, false> :
    public boundary_ncell_layer <ConfigType, ElementTag, dim - 1>
  {
    //requirements:
    //array of pointers to elements of class 'dim' and a integer representing the orientation within the cell relative to the element it points to.
    typedef topology::bndcells<ElementTag, dim>                         LevelSpecs;
    typedef topology::bndcells<typename LevelSpecs::tag, 0>  VertexOnElementSpecs;
    typedef boundary_ncell_layer <ConfigType, ElementTag, dim - 1 >      Base;

    typedef element_t<ConfigType, typename LevelSpecs::tag>  LevelElementType;
    typedef element_orientation<VertexOnElementSpecs::num>     ElementOrientationType;

    typedef typename topology::bndcells<ElementTag, dim>::layout_tag layout_tag;
    static const long array_size = topology::bndcells<ElementTag, dim>::num;
    typedef typename result_of::ncell<ConfigType, dim>::type            element_type;

    typedef typename result_of::container<element_type *, layout_tag, array_size>::type      element_container_type;
    typedef typename result_of::container<ElementOrientationType, layout_tag, array_size>::type      orientation_container_type;

    typedef typename result_of::ncell<ConfigType, 0>::type      VertexType;

    protected:
      template <typename DomainType>
      void fill_level(DomainType & dom)
      {
        //fill lower level first:
        Base::fill_level(dom);

        //for (long i=0; i<LevelSpecs::num; ++i)
        //  orientations_[i].resize(VertexOnElementSpecs::num);

        topology::bndcell_filler<ElementTag, dim>::fill(elements_,
                                                           Base::vertices_,
                                                           orientations_,
                                                           dom);
      }

    public:

      boundary_ncell_layer( )
      {
          std::fill( elements_.begin(), elements_.end(), static_cast<element_type *>(NULL) );
      };

      boundary_ncell_layer( const boundary_ncell_layer & llh) : Base (llh), elements_(llh.elements_), orientations_(llh.orientations_) {}

      /////////////////// access container: ////////////////////

      using Base::container;

      //non-const:
      element_container_type *
      container(dimension_tag<dim>)
      {
        return &elements_;
      }

      //const:

      const element_container_type *
      container(dimension_tag<dim>) const
      {
        return &elements_;
      }

      ////////////////// orientation: ////////////////////
      std::size_t global_to_local_orientation(LevelElementType const & el, long index) const
      {
        for (std::size_t i=0; i<LevelSpecs::num; ++i)
        {
          if (elements_[i] == &el)
            return orientations_[i](index);
        }
        assert(false && "Provided k-cell is not a boundary element of the hosting n-cell!");
        return index;
      }

      void fill_vertices(VertexType ** vertices_, size_t num)
      {
            Base::fill_vertices(vertices_, num);
      }

    private:
      element_container_type elements_;
      orientation_container_type orientations_;
  };

  //
  // Full storage of boundary cell, but no orientation
  //
  /** @brief Implementation of boundary k-cell storage without orientation */
  template <typename ConfigType, typename ElementTag, unsigned long dim>
  class boundary_ncell_layer <ConfigType, ElementTag, dim, full_handling_tag, no_handling_tag, false> :
    public boundary_ncell_layer <ConfigType, ElementTag, dim - 1>
  {
    //requirements:
    //array of pointers to elements of class 'dim' and a integer representing the orientation within the cell relative to the element it points to.
    typedef topology::bndcells<ElementTag, dim>                         LevelSpecs;
    typedef topology::bndcells<typename LevelSpecs::tag, 0>  VertexOnElementSpecs;
    typedef boundary_ncell_layer <ConfigType, ElementTag, dim - 1 >      Base;

    typedef element_t<ConfigType, typename LevelSpecs::tag>  LevelElementType;
    typedef element_orientation<VertexOnElementSpecs::num>     ElementOrientationType;

    typedef typename topology::bndcells<ElementTag, dim>::layout_tag layout_tag;
    static const long array_size = topology::bndcells<ElementTag, dim>::num;
    typedef typename result_of::ncell<ConfigType, dim>::type            element_type;

    typedef typename result_of::container<element_type *, layout_tag, array_size>::type      element_container_type;

    typedef typename result_of::ncell<ConfigType, 0>::type      VertexType;

    protected:
      template <typename DomainType>
      void fill_level(DomainType & dom)
      {
        typedef ElementOrientationType *    OrientationPointer;
        //fill lower level first:
        Base::fill_level(dom);

        topology::bndcell_filler<ElementTag, dim>::fill(elements_,
                                                           Base::vertices_,
                                                           dom);
      }

    public:

      boundary_ncell_layer( )
      {
          std::fill( elements_.begin(), elements_.end(), static_cast<element_type *>(NULL) );
      }

      boundary_ncell_layer( const boundary_ncell_layer & llh) : Base (llh), elements_(llh.elements) {}

      /////////////////// access container: ////////////////////

      using Base::container;

      //non-const:
      element_container_type *
      container(dimension_tag<dim>)
      {
        return &elements_;
      }

      //const:
      const element_container_type *
      container(dimension_tag<dim>) const
      {
        return &elements_;
      }

      void fill_vertices(VertexType ** vertices_, size_t num)
      {
            Base::fill_vertices(vertices_, num);
      }

    private:
      element_container_type elements_;//[LevelSpecs::num];
  };

  //
  // No storage of boundary elements:
  //
  /** @brief Implementation of the case that boundary k-cells are not stored at all */
  template <typename ConfigType, typename ElementTag, unsigned long dim, typename orienter_tag>
  class boundary_ncell_layer <ConfigType, ElementTag, dim, no_handling_tag, orienter_tag, false> :
    public boundary_ncell_layer < ConfigType, ElementTag, dim - 1 >
  {
    //requirements:
    //array of pointers to elements of class 'dim' and a integer representing the orientation within the cell relative to the element it points to.
    //typedef typename DomainTypes<ConfigType>::segment_type        SegmentType;
    typedef topology::bndcells<ElementTag, dim>                                LevelSpecs;
    typedef boundary_ncell_layer < ConfigType, ElementTag, dim - 1 >      Base;

    typedef element_t<ConfigType, typename LevelSpecs::tag>  LevelElementType;

    typedef typename result_of::ncell<ConfigType, 0>::type      VertexType;

    protected:
      template <typename DomainType>
      void fill_level(DomainType & dom)
      {
        //fill lower topological levels only:
        Base::fill_level(dom);
      }

      void fill_vertices(VertexType ** vertices_, size_t num)
      {
            Base::fill_vertices(vertices_, num);
      }

    public:

      boundary_ncell_layer( ) {};

      boundary_ncell_layer( const boundary_ncell_layer & llh) : Base (llh) {}

  };

  //at level 0, i.e. vertex level, recursion ends:
  /** @brief Specialization for the vertex level. Recursion ends here */
  template <typename ConfigType, typename ElementTag, typename handling_tag, typename orienter_tag>
  class boundary_ncell_layer <ConfigType, ElementTag, 0, handling_tag, orienter_tag, true>
  {
    //array of pointers to elements of class 'dim' and a integer representing the orientation within the cell relative to the element it points to.
    //typedef typename DomainTypes<ConfigType>::segment_type               SegmentType;
    typedef topology::bndcells<ElementTag, 0>                                      LevelSpecs;

    typedef element_t<ConfigType, typename LevelSpecs::tag>         VertexType;
    typedef typename result_of::point<ConfigType>::type              PointType;

    typedef typename result_of::iterator< element_t<ConfigType, ElementTag>, 0>::type         VertexIterator;

    typedef typename topology::bndcells<ElementTag, 0>::layout_tag layout_tag;
    static const long array_size = topology::bndcells<ElementTag, 0>::num;
    typedef typename result_of::ncell<ConfigType, 0>::type            element_type;

    typedef typename result_of::container<element_type *, layout_tag, array_size>::type      element_container_type;

    protected:
      //end recursion:
      template <typename DomainType>
      void fill_level(DomainType & dom) {}

    public:
      boundary_ncell_layer() {};

      boundary_ncell_layer( const boundary_ncell_layer & llh) : vertices_(llh.vertices_) {}

      ////////////////// container access: /////////////////////////

      //non-const:
      element_container_type *
      container(dimension_tag<0>)
      {
        return &vertices_;
      }

      //const:
      const element_container_type *
      container(dimension_tag<0>) const
      {
        return &vertices_;
      }

      void fill_vertices(VertexType ** vertices_in, size_t num)
      {
            assert( num <= LevelSpecs::num );
            vertices_.resize(num);
            std::copy( vertices_in, vertices_in + num, vertices_.begin() );
      }

    protected:
      element_container_type vertices_;
  };

}

#endif

<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2011, Willow Garage, 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 Willow Garage, Inc. 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.
 *
 * Author: Radu B. Rusu, Suat Gedikli
 *
 */
#include <pcl/io/pcd_grabber.h>
#include <pcl/console/parse.h>
#define BOOST_FILESYSTEM_VERSION 2
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/thread/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <pcl/console/print.h>
#include <pcl/visualization/cloud_viewer.h>

using pcl::console::print_error;
using pcl::console::print_info;
using pcl::console::print_value;

boost::mutex mutex_;

void
printHelp (int argc, char **argv)
{
  //print_error ("Syntax is: %s <file_name 1..N>.pcd <options>\n", argv[0]);
  print_error ("Syntax is: %s <options>\n", argv[0]);
  print_info ("  where options are:\n");
  print_info ("                     -file file_name          = PCD file to be read from\n");
  print_info ("                     -dir directory_path      = directory path to PCD file(s) to be read from\n");
  print_info ("                     -fps frequency           = frames per second\n");
  print_info ("                     -repeat                  = optional parameter that tells wheter the PCD file(s) should be \"grabbed\" in a endless loop.\n");
  print_info ("\n");
  print_info ("                     -cam (*)                 = use given camera settings as initial view\n");
  print_info (stderr, " (*) [Clipping Range / Focal Point / Position / ViewUp / Distance / Window Size / Window Pos] or use a <filename.cam> that contains the same information.\n");
}

// Create the PCLVisualizer object
boost::shared_ptr<pcl::visualization::PCLVisualizer> p;
std::vector<double> fcolor_r, fcolor_b, fcolor_g;
bool fcolorparam = false;

struct EventHelper
{
  void
  cloud_cb (const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr & cloud)
  {
    // Add the cloud to the renderer
    boost::mutex::scoped_lock lock (mutex_);
    if (!cloud)
      return;
    if (!p->updatePointCloud (cloud, "PCDCloud"))
    {
      p->addPointCloud (cloud, "PCDCloud");
      p->resetCameraViewpoint ("PCDCloud");
    }
  }
};

void
keyboard_callback (const pcl::visualization::KeyboardEvent& event, void* cookie)
{
  std::string* message = (std::string*)cookie;
  cout << (*message) << " :: ";
  if (event.getKeyCode())
    cout << "the key \'" << event.getKeyCode() << "\' (" << (int)event.getKeyCode() << ") was";
  else
    cout << "the special key \'" << event.getKeySym() << "\' was";
  if (event.keyDown())
    cout << " pressed" << endl;
  else
    cout << " released" << endl;
}

void mouse_callback (const pcl::visualization::MouseEvent& mouse_event, void* cookie)
{
  std::string* message = (std::string*) cookie;
  if (mouse_event.getType() == pcl::visualization::MouseEvent::MouseButtonPress && mouse_event.getButton() == pcl::visualization::MouseEvent::LeftButton)
  {
    cout << (*message) << " :: " << mouse_event.getX () << " , " << mouse_event.getY () << endl;
  }
}

/* ---[ */
int
main (int argc, char** argv)
{
  srand (time (0));

  if (argc > 1)
  {
    for (int i = 1; i < argc; i++)
    {
      if (std::string (argv[i]) == "-h")
      {
        printHelp (argc, argv);
        return (-1);
      }
    }
  }

  // Command line parsing
  double bcolor[3] = {0, 0, 0};
  pcl::console::parse_3x_arguments (argc, argv, "-bc", bcolor[0], bcolor[1], bcolor[2]);

  fcolorparam = pcl::console::parse_multiple_3x_arguments (argc, argv, "-fc", fcolor_r, fcolor_g, fcolor_b);

  int psize = 0;
  pcl::console::parse_argument (argc, argv, "-ps", psize);

  double opaque;
  pcl::console::parse_argument (argc, argv, "-opaque", opaque);

  p.reset (new pcl::visualization::PCLVisualizer (argc, argv, "PCD viewer"));

  //  // Change the cloud rendered point size
  //  if (psize > 0)
  //    p->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, psize, "OpenNICloud");
  //
  //  // Change the cloud rendered opacity
  //  if (opaque >= 0)
  //    p->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_OPACITY, opaque, "OpenNICloud");

  p->setBackgroundColor (bcolor[0], bcolor[1], bcolor[2]);

  // Read axes settings
  double axes = 0.0;
  pcl::console::parse_argument (argc, argv, "-ax", axes);
  if (axes != 0.0 && p)
  {
    double ax_x = 0.0, ax_y = 0.0, ax_z = 0.0;
    pcl::console::parse_3x_arguments (argc, argv, "-ax_pos", ax_x, ax_y, ax_z, false);
    // Draw XYZ axes if command-line enabled
    p->addCoordinateSystem (axes, ax_x, ax_y, ax_z);
  }

  pcl::Grabber* grabber = 0;

  float frames_per_second = 0; // 0 means only if triggered!
  pcl::console::parse (argc, argv, "-fps", frames_per_second);
  if (frames_per_second < 0)
    frames_per_second = 0.0;

  std::cout << pcl::console::find_argument (argc, argv, "-repeat") << " : repaet" << std::endl;
  bool repeat = (pcl::console::find_argument (argc, argv, "-repeat") != -1);

  std::cout << "fps: " << frames_per_second << " , repeat: " << repeat << std::endl;
  std::string path = "";
  pcl::console::parse_argument (argc, argv, "-file", path);
  std::cout << "path: " << path << std::endl;
  if (path != "" && boost::filesystem::exists (path))
  {
    grabber = new pcl::PCDGrabber<pcl::PointXYZRGB> (path, frames_per_second, repeat);
  }
  else
  {
    std::vector<std::string> pcd_files;
    pcl::console::parse_argument (argc, argv, "-dir", path);
    std::cout << "path: " << path << std::endl;
    if (path != "" && boost::filesystem::exists (path))
    {
      boost::filesystem::directory_iterator end_itr;
      for (boost::filesystem::directory_iterator itr (path); itr != end_itr; ++itr)
      {
        if (!is_directory (itr->status()) && boost::algorithm::to_upper_copy(boost::filesystem::extension (itr->leaf())) == ".PCD" )
        {
          pcd_files.push_back (itr->path ().string());
          std::cout << "added: " << itr->path ().string() << std::endl;
        }
      }
    }
    else
    {
      std::cout << "Neither a pcd file given using the \"-file\" option, nor given a directory containing pcd files using the \"-dir\" option." << std::endl;
    }
    grabber = new pcl::PCDGrabber<pcl::PointXYZRGB> (pcd_files, frames_per_second, repeat);
  }

  EventHelper h;
  boost::function<void(const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr&) > f = boost::bind (&EventHelper::cloud_cb, &h, _1);
  boost::signals2::connection c1 = grabber->registerCallback (f);

  std::string mouseMsg3D ("Mouse coordinates in PCL Visualizer");
  std::string keyMsg3D ("Key event for PCL Visualizer");

  p->registerMouseCallback (&mouse_callback, (void*)(&mouseMsg3D));
  p->registerKeyboardCallback(&keyboard_callback, (void*)(&keyMsg3D));

  grabber->start ();
  while (true)
  {
    boost::this_thread::sleep(boost::posix_time::microseconds(10000));
    {
      boost::mutex::scoped_lock lock (mutex_);
      p->spinOnce ();
      if (p->wasStopped ())
        break;
    }
  }

  grabber->stop ();
}
/* ]--- */
<commit_msg>attempting a fix for pcd_grabber_viewer on Alex's MacOS<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2011, Willow Garage, 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 Willow Garage, Inc. 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.
 *
 * Author: Radu B. Rusu, Suat Gedikli
 *
 */
#include <pcl/io/pcd_grabber.h>
#include <pcl/console/parse.h>
#define BOOST_FILESYSTEM_VERSION 2
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/thread/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <pcl/console/print.h>
#include <pcl/visualization/cloud_viewer.h>

using pcl::console::print_error;
using pcl::console::print_info;
using pcl::console::print_value;

boost::mutex mutex_;
pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr cloud_;

void
printHelp (int argc, char **argv)
{
  //print_error ("Syntax is: %s <file_name 1..N>.pcd <options>\n", argv[0]);
  print_error ("Syntax is: %s <options>\n", argv[0]);
  print_info ("  where options are:\n");
  print_info ("                     -file file_name          = PCD file to be read from\n");
  print_info ("                     -dir directory_path      = directory path to PCD file(s) to be read from\n");
  print_info ("                     -fps frequency           = frames per second\n");
  print_info ("                     -repeat                  = optional parameter that tells wheter the PCD file(s) should be \"grabbed\" in a endless loop.\n");
  print_info ("\n");
  print_info ("                     -cam (*)                 = use given camera settings as initial view\n");
  print_info (stderr, " (*) [Clipping Range / Focal Point / Position / ViewUp / Distance / Window Size / Window Pos] or use a <filename.cam> that contains the same information.\n");
}

// Create the PCLVisualizer object
boost::shared_ptr<pcl::visualization::PCLVisualizer> p;
std::vector<double> fcolor_r, fcolor_b, fcolor_g;
bool fcolorparam = false;

struct EventHelper
{
  void
  cloud_cb (const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr & cloud)
  {
    // Add the cloud to the renderer
    boost::mutex::scoped_lock lock (mutex_);

    cloud_ = cloud;
  }
};

void
keyboard_callback (const pcl::visualization::KeyboardEvent& event, void* cookie)
{
  std::string* message = (std::string*)cookie;
  cout << (*message) << " :: ";
  if (event.getKeyCode())
    cout << "the key \'" << event.getKeyCode() << "\' (" << (int)event.getKeyCode() << ") was";
  else
    cout << "the special key \'" << event.getKeySym() << "\' was";
  if (event.keyDown())
    cout << " pressed" << endl;
  else
    cout << " released" << endl;
}

void mouse_callback (const pcl::visualization::MouseEvent& mouse_event, void* cookie)
{
  std::string* message = (std::string*) cookie;
  if (mouse_event.getType() == pcl::visualization::MouseEvent::MouseButtonPress && mouse_event.getButton() == pcl::visualization::MouseEvent::LeftButton)
  {
    cout << (*message) << " :: " << mouse_event.getX () << " , " << mouse_event.getY () << endl;
  }
}

/* ---[ */
int
main (int argc, char** argv)
{
  srand (time (0));

  if (argc > 1)
  {
    for (int i = 1; i < argc; i++)
    {
      if (std::string (argv[i]) == "-h")
      {
        printHelp (argc, argv);
        return (-1);
      }
    }
  }

  // Command line parsing
  double bcolor[3] = {0, 0, 0};
  pcl::console::parse_3x_arguments (argc, argv, "-bc", bcolor[0], bcolor[1], bcolor[2]);

  fcolorparam = pcl::console::parse_multiple_3x_arguments (argc, argv, "-fc", fcolor_r, fcolor_g, fcolor_b);

  int psize = 0;
  pcl::console::parse_argument (argc, argv, "-ps", psize);

  double opaque;
  pcl::console::parse_argument (argc, argv, "-opaque", opaque);

  p.reset (new pcl::visualization::PCLVisualizer (argc, argv, "PCD viewer"));

  //  // Change the cloud rendered point size
  //  if (psize > 0)
  //    p->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, psize, "OpenNICloud");
  //
  //  // Change the cloud rendered opacity
  //  if (opaque >= 0)
  //    p->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_OPACITY, opaque, "OpenNICloud");

  p->setBackgroundColor (bcolor[0], bcolor[1], bcolor[2]);

  // Read axes settings
  double axes = 0.0;
  pcl::console::parse_argument (argc, argv, "-ax", axes);
  if (axes != 0.0 && p)
  {
    double ax_x = 0.0, ax_y = 0.0, ax_z = 0.0;
    pcl::console::parse_3x_arguments (argc, argv, "-ax_pos", ax_x, ax_y, ax_z, false);
    // Draw XYZ axes if command-line enabled
    p->addCoordinateSystem (axes, ax_x, ax_y, ax_z);
  }

  pcl::Grabber* grabber = 0;

  float frames_per_second = 0; // 0 means only if triggered!
  pcl::console::parse (argc, argv, "-fps", frames_per_second);
  if (frames_per_second < 0)
    frames_per_second = 0.0;

  std::cout << pcl::console::find_argument (argc, argv, "-repeat") << " : repaet" << std::endl;
  bool repeat = (pcl::console::find_argument (argc, argv, "-repeat") != -1);

  std::cout << "fps: " << frames_per_second << " , repeat: " << repeat << std::endl;
  std::string path = "";
  pcl::console::parse_argument (argc, argv, "-file", path);
  std::cout << "path: " << path << std::endl;
  if (path != "" && boost::filesystem::exists (path))
  {
    grabber = new pcl::PCDGrabber<pcl::PointXYZRGB> (path, frames_per_second, repeat);
  }
  else
  {
    std::vector<std::string> pcd_files;
    pcl::console::parse_argument (argc, argv, "-dir", path);
    std::cout << "path: " << path << std::endl;
    if (path != "" && boost::filesystem::exists (path))
    {
      boost::filesystem::directory_iterator end_itr;
      for (boost::filesystem::directory_iterator itr (path); itr != end_itr; ++itr)
      {
        if (!is_directory (itr->status()) && boost::algorithm::to_upper_copy(boost::filesystem::extension (itr->leaf())) == ".PCD" )
        {
          pcd_files.push_back (itr->path ().string());
          std::cout << "added: " << itr->path ().string() << std::endl;
        }
      }
    }
    else
    {
      std::cout << "Neither a pcd file given using the \"-file\" option, nor given a directory containing pcd files using the \"-dir\" option." << std::endl;
    }
    grabber = new pcl::PCDGrabber<pcl::PointXYZRGB> (pcd_files, frames_per_second, repeat);
  }

  EventHelper h;
  boost::function<void(const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr&) > f = boost::bind (&EventHelper::cloud_cb, &h, _1);
  boost::signals2::connection c1 = grabber->registerCallback (f);

  std::string mouseMsg3D ("Mouse coordinates in PCL Visualizer");
  std::string keyMsg3D ("Key event for PCL Visualizer");

  p->registerMouseCallback (&mouse_callback, (void*)(&mouseMsg3D));
  p->registerKeyboardCallback(&keyboard_callback, (void*)(&keyMsg3D));

  grabber->start ();
  while (true)
  {
    if (!cloud_)
    {
      boost::this_thread::sleep(boost::posix_time::microseconds(10000));
      continue;
    }

    boost::mutex::scoped_lock lock (mutex_);
    pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr temp_cloud;
    temp_cloud.swap (cloud_);

    if (!p->updatePointCloud (temp_cloud, "PCDCloud"))
    {
      p->addPointCloud (temp_cloud, "PCDCloud");
      p->resetCameraViewpoint ("PCDCloud");
    }
    p->spinOnce ();
    if (p->wasStopped ())
      break;
  }

  grabber->stop ();
}
/* ]--- */
<|endoftext|>