<commit_before>/*************************************************************************
 *
 *  $RCSfile: queryfilter.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: oj $ $Date: 2002-12-04 11:25:48 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an AS IS basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef DBAUI_QUERYFILTER_HXX
#define DBAUI_QUERYFILTER_HXX

#ifndef _DIALOG_HXX //autogen
#include <vcl/dialog.hxx>
#endif

#ifndef _LSTBOX_HXX //autogen
#include <vcl/lstbox.hxx>
#endif

#ifndef _EDIT_HXX //autogen
#include <vcl/edit.hxx>
#endif

#ifndef _FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif

#ifndef _BUTTON_HXX //autogen
#include <vcl/button.hxx>
#endif
#ifndef _CONNECTIVITY_PARSE_SQLITERATOR_HXX_
#include <connectivity/sqliterator.hxx>
#endif

#ifndef CONNECTIVITY_PREDICATEINPUT_HXX
#include <connectivity/predicateinput.hxx>
#endif
#ifndef SVX_QUERYDESIGNCONTEXT_HXX
#include "svx/ParseContext.hxx"
#endif

namespace rtl
{
    class OUString;
}
namespace com
{
    namespace sun
    {
        namespace star
        {
            namespace sdb
            {
                class XSQLQueryComposer;
            }
            namespace sdbc
            {
                class XConnection;
                class XDatabaseMetaData;
            }
            namespace container
            {
                class XNameAccess;
            }
            namespace beans
            {
                struct PropertyValue;
            }
        }
    }
}
//==================================================================
// DlgFilterCrit
//==================================================================
namespace dbaui
{
    class DlgFilterCrit :public ModalDialog
                        ,public ::svxform::OParseContextClient
    {
    private:
        ListBox         aLB_WHEREFIELD1;
        ListBox         aLB_WHERECOMP1;
        Edit            aET_WHEREVALUE1;
        ListBox         aLB_WHERECOND2;
        ListBox         aLB_WHEREFIELD2;
        ListBox         aLB_WHERECOMP2;
        Edit            aET_WHEREVALUE2;
        ListBox         aLB_WHERECOND3;
        ListBox         aLB_WHEREFIELD3;
        ListBox         aLB_WHERECOMP3;
        Edit            aET_WHEREVALUE3;
        FixedText       aFT_WHEREFIELD;
        FixedText       aFT_WHERECOMP;
        FixedText       aFT_WHEREVALUE;
        FixedText       aFT_WHEREOPER;
        FixedLine       aFL_FIELDS;
        OKButton        aBT_OK;
        CancelButton    aBT_CANCEL;
        HelpButton      aBT_HELP;
        String          aSTR_NOENTRY;
        String          aSTR_COMPARE_OPERATORS;

        ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSQLQueryComposer>     m_xQueryComposer;
        ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess>     m_xColumns;
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection>          m_xConnection;
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData>    m_xMetaData;

        ::dbtools::OPredicateInputController    m_aPredicateInput;

        void            SelectField( ListBox& rBox, const String& rField );
        DECL_LINK( ListSelectHdl, ListBox * );
        DECL_LINK( ListSelectCompHdl, ListBox * );
        void            SetLine( USHORT nIdx,const ::com::sun::star::beans::PropertyValue& _rItem,sal_Bool _bOr );
        void            EnableLines();
        ::connectivity::OSQLPredicateType GetOSQLPredicateType(USHORT nPos,USHORT nCount) const;
        USHORT          GetSelectionPos(::connectivity::OSQLPredicateType eType,const ListBox& rListBox) const;
        ::rtl::OUString getCondition(const ListBox& _rField,const ListBox& _rComp,const Edit& _rValue) const;
        void            addQuoting(const ::rtl::OUString& _rColumnName,String& _rCondition)  const;

        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > getMatchingColumn( const Edit& _rValueInput ) const;
        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > getColumn( const ::rtl::OUString& _rFieldName ) const;

    public:
        DlgFilterCrit(  Window * pParent,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection>& _rxConnection,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSQLQueryComposer>& _rxQueryComposer,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess>& _rxCols,
                        const String& rFieldName = String()
                    );
        ~DlgFilterCrit();

        String          BuildWherePart();

        void            GetFilterList( ) const;

    protected:
        DECL_LINK( PredicateLoseFocus, Edit* );
    };

}

#endif // DBAUI_QUERYFILTER_HXX

<commit_msg>INTEGRATION: CWS oj08 (1.7.186); FILE MERGED 2004/01/29 09:20:46 oj 1.7.186.1: #i19884# change filteroperator<commit_after>/*************************************************************************
 *
 *  $RCSfile: queryfilter.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: obo $ $Date: 2004-03-15 12:43:29 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an AS IS basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef DBAUI_QUERYFILTER_HXX
#define DBAUI_QUERYFILTER_HXX

#ifndef _DIALOG_HXX //autogen
#include <vcl/dialog.hxx>
#endif

#ifndef _LSTBOX_HXX //autogen
#include <vcl/lstbox.hxx>
#endif

#ifndef _EDIT_HXX //autogen
#include <vcl/edit.hxx>
#endif

#ifndef _FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif

#ifndef _BUTTON_HXX //autogen
#include <vcl/button.hxx>
#endif
#ifndef _CONNECTIVITY_PARSE_SQLITERATOR_HXX_
#include <connectivity/sqliterator.hxx>
#endif

#ifndef CONNECTIVITY_PREDICATEINPUT_HXX
#include <connectivity/predicateinput.hxx>
#endif
#ifndef SVX_QUERYDESIGNCONTEXT_HXX
#include "svx/ParseContext.hxx"
#endif

namespace rtl
{
    class OUString;
}
namespace com
{
    namespace sun
    {
        namespace star
        {
            namespace sdb
            {
                class XSQLQueryComposer;
            }
            namespace sdbc
            {
                class XConnection;
                class XDatabaseMetaData;
            }
            namespace container
            {
                class XNameAccess;
            }
            namespace beans
            {
                struct PropertyValue;
            }
        }
    }
}
//==================================================================
// DlgFilterCrit
//==================================================================
namespace dbaui
{
    class DlgFilterCrit :public ModalDialog
                        ,public ::svxform::OParseContextClient
    {
    private:
        ListBox         aLB_WHEREFIELD1;
        ListBox         aLB_WHERECOMP1;
        Edit            aET_WHEREVALUE1;
        ListBox         aLB_WHERECOND2;
        ListBox         aLB_WHEREFIELD2;
        ListBox         aLB_WHERECOMP2;
        Edit            aET_WHEREVALUE2;
        ListBox         aLB_WHERECOND3;
        ListBox         aLB_WHEREFIELD3;
        ListBox         aLB_WHERECOMP3;
        Edit            aET_WHEREVALUE3;
        FixedText       aFT_WHEREFIELD;
        FixedText       aFT_WHERECOMP;
        FixedText       aFT_WHEREVALUE;
        FixedText       aFT_WHEREOPER;
        FixedLine       aFL_FIELDS;
        OKButton        aBT_OK;
        CancelButton    aBT_CANCEL;
        HelpButton      aBT_HELP;
        String          aSTR_NOENTRY;
        String          aSTR_COMPARE_OPERATORS;

        ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSQLQueryComposer>     m_xQueryComposer;
        ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess>     m_xColumns;
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection>          m_xConnection;
        ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData>    m_xMetaData;

        ::dbtools::OPredicateInputController    m_aPredicateInput;

        void            SelectField( ListBox& rBox, const String& rField );
        DECL_LINK( ListSelectHdl, ListBox * );
        DECL_LINK( ListSelectCompHdl, ListBox * );
        void            SetLine( USHORT nIdx,const ::com::sun::star::beans::PropertyValue& _rItem,sal_Bool _bOr );
        void            EnableLines();
        sal_Int32       GetOSQLPredicateType(USHORT nPos,USHORT nCount) const;
        USHORT          GetSelectionPos(sal_Int32 eType,const ListBox& rListBox) const;
        void            getCondition(const ListBox& _rField,const ListBox& _rComp,const Edit& _rValue,::com::sun::star::beans::PropertyValue& _rFilter) const;
        void            addQuoting(const ::rtl::OUString& _rColumnName,String& _rCondition)  const;

        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > getMatchingColumn( const Edit& _rValueInput ) const;
        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > getColumn( const ::rtl::OUString& _rFieldName ) const;
        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > getQueryColumn( const ::rtl::OUString& _rFieldName ) const;

    public:
        DlgFilterCrit(  Window * pParent,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection>& _rxConnection,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSQLQueryComposer>& _rxQueryComposer,
                        const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess>& _rxCols,
                        const String& rFieldName = String()
                    );
        ~DlgFilterCrit();

        String          BuildWherePart();

        void            GetFilterList( ) const;

    protected:
        DECL_LINK( PredicateLoseFocus, Edit* );
    };

}

#endif // DBAUI_QUERYFILTER_HXX

<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
// FILE: point.hpp
// DATE: 2014-07-30
// AUTH: Trevor Wilson <kmdreko@gmail.com>
// DESC: Defines a multi-dimensional point class

////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2019 Trevor Wilson
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
//   The above copyright notice and this permission notice shall be included in
//   all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#ifndef WILT_POINT_HPP
#define WILT_POINT_HPP

#include <array>
#include <cstddef>
#include <initializer_list>
#include <stdexcept>
#include <utility>

namespace wilt
{
  // type aliases
  using pos_t = std::ptrdiff_t;

  //! @class  Point
  //! @brief  An integer point class with arithmetic operations
  template <std::size_t N>
  class Point
  {
  public:

    //! @brief  Default constructor. Sets all values to 0
    Point()
    {
      data_.fill(0);
    }

    template <class... Args, typename std::enable_if<sizeof...(Args) == N, int>::type* = nullptr>
    Point(Args... args)
      : data_{ args... }
    {

    }

    //! @brief      Copy constructor
    //! @param[in]  pt - Point to copy from
    Point(const Point<N>& pt)
      : data_(pt.data_)
    {

    }

    //! @brief      Assignment operator
    //! @param[in]  pt - the point to copy from
    //! @return     reference to this point
    Point<N>& operator = (const Point<N>& pt)
    {
      data_ = pt.data_;
      return *this;
    }

    //! @brief      In-place addition operator
    //! @param[in]  pt - the point to add
    //! @return     reference to this point
    Point<N>& operator+= (const Point<N>& pt)
    {
      for (std::size_t i = 0; i < N; ++i)
        data_[i] += pt.data_[i];
      return *this;
    }

    //! @brief      In-place subtraction operator
    //! @param[in]  pt - the point to subtract
    //! @return     reference to this point
    Point<N>& operator-= (const Point<N>& pt)
    {
      for (std::size_t i = 0; i < N; ++i)
        data_[i] -= pt.data_[i];
      return *this;
    }

    //! @brief      In-place addition operator
    //! @param[in]  val - the value to add
    //! @return     reference to this point
    Point<N>& operator+= (pos_t val)
    {
      for (std::size_t i = 0; i < N; ++i)
        data_[i] += val;
      return *this;
    }

    //! @brief      In-place subtraction operator
    //! @param[in]  val - the value to subtract
    //! @return     reference to this point
    Point<N>& operator-= (pos_t val)
    {
      for (std::size_t i = 0; i < N; ++i)
        data_[i] -= val;
      return *this;
    }

    //! @brief      In-place multiplication operator
    //! @param[in]  val - the value to multiply
    //! @return     reference to this point
    Point<N>& operator*= (pos_t val)
    {
      for (std::size_t i = 0; i < N; ++i)
        data_[i] *= val;
      return *this;
    }

    //! @brief      In-place division operator
    //! @param[in]  val - the value to divide
    //! @return     reference to this point
    Point<N>& operator/= (pos_t val)
    {
      for (std::size_t i = 0; i < N; ++i)
        data_[i] /= val;
      return *this;
    }

    //! @brief      Indexing operator
    //! @param[in]  n - index
    //! @return     reference to value at the index
    pos_t& operator[] (std::size_t n)
    {
      return data_[n];
    }

    //! @brief      Indexing operator
    //! @param[in]  n - index
    //! @return     reference to value at the index
    const pos_t& operator[] (std::size_t n) const
    {
      return data_[n];
    }

    pos_t* data()
    {
      return data_.data();
    }

    const pos_t* data() const
    {
      return data_.data();
    }

    void clear()
    {
      data_.fill(0);
    }

    void fill(pos_t val)
    {
      data_.fill(val);
    }

    //! @brief      Slices a point by removing an index
    //! @param[in]  n - index to remove
    //! @return     copy with the index removed
    //!
    //! Is used to simplify NArray::slice() calls
    //! Will fail if N==0
    Point<N-1> removed(std::size_t n) const
    {
      Point<N-1> ret;
      for (std::size_t i = 0, j = 0; i < N; ++i)
        if (i != n)
          ret[j++] = data_[i];
      return ret;
    }

    //! @brief      Adds an element to a point at an index
    //! @param[in]  n - index to add at
    //! @param[in]  v - value to add
    //! @return     copy with the value added
    Point<N+1> inserted(std::size_t n, pos_t v) const
    {
      Point<N+1> ret;
      for (std::size_t i = 0; i < n; ++i)
        ret[i] = data_[i];
      ret[n] = v;
      for (std::size_t i = n + 1; i < N + 1; ++i)
        ret[i] = data_[i - 1];
      return ret;
    }

    //! @brief      Creates a point with two index values swapped
    //! @param[in]  a - first index to swap
    //! @param[in]  b - second index to swap
    //! @return     point with the indices swapped
    //!
    //! Is used to simplify NArray::transpose() calls
    //! Will fail if N==0
    Point<N> swapped(std::size_t a, std::size_t b) const
    {
      Point<N> ret = *this;
      std::swap(ret.data_[a], ret.data_[b]);
      return ret;
    }

    // gets the first M values
    template <std::size_t M>
    Point<M> high() const
    {
      Point<M> ret;
      for (std::size_t i = 0; i < M; ++i)
        ret[i] = data_[i];
      return ret;
    }

    // gets the last M values
    template <std::size_t M>
    Point<M> low() const
    {
      Point<M> ret;
      for (std::size_t i = 0; i < M; ++i)
        ret[i] = data_[N - M + i];
      return ret;
    }

  private:
    //! @brief  internal storage array
    std::array<pos_t, N> data_;

  }; // class Point

  //! @brief      Compares the two points
  //! @param[in]  lhs - point to compare
  //! @param[in]  rhs - point to compare
  //! @return     true if points are equal, false if elements are not equal
  template <std::size_t N>
  bool operator== (const wilt::Point<N>& lhs, const wilt::Point<N>& rhs)
  {
    for (std::size_t i = 0; i < N; ++i)
      if (!(lhs[i] == rhs[i]))
        return false;

    return true;
  }

  //! @brief      Compares the two points
  //! @param[in]  lhs - point to compare
  //! @param[in]  rhs - point to compare
  //! @return     false if points are equal, true if elements are not equal
  template <std::size_t N>
  bool operator!= (const wilt::Point<N>& lhs, const wilt::Point<N>& rhs)
  {
    for (std::size_t i = 0; i < N; ++i)
      if (!(lhs[i] == rhs[i]))
        return true;

    return false;
  }

  //! @brief      Adds two points
  //! @param[in]  lhs - point to add
  //! @param[in]  rhs - point to add
  //! @return     result from addition of the two points
  template <std::size_t N>
  wilt::Point<N> operator+ (const wilt::Point<N>& lhs, const wilt::Point<N>& rhs)
  {
    wilt::Point<N> ret;
    for (std::size_t i = 0; i < N; ++i)
      ret[i] = lhs[i] + rhs[i];
    return ret;
  }

  //! @brief      Subtracts two points
  //! @param[in]  lhs - point to subtract
  //! @param[in]  rhs - point to subtract
  //! @return     result from subtraction of the two points
  template <std::size_t N>
  wilt::Point<N> operator- (const wilt::Point<N>& lhs, const wilt::Point<N>& rhs)
  {
    wilt::Point<N> ret;
    for (std::size_t i = 0; i < N; ++i)
      ret[i] = lhs[i] - rhs[i];
    return ret;
  }

  //! @brief      Adds a point and a scalar
  //! @param[in]  lhs - point to add
  //! @param[in]  rhs - scalar to add
  //! @return     result from addition of the point and scalar
  template <std::size_t N>
  wilt::Point<N> operator+ (const wilt::Point<N>& lhs, pos_t rhs)
  {
    wilt::Point<N> ret;
    for (std::size_t i = 0; i < N; ++i)
      ret[i] = lhs[i] + rhs;
    return ret;
  }

  //! @brief      Subtracts a point and a scalar
  //! @param[in]  lhs - point to subtract
  //! @param[in]  rhs - scalar to subtract
  //! @return     result from subtraction of the point and scalar
  template <std::size_t N>
  wilt::Point<N> operator- (const wilt::Point<N>& lhs, pos_t rhs)
  {
    wilt::Point<N> ret;
    for (std::size_t i = 0; i < N; ++i)
      ret[i] = lhs[i] - rhs;
    return ret;
  }

  //! @brief      Multiplies a point and a scalar
  //! @param[in]  lhs - point to multiply
  //! @param[in]  rhs - scalar to multiply
  //! @return     result from multipliction of the point and scalar
  template <std::size_t N>
  wilt::Point<N> operator* (const wilt::Point<N>& lhs, pos_t rhs)
  {
    wilt::Point<N> ret;
    for (std::size_t i = 0; i < N; ++i)
      ret[i] = lhs[i] * rhs;
    return ret;
  }

  //! @brief      Divides a point and a scalar
  //! @param[in]  lhs - point to divide
  //! @param[in]  rhs - scalar to divide
  //! @return     result from division of the point and scalar
  template <std::size_t N>
  wilt::Point<N> operator/ (const wilt::Point<N>& lhs, pos_t rhs)
  {
    wilt::Point<N> ret;
    for (std::size_t i = 0; i < N; ++i)
      ret[i] = lhs[i] / rhs;
    return ret;
  }

  //! @brief      Adds a point and a scalar
  //! @param[in]  lhs - scalar to add
  //! @param[in]  rhs - point to add
  //! @return     result from addition of the point and scalar
  template <std::size_t N>
  wilt::Point<N> operator+ (pos_t lhs, const wilt::Point<N>& rhs)
  {
    wilt::Point<N> ret;
    for (std::size_t i = 0; i < N; ++i)
      ret[i] = lhs + rhs[i];
    return ret;
  }

  //! @brief      Subtracts a point and a scalar
  //! @param[in]  lhs - scalar to subtract
  //! @param[in]  rhs - point to subtract
  //! @return     result from subtraction of the point and scalar
  template <std::size_t N>
  wilt::Point<N> operator- (pos_t lhs, const wilt::Point<N>& rhs)
  {
    wilt::Point<N> ret;
    for (std::size_t i = 0; i < N; ++i)
      ret[i] = lhs - rhs[i];
    return ret;
  }

  //! @brief      Multiplies a point and a scalar
  //! @param[in]  lhs - scalar to multiply
  //! @param[in]  rhs - point to multiply
  //! @return     result from multipliction of the point and scalar
  template <std::size_t N>
  wilt::Point<N> operator* (pos_t lhs, const wilt::Point<N>& rhs)
  {
    wilt::Point<N> ret;
    for (std::size_t i = 0; i < N; ++i)
      ret[i] = lhs * rhs[i];
    return ret;
  }

  //! @brief      Divides a point and a scalar
  //! @param[in]  lhs - scalar to divide
  //! @param[in]  rhs - point to divide
  //! @return     result from division of the point and scalar
  template <std::size_t N>
  wilt::Point<N> operator/ (pos_t lhs, const wilt::Point<N>& rhs)
  {
    wilt::Point<N> ret;
    for (std::size_t i = 0; i < N; ++i)
      ret[i] = lhs / rhs[i];
    return ret;
  }

} // namespace wilt

#endif // !WILT_POINT_HPP
<commit_msg>make Point all constexpr<commit_after>////////////////////////////////////////////////////////////////////////////////
// FILE: point.hpp
// DATE: 2014-07-30
// AUTH: Trevor Wilson <kmdreko@gmail.com>
// DESC: Defines a multi-dimensional point class

////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2019 Trevor Wilson
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
//   The above copyright notice and this permission notice shall be included in
//   all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#ifndef WILT_POINT_HPP
#define WILT_POINT_HPP

#include <array>
#include <cstddef>
#include <initializer_list>
#include <stdexcept>
#include <utility>

namespace wilt
{
  // type aliases
  using pos_t = std::ptrdiff_t;

  //! @class  Point
  //! @brief  An integer point class with arithmetic operations
  template <std::size_t N>
  class Point
  {
  public:

    //! @brief  Default constructor. Sets all values to 0
    constexpr Point()
      : data_{ }
    {
      for (std::size_t i = 0; i < N; ++i)
        data_[i] = 0;
    }

    template <class... Args, typename std::enable_if<sizeof...(Args) == N, int>::type* = nullptr>
    constexpr Point(Args... args)
      : data_{ args... }
    {

    }

    //! @brief      Copy constructor
    //! @param[in]  pt - Point to copy from
    constexpr Point(const Point<N>& pt)
      : data_{ pt.data_ }
    {

    }

    //! @brief      Assignment operator
    //! @param[in]  pt - the point to copy from
    //! @return     reference to this point
    constexpr Point<N>& operator = (const Point<N>& pt)
    {
      data_ = pt.data_;
      return *this;
    }

    //! @brief      In-place addition operator
    //! @param[in]  pt - the point to add
    //! @return     reference to this point
    constexpr Point<N>& operator+= (const Point<N>& pt)
    {
      for (std::size_t i = 0; i < N; ++i)
        data_[i] += pt.data_[i];
      return *this;
    }

    //! @brief      In-place subtraction operator
    //! @param[in]  pt - the point to subtract
    //! @return     reference to this point
    constexpr Point<N>& operator-= (const Point<N>& pt)
    {
      for (std::size_t i = 0; i < N; ++i)
        data_[i] -= pt.data_[i];
      return *this;
    }

    //! @brief      In-place addition operator
    //! @param[in]  val - the value to add
    //! @return     reference to this point
    constexpr Point<N>& operator+= (pos_t val)
    {
      for (std::size_t i = 0; i < N; ++i)
        data_[i] += val;
      return *this;
    }

    //! @brief      In-place subtraction operator
    //! @param[in]  val - the value to subtract
    //! @return     reference to this point
    constexpr Point<N>& operator-= (pos_t val)
    {
      for (std::size_t i = 0; i < N; ++i)
        data_[i] -= val;
      return *this;
    }

    //! @brief      In-place multiplication operator
    //! @param[in]  val - the value to multiply
    //! @return     reference to this point
    constexpr Point<N>& operator*= (pos_t val)
    {
      for (std::size_t i = 0; i < N; ++i)
        data_[i] *= val;
      return *this;
    }

    //! @brief      In-place division operator
    //! @param[in]  val - the value to divide
    //! @return     reference to this point
    constexpr Point<N>& operator/= (pos_t val)
    {
      for (std::size_t i = 0; i < N; ++i)
        data_[i] /= val;
      return *this;
    }

    //! @brief      Indexing operator
    //! @param[in]  n - index
    //! @return     reference to value at the index
    constexpr pos_t& operator[] (std::size_t n)
    {
      return data_[n];
    }

    //! @brief      Indexing operator
    //! @param[in]  n - index
    //! @return     reference to value at the index
    constexpr const pos_t& operator[] (std::size_t n) const
    {
      return data_[n];
    }

    constexpr pos_t* data()
    {
      return data_.data();
    }

    constexpr const pos_t* data() const
    {
      return data_.data();
    }

    constexpr void clear()
    {
      for (std::size_t i = 0; i < N; ++i)
        data_[i] = 0;
    }

    constexpr void fill(pos_t val)
    {
      for (std::size_t i = 0; i < N; ++i)
        data_[i] = val;
    }

    //! @brief      Slices a point by removing an index
    //! @param[in]  n - index to remove
    //! @return     copy with the index removed
    //!
    //! Is used to simplify NArray::slice() calls
    //! Will fail if N==0
    constexpr Point<N-1> removed(std::size_t n) const
    {
      Point<N-1> ret;
      for (std::size_t i = 0, j = 0; i < N; ++i)
        if (i != n)
          ret[j++] = data_[i];
      return ret;
    }

    //! @brief      Adds an element to a point at an index
    //! @param[in]  n - index to add at
    //! @param[in]  v - value to add
    //! @return     copy with the value added
    constexpr Point<N+1> inserted(std::size_t n, pos_t v) const
    {
      Point<N+1> ret;
      for (std::size_t i = 0; i < n; ++i)
        ret[i] = data_[i];
      ret[n] = v;
      for (std::size_t i = n + 1; i < N + 1; ++i)
        ret[i] = data_[i - 1];
      return ret;
    }

    //! @brief      Creates a point with two index values swapped
    //! @param[in]  a - first index to swap
    //! @param[in]  b - second index to swap
    //! @return     point with the indices swapped
    //!
    //! Is used to simplify NArray::transpose() calls
    //! Will fail if N==0
    constexpr Point<N> swapped(std::size_t a, std::size_t b) const
    {
      Point<N> ret = *this;
      std::swap(ret.data_[a], ret.data_[b]);
      return ret;
    }

    // gets the first M values
    template <std::size_t M>
    constexpr Point<M> high() const
    {
      Point<M> ret;
      for (std::size_t i = 0; i < M; ++i)
        ret[i] = data_[i];
      return ret;
    }

    // gets the last M values
    template <std::size_t M>
    constexpr Point<M> low() const
    {
      Point<M> ret;
      for (std::size_t i = 0; i < M; ++i)
        ret[i] = data_[N - M + i];
      return ret;
    }

  private:
    //! @brief  internal storage array
    std::array<pos_t, N> data_;

  }; // class Point

  //! @brief      Compares the two points
  //! @param[in]  lhs - point to compare
  //! @param[in]  rhs - point to compare
  //! @return     true if points are equal, false if elements are not equal
  template <std::size_t N>
  constexpr bool operator== (const wilt::Point<N>& lhs, const wilt::Point<N>& rhs)
  {
    for (std::size_t i = 0; i < N; ++i)
      if (!(lhs[i] == rhs[i]))
        return false;

    return true;
  }

  //! @brief      Compares the two points
  //! @param[in]  lhs - point to compare
  //! @param[in]  rhs - point to compare
  //! @return     false if points are equal, true if elements are not equal
  template <std::size_t N>
  constexpr bool operator!= (const wilt::Point<N>& lhs, const wilt::Point<N>& rhs)
  {
    for (std::size_t i = 0; i < N; ++i)
      if (!(lhs[i] == rhs[i]))
        return true;

    return false;
  }

  //! @brief      Adds two points
  //! @param[in]  lhs - point to add
  //! @param[in]  rhs - point to add
  //! @return     result from addition of the two points
  template <std::size_t N>
  constexpr wilt::Point<N> operator+ (const wilt::Point<N>& lhs, const wilt::Point<N>& rhs)
  {
    wilt::Point<N> ret;
    for (std::size_t i = 0; i < N; ++i)
      ret[i] = lhs[i] + rhs[i];
    return ret;
  }

  //! @brief      Subtracts two points
  //! @param[in]  lhs - point to subtract
  //! @param[in]  rhs - point to subtract
  //! @return     result from subtraction of the two points
  template <std::size_t N>
  constexpr wilt::Point<N> operator- (const wilt::Point<N>& lhs, const wilt::Point<N>& rhs)
  {
    wilt::Point<N> ret;
    for (std::size_t i = 0; i < N; ++i)
      ret[i] = lhs[i] - rhs[i];
    return ret;
  }

  //! @brief      Adds a point and a scalar
  //! @param[in]  lhs - point to add
  //! @param[in]  rhs - scalar to add
  //! @return     result from addition of the point and scalar
  template <std::size_t N>
  constexpr wilt::Point<N> operator+ (const wilt::Point<N>& lhs, pos_t rhs)
  {
    wilt::Point<N> ret;
    for (std::size_t i = 0; i < N; ++i)
      ret[i] = lhs[i] + rhs;
    return ret;
  }

  //! @brief      Subtracts a point and a scalar
  //! @param[in]  lhs - point to subtract
  //! @param[in]  rhs - scalar to subtract
  //! @return     result from subtraction of the point and scalar
  template <std::size_t N>
  constexpr wilt::Point<N> operator- (const wilt::Point<N>& lhs, pos_t rhs)
  {
    wilt::Point<N> ret;
    for (std::size_t i = 0; i < N; ++i)
      ret[i] = lhs[i] - rhs;
    return ret;
  }

  //! @brief      Multiplies a point and a scalar
  //! @param[in]  lhs - point to multiply
  //! @param[in]  rhs - scalar to multiply
  //! @return     result from multipliction of the point and scalar
  template <std::size_t N>
  constexpr wilt::Point<N> operator* (const wilt::Point<N>& lhs, pos_t rhs)
  {
    wilt::Point<N> ret;
    for (std::size_t i = 0; i < N; ++i)
      ret[i] = lhs[i] * rhs;
    return ret;
  }

  //! @brief      Divides a point and a scalar
  //! @param[in]  lhs - point to divide
  //! @param[in]  rhs - scalar to divide
  //! @return     result from division of the point and scalar
  template <std::size_t N>
  constexpr wilt::Point<N> operator/ (const wilt::Point<N>& lhs, pos_t rhs)
  {
    wilt::Point<N> ret;
    for (std::size_t i = 0; i < N; ++i)
      ret[i] = lhs[i] / rhs;
    return ret;
  }

  //! @brief      Adds a point and a scalar
  //! @param[in]  lhs - scalar to add
  //! @param[in]  rhs - point to add
  //! @return     result from addition of the point and scalar
  template <std::size_t N>
  constexpr wilt::Point<N> operator+ (pos_t lhs, const wilt::Point<N>& rhs)
  {
    wilt::Point<N> ret;
    for (std::size_t i = 0; i < N; ++i)
      ret[i] = lhs + rhs[i];
    return ret;
  }

  //! @brief      Subtracts a point and a scalar
  //! @param[in]  lhs - scalar to subtract
  //! @param[in]  rhs - point to subtract
  //! @return     result from subtraction of the point and scalar
  template <std::size_t N>
  constexpr wilt::Point<N> operator- (pos_t lhs, const wilt::Point<N>& rhs)
  {
    wilt::Point<N> ret;
    for (std::size_t i = 0; i < N; ++i)
      ret[i] = lhs - rhs[i];
    return ret;
  }

  //! @brief      Multiplies a point and a scalar
  //! @param[in]  lhs - scalar to multiply
  //! @param[in]  rhs - point to multiply
  //! @return     result from multipliction of the point and scalar
  template <std::size_t N>
  constexpr wilt::Point<N> operator* (pos_t lhs, const wilt::Point<N>& rhs)
  {
    wilt::Point<N> ret;
    for (std::size_t i = 0; i < N; ++i)
      ret[i] = lhs * rhs[i];
    return ret;
  }

  //! @brief      Divides a point and a scalar
  //! @param[in]  lhs - scalar to divide
  //! @param[in]  rhs - point to divide
  //! @return     result from division of the point and scalar
  template <std::size_t N>
  constexpr wilt::Point<N> operator/ (pos_t lhs, const wilt::Point<N>& rhs)
  {
    wilt::Point<N> ret;
    for (std::size_t i = 0; i < N; ++i)
      ret[i] = lhs / rhs[i];
    return ret;
  }

} // namespace wilt

#endif // !WILT_POINT_HPP
<|endoftext|>


<commit_before>#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#define ll long long
using namespace std;
const int maxn = 500010, inf = 1000000000;
struct poi {
    int too, pre, sum;
} e[maxn];
struct tjm {
    int sum, tag;
} a[maxn];
struct zs {
    int x, y, len;
} edge[maxn];
int n, m, x, y, z, flag, tot, tot2, cnt;
int last[maxn], size[maxn], fa[maxn], dep[maxn], son[maxn], w[maxn], top[maxn];
void read(int &k) {
    int f = 1;
    k = 0;
    char c = getchar();
    while (c < '0' || c > '9') c == '-' && (f = -1), c = getchar();
    while (c <= '9' && c >= '0') k = k * 10 + c - '0', c = getchar();
    k *= f;
}
void add(int x, int y, int z) {
    e[++tot].too = y;
    e[tot].sum = z;
    e[tot].pre = last[x];
    last[x] = tot;
}
void dfs1(int x) {
    size[x] = 1;
    for (int i = last[x]; i; i = e[i].pre) {
        int too = e[i].too;
        if (too != fa[x]) {
            fa[too] = x;
            dep[too] = dep[x] + e[i].sum;
            dfs1(too);
            if (size[too] > size[son[x]]) son[x] = too;
            size[x] += size[too];
        }
    }
}
void dfs2(int x, int tp) {
    w[x] = ++cnt;
    top[x] = tp;
    if (son[x]) dfs2(son[x], tp);
    for (int i = last[x]; i; i = e[i].pre)
        if (e[i].too != son[x] && e[i].too != fa[x]) dfs2(e[i].too, e[i].too);
}
void pushdown(int x) {
    if (a[x].tag == inf) return;
    int tag = a[x].tag;
    a[x].tag = inf;
    a[x << 1].tag = min(tag, a[x << 1].tag);
    a[x << 1 | 1].tag = min(tag, a[x << 1 | 1].tag);
}
void update(int x, int nl, int nr, int l, int r, int delta) {
    /// if(nl!=nr)pushdown(x);
    if (l <= nl && nr <= r)
        a[x].tag = min(a[x].tag, delta);
    else {
        // printf("%d %d\n",nl,nr);
        int mid = (nl + nr) >> 1;
        if (l <= mid) update(x << 1, nl, mid, l, r, delta);
        if (r > mid) update(x << 1 | 1, mid + 1, nr, l, r, delta);
    }
}
ll query(int x, int nl, int nr, int num) {
    if (nl != nr) pushdown(x);
    if (nl == num && nr == num)
        return a[x].tag;
    else {
        int mid = (nl + nr) >> 1;
        if (nl <= num && num <= mid) return query(x << 1, nl, mid, num);
        if (mid < num && num <= nr) return query(x << 1 | 1, mid + 1, nr, num);
    }
}
void work(int x, int y, int len) {
    std::cerr << x << ' ' << y << ' ' << len << std::endl;
    int f1 = top[x], f2 = top[y];
    while (f1 != f2) {
        if (dep[f1] < dep[f2]) swap(x, y), swap(f1, f2);
        std::cerr << w[f1] << ' ' << w[x] << std::endl;
        update(1, 1, cnt, w[f1], w[x], len);
        x = fa[f1];
        f1 = top[x];
    }
    if (x == y) return;
    if (dep[x] < dep[y]) swap(x, y);
    update(1, 1, cnt, w[son[y]], w[x], len);
}
void build(int x, int l, int r) {
    a[x].tag = inf;
    int mid = (l + r) >> 1;
    if (l != r) build(x << 1, l, mid), build(x << 1 | 1, mid + 1, r);
}
int main() {
    read(n);
    read(m);
    for (int i = 1; i <= m; i++) {
        read(x);
        read(y);
        read(z);
        read(flag);
        if (!flag)
            edge[++tot2].x = x, edge[tot2].y = y, edge[tot2].len = z;
        else
            add(x, y, z), add(y, x, z);
    }
    dfs1(1);
    dfs2(1, 1);
    build(1, 1, n);
    for (int i = 1; i <= tot2; i++)
        work(edge[i].x, edge[i].y,
             edge[i].len + dep[edge[i].x] + dep[edge[i].y]);
    for (int i = 2; i <= n; i++) {
        int ans = query(1, 1, cnt, w[i]);
        if (ans != inf)
            printf("%d ", ans - dep[i]);
        else
            printf("-1 ");
    }
    return 0;
}<commit_msg>Delete std.cpp<commit_after><|endoftext|>


<commit_before>#include "server.h"

#include <boost/asio/spawn.hpp>

#include <memory>
#include <csignal>

using namespace std;
namespace asio = boost::asio;
namespace sys = boost::system;
namespace py = boost::python;

namespace wsgi_boost
{
	HttpServer::HttpServer(std::string ip_address, unsigned short port, unsigned int num_threads) :
		m_ip_address{ ip_address }, m_port{ port }, m_num_threads{ num_threads }, m_acceptor(m_io_service), m_signals{ m_io_service }
	{
		m_is_running.store(false);
		m_signals.add(SIGINT);
		m_signals.add(SIGTERM);
#if defined(SIGQUIT)
		m_signals.add(SIGQUIT);
#endif // defined(SIGQUIT)
	}

	void HttpServer::accept()
	{
		socket_ptr socket = make_shared<asio::ip::tcp::socket>(asio::ip::tcp::socket(m_io_service));
		m_acceptor.async_accept(*socket, [this, socket](const boost::system::error_code& ec)
		{
			accept();
			if (!ec)
			{
				socket->set_option(asio::ip::tcp::no_delay(true));
				process_request(socket);
			}
		});
	}

	void HttpServer::process_request(socket_ptr socket)
	{
		// A stackful coroutine is needed here to correctly implement keep-alive
		// in case if the number of concurent requests is greater than
		// the number of server threads.
		// Without the coroutine the next request while all threads are busy
		// hangs in limbo and causes io_service to crash.
		asio::spawn(m_io_service, [this, socket](asio::yield_context yc)
		{
			Connection connection{ socket, m_io_service, yc, header_timeout, content_timeout };
			Request request{ connection };
			Response response{ connection };
			sys::error_code ec = request.parse_header();
			if (!ec)
			{
				check_static_route(request);
				response.http_version = request.http_version;
				handle_request(request, response);
			}
			else if (ec == sys::errc::bad_message)
			{
				response.send_mesage("400 Bad Request");
			}
			else if (ec == sys::errc::invalid_argument)
			{
				response.send_mesage("411 Length Required");
			}
			if (request.persistent())
				process_request(request.connection().socket());
		});
	}

	void HttpServer::check_static_route(Request& request)
	{
		for (const auto& route : m_static_routes)
		{
			if (boost::regex_search(request.path, route.first))
			{
				request.path_regex = route.first;
				request.content_dir = route.second;
				break;
			}
		}
	}

	void HttpServer::handle_request(Request& request, Response& response)
	{
		if (request.content_dir == string())
		{
			request.url_scheme = url_scheme;
			request.host_name = host_name;
			request.local_endpoint_port = m_port;
			GilAcquire acquire_gil;
			WsgiRequestHandler handler{ request, response, m_app };
			try
			{
				handler.handle();
			}
			catch (const py::error_already_set&)
			{
				PyErr_Print();
				response.send_mesage("500 Internal Server Error", "Error 500: WSGI application error!");
			}
			catch (const exception& ex)
			{
				cerr << ex.what() << '\n';
				response.send_mesage("500 Internal Server Error", "Error 500: Internal server error!");
			}
		}
		else
		{
			request.use_gzip = use_gzip;
			StaticRequestHandler handler{ request, response };
			try
			{
				handler.handle();
			}
			catch (const exception& ex)
			{
				cerr << ex.what() << '\n';
				response.send_mesage("500 Internal Server Error", "Error 500: Internal server error!");
			}
		}
	}

	void HttpServer::add_static_route(string path, string content_dir)
	{
		m_static_routes.emplace_back(boost::regex(path, boost::regex_constants::icase), content_dir);
	}

	void HttpServer::set_app(py::object app)
	{
		if (is_running())
			throw RuntimeError("Attempt to set a WSGI app while the server is running!");
		m_app = app;
	}

	void HttpServer::start()
	{
		if (!is_running())
		{
			cout << "Starting WsgiBoostHttp server...\n";
			GilRelease release_gil;
			if (m_io_service.stopped())
				m_io_service.reset();
			asio::ip::tcp::endpoint endpoint;
			if (m_ip_address != "")
			{
				asio::ip::tcp::resolver resolver(m_io_service);
				try
				{
					endpoint = *resolver.resolve({ m_ip_address, to_string(m_port) });
				}
				catch (const exception&)
				{
					throw RuntimeError("Unable to resolve IP address " + m_ip_address + " and port " + to_string(m_port) + "!");
				}
			}
			else
			{
				endpoint = asio::ip::tcp::endpoint(asio::ip::tcp::v4(), m_port);
			}
			m_acceptor.open(endpoint.protocol());
			m_acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(reuse_address));
			m_acceptor.bind(endpoint);
			m_acceptor.listen();
			if (host_name == string())
				host_name = asio::ip::host_name();
			accept();
			m_threads.clear();
			for (unsigned int i = 1; i < m_num_threads; ++i)
			{
				m_threads.emplace_back([this]()
				{
					m_io_service.run();
				});
			}
			m_signals.async_wait([this](sys::error_code, int) { stop(); });
			m_is_running.store(true);
			m_io_service.run();
			for (auto& t : m_threads)
			{
				t.join();
			}
		}
		else
		{
			cerr << "The server is already running!\n";
		}
	}

	void HttpServer::stop()
	{
		if (is_running())
		{
			m_acceptor.close();
			m_io_service.stop();
			m_signals.cancel();
			cout << "WsgiBoostHttp server stopped.\n";
			m_is_running.store(false);
		}
	}

	bool HttpServer::is_running() const
	{
		return m_is_running.load();
	}
}
<commit_msg>More informative server messages in console<commit_after>#include "server.h"

#include <boost/asio/spawn.hpp>

#include <memory>
#include <csignal>

using namespace std;
namespace asio = boost::asio;
namespace sys = boost::system;
namespace py = boost::python;

namespace wsgi_boost
{
	HttpServer::HttpServer(std::string ip_address, unsigned short port, unsigned int num_threads) :
		m_ip_address{ ip_address }, m_port{ port }, m_num_threads{ num_threads }, m_acceptor(m_io_service), m_signals{ m_io_service }
	{
		m_is_running.store(false);
		m_signals.add(SIGINT);
		m_signals.add(SIGTERM);
#if defined(SIGQUIT)
		m_signals.add(SIGQUIT);
#endif // defined(SIGQUIT)
	}

	void HttpServer::accept()
	{
		socket_ptr socket = make_shared<asio::ip::tcp::socket>(asio::ip::tcp::socket(m_io_service));
		m_acceptor.async_accept(*socket, [this, socket](const boost::system::error_code& ec)
		{
			accept();
			if (!ec)
			{
				socket->set_option(asio::ip::tcp::no_delay(true));
				process_request(socket);
			}
		});
	}

	void HttpServer::process_request(socket_ptr socket)
	{
		// A stackful coroutine is needed here to correctly implement keep-alive
		// in case if the number of concurent requests is greater than
		// the number of server threads.
		// Without the coroutine the next request while all threads are busy
		// hangs in limbo and causes io_service to crash.
		asio::spawn(m_io_service, [this, socket](asio::yield_context yc)
		{
			Connection connection{ socket, m_io_service, yc, header_timeout, content_timeout };
			Request request{ connection };
			Response response{ connection };
			sys::error_code ec = request.parse_header();
			if (!ec)
			{
				check_static_route(request);
				response.http_version = request.http_version;
				handle_request(request, response);
			}
			else if (ec == sys::errc::bad_message)
			{
				response.send_mesage("400 Bad Request");
			}
			else if (ec == sys::errc::invalid_argument)
			{
				response.send_mesage("411 Length Required");
			}
			if (request.persistent())
				process_request(request.connection().socket());
		});
	}

	void HttpServer::check_static_route(Request& request)
	{
		for (const auto& route : m_static_routes)
		{
			if (boost::regex_search(request.path, route.first))
			{
				request.path_regex = route.first;
				request.content_dir = route.second;
				break;
			}
		}
	}

	void HttpServer::handle_request(Request& request, Response& response)
	{
		if (request.content_dir == string())
		{
			request.url_scheme = url_scheme;
			request.host_name = host_name;
			request.local_endpoint_port = m_port;
			GilAcquire acquire_gil;
			WsgiRequestHandler handler{ request, response, m_app };
			try
			{
				handler.handle();
			}
			catch (const py::error_already_set&)
			{
				PyErr_Print();
				response.send_mesage("500 Internal Server Error", "Error 500: WSGI application error!");
			}
			catch (const exception& ex)
			{
				cerr << ex.what() << '\n';
				response.send_mesage("500 Internal Server Error", "Error 500: Internal server error!");
			}
		}
		else
		{
			request.use_gzip = use_gzip;
			StaticRequestHandler handler{ request, response };
			try
			{
				handler.handle();
			}
			catch (const exception& ex)
			{
				cerr << ex.what() << '\n';
				response.send_mesage("500 Internal Server Error", "Error 500: Internal server error!");
			}
		}
	}

	void HttpServer::add_static_route(string path, string content_dir)
	{
		m_static_routes.emplace_back(boost::regex(path, boost::regex_constants::icase), content_dir);
	}

	void HttpServer::set_app(py::object app)
	{
		if (is_running())
			throw RuntimeError("Attempt to set a WSGI app while the server is running!");
		m_app = app;
	}

	void HttpServer::start()
	{
		if (!is_running())
		{
			GilRelease release_gil;
			cout << "WsgiBoostHttp server starting.\n";
			cout << "Press Ctrl+C to stop it.\n";
			if (m_io_service.stopped())
				m_io_service.reset();
			asio::ip::tcp::endpoint endpoint;
			if (m_ip_address != "")
			{
				asio::ip::tcp::resolver resolver(m_io_service);
				try
				{
					endpoint = *resolver.resolve({ m_ip_address, to_string(m_port) });
				}
				catch (const exception&)
				{
					throw RuntimeError("Unable to resolve IP address " + m_ip_address + " and port " + to_string(m_port) + "!");
				}
			}
			else
			{
				endpoint = asio::ip::tcp::endpoint(asio::ip::tcp::v4(), m_port);
			}
			m_acceptor.open(endpoint.protocol());
			m_acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(reuse_address));
			m_acceptor.bind(endpoint);
			m_acceptor.listen();
			if (host_name == string())
				host_name = asio::ip::host_name();
			accept();
			m_threads.clear();
			for (unsigned int i = 1; i < m_num_threads; ++i)
			{
				m_threads.emplace_back([this]()
				{
					m_io_service.run();
				});
			}
			m_signals.async_wait([this](sys::error_code, int) { stop(); });
			m_is_running.store(true);
			m_io_service.run();
			for (auto& t : m_threads)
			{
				t.join();
			}
			cout << "WsgiBoostHttp server stopped.\n";
			m_is_running.store(false);
		}
		else
		{
			cerr << "The server is already running!\n";
		}
	}

	void HttpServer::stop()
	{
		if (is_running())
		{
			m_acceptor.close();
			m_io_service.stop();
			m_signals.cancel();
		}
		else
		{
			cerr << "The server is not running!\n";
		}
	}

	bool HttpServer::is_running() const
	{
		return m_is_running.load();
	}
}
<|endoftext|>


<commit_before>#include "../base/SRC_FIRST.hpp"
#include "shape_renderer.hpp"
#include "skin.hpp"

#include "../base/logging.hpp"

namespace yg
{
  namespace gl
  {
    ShapeRenderer::ShapeRenderer(base_t::Params const & params) : base_t(params)
    {
    }

    void ShapeRenderer::drawArc(m2::PointD const & center, double startA, double endA, double r, yg::Color const & c, double depth)
    {
      vector<m2::PointF> pts;
      approximateArc(center, startA, endA, r, pts);
      vector<m2::PointD> ptsD;
      copy(pts.begin(), pts.end(), back_inserter(ptsD));
      drawPath(&ptsD[0], ptsD.size(), skin()->mapPenInfo(yg::PenInfo(c, 3, 0, 0, 0)), depth);
    }

    void ShapeRenderer::approximateArc(m2::PointF const & center, double startA, double endA, double r, vector<m2::PointF> & pts)
    {
      double sectorA = math::pi / 180.0;
      unsigned sectorsCount = floor((endA - startA) / sectorA);
      sectorA = (endA - startA) / sectorsCount;

      for (unsigned i = 0; i <= sectorsCount; ++i)
        pts.push_back(m2::Shift(m2::Rotate(m2::PointD(r, 0), startA + i * sectorA), center));
    }

    void ShapeRenderer::drawSector(m2::PointD const & center, double startA, double endA, double r, yg::Color const & c, double depth)
    {
      vector<m2::PointF> pts;

      pts.push_back(center);
      approximateArc(center, startA, endA, r, pts);
      pts.push_back(center);

      vector<m2::PointD> ptsD;
      copy(pts.begin(), pts.end(), back_inserter(ptsD));
      drawPath(&ptsD[0], ptsD.size(), skin()->mapPenInfo(yg::PenInfo(c, 2, 0, 0, 0)), depth);
    }

    void ShapeRenderer::fillSector(m2::PointD const & center, double startA, double endA, double r, yg::Color const & c, double depth)
    {
      vector<m2::PointF> arcPts;

      arcPts.push_back(center);
      approximateArc(center, startA, endA, r, arcPts);

      m2::PointF pt0 = arcPts[0];
      m2::PointF pt1 = arcPts[1];

      vector<m2::PointD> sectorPts;

      for (size_t i = 2; i < arcPts.size(); ++i)
      {
        sectorPts.push_back(pt0);
        sectorPts.push_back(pt1);
        sectorPts.push_back(arcPts[i]);
        pt1 = arcPts[i];
      }

      drawTrianglesList(&sectorPts[0], sectorPts.size(), skin()->mapColor(c), depth);
    }

    void ShapeRenderer::drawRectangle(m2::RectD const & r, yg::Color const & c, double depth)
    {
      ResourceStyle const * style = skin()->fromID(skin()->mapColor(c));

      if (style == 0)
      {
        LOG(LINFO, ("cannot map color"));
        return;
      }

      m2::PointF rectPts[4] = {
          m2::PointF(r.minX(), r.minY()),
          m2::PointF(r.maxX(), r.minY()),
          m2::PointF(r.minX(), r.maxY()),
          m2::PointD(r.maxX(), r.maxY())
        };

      m2::PointF texPt = style->m_texRect.Center();

      addTexturedStripStrided(
          rectPts,
          sizeof(m2::PointF),
          &texPt,
          0,
          4,
          depth,
          style->m_pageID
          );
    }
  }
}
<commit_msg>drawRectangle rect color bug fix.<commit_after>#include "../base/SRC_FIRST.hpp"
#include "shape_renderer.hpp"
#include "skin.hpp"

#include "../base/logging.hpp"

namespace yg
{
  namespace gl
  {
    ShapeRenderer::ShapeRenderer(base_t::Params const & params) : base_t(params)
    {
    }

    void ShapeRenderer::drawArc(m2::PointD const & center, double startA, double endA, double r, yg::Color const & c, double depth)
    {
      vector<m2::PointF> pts;
      approximateArc(center, startA, endA, r, pts);
      vector<m2::PointD> ptsD;
      copy(pts.begin(), pts.end(), back_inserter(ptsD));
      drawPath(&ptsD[0], ptsD.size(), skin()->mapPenInfo(yg::PenInfo(c, 3, 0, 0, 0)), depth);
    }

    void ShapeRenderer::approximateArc(m2::PointF const & center, double startA, double endA, double r, vector<m2::PointF> & pts)
    {
      double sectorA = math::pi / 180.0;
      unsigned sectorsCount = floor((endA - startA) / sectorA);
      sectorA = (endA - startA) / sectorsCount;

      for (unsigned i = 0; i <= sectorsCount; ++i)
        pts.push_back(m2::Shift(m2::Rotate(m2::PointD(r, 0), startA + i * sectorA), center));
    }

    void ShapeRenderer::drawSector(m2::PointD const & center, double startA, double endA, double r, yg::Color const & c, double depth)
    {
      vector<m2::PointF> pts;

      pts.push_back(center);
      approximateArc(center, startA, endA, r, pts);
      pts.push_back(center);

      vector<m2::PointD> ptsD;
      copy(pts.begin(), pts.end(), back_inserter(ptsD));
      drawPath(&ptsD[0], ptsD.size(), skin()->mapPenInfo(yg::PenInfo(c, 2, 0, 0, 0)), depth);
    }

    void ShapeRenderer::fillSector(m2::PointD const & center, double startA, double endA, double r, yg::Color const & c, double depth)
    {
      vector<m2::PointF> arcPts;

      arcPts.push_back(center);
      approximateArc(center, startA, endA, r, arcPts);

      m2::PointF pt0 = arcPts[0];
      m2::PointF pt1 = arcPts[1];

      vector<m2::PointD> sectorPts;

      for (size_t i = 2; i < arcPts.size(); ++i)
      {
        sectorPts.push_back(pt0);
        sectorPts.push_back(pt1);
        sectorPts.push_back(arcPts[i]);
        pt1 = arcPts[i];
      }

      drawTrianglesList(&sectorPts[0], sectorPts.size(), skin()->mapColor(c), depth);
    }

    void ShapeRenderer::drawRectangle(m2::RectD const & r, yg::Color const & c, double depth)
    {
      ResourceStyle const * style = skin()->fromID(skin()->mapColor(c));

      if (style == 0)
      {
        LOG(LINFO, ("cannot map color"));
        return;
      }

      m2::PointF rectPts[4] = {
          m2::PointF(r.minX(), r.minY()),
          m2::PointF(r.maxX(), r.minY()),
          m2::PointF(r.minX(), r.maxY()),
          m2::PointD(r.maxX(), r.maxY())
        };

      m2::PointF texPt = skin()->pages()[style->m_pageID]->texture()->mapPixel(style->m_texRect.Center());

      addTexturedStripStrided(
          rectPts,
          sizeof(m2::PointF),
          &texPt,
          0,
          4,
          depth,
          style->m_pageID
          );
    }
  }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2018 The Android Open Source Project
 *
 * 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.
 */

#include <jni.h>
#include <string>
#include <vector>

#include "MegaDroneEngine.h"

std::vector<int> convertJavaArrayToVector(JNIEnv *env, jintArray intArray){

    std::vector<int> v;
    jsize length = env->GetArrayLength(intArray);

    if (length > 0) {
        jboolean isCopy;
        jint *elements = env->GetIntArrayElements(intArray, &isCopy);
        for (int i = 0; i < length; i++) {
            v.push_back(elements[i]);
        }
    }
    return v;
}
extern "C" {
/**
 * Start the audio engine
 *
 * @param env
 * @param instance
 * @param jCpuIds - CPU core IDs which the audio process should affine to
 * @return a pointer to the audio engine. This should be passed to other methods
 */
JNIEXPORT jlong JNICALL
Java_com_example_oboe_megadrone_MainActivity_startEngine(JNIEnv *env, jobject /*unused*/,
                                                         jintArray jCpuIds) {
    std::vector<int> cpuIds = convertJavaArrayToVector(env, jCpuIds);
    LOGD("cpu ids size: %d", static_cast<int>(cpuIds.size()));
    MegaDroneEngine  *engine = new MegaDroneEngine(std::move(cpuIds));
    LOGD("Engine Started");
    return reinterpret_cast<jlong>(engine);
}

JNIEXPORT void JNICALL
Java_com_example_oboe_megadrone_MainActivity_stopEngine(JNIEnv *env, jobject instance,
        jlong jEngineHandle) {
    auto engine = reinterpret_cast<MegaDroneEngine*>(jEngineHandle);
    if (engine) {
        delete engine;
    } else {
        LOGD("Engine invalid, call startEngine() to create");
    }
}

JNIEXPORT void JNICALL
Java_com_example_oboe_megadrone_MainActivity_tap(JNIEnv *env, jobject instance,
        jlong jEngineHandle, jboolean isDown) {

    auto *engine = reinterpret_cast<MegaDroneEngine*>(jEngineHandle);
    if (engine) {
        engine->tap(isDown);
    } else {
        LOGE("Engine handle is invalid, call createEngine() to create a new one");
    }
}

JNIEXPORT void JNICALL
Java_com_example_oboe_megadrone_MainActivity_native_1setDefaultStreamValues(JNIEnv *env,
                                                                            jclass type,
                                                                            jint sampleRate,
                                                                            jint framesPerBurst) {
    oboe::DefaultStreamValues::SampleRate = (int32_t) sampleRate;
    oboe::DefaultStreamValues::FramesPerBurst = (int32_t) framesPerBurst;
}

} // extern "C"<commit_msg>MegaDrone: fix memory leak in JNI<commit_after>/*
 * Copyright 2018 The Android Open Source Project
 *
 * 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.
 */

#include <jni.h>
#include <string>
#include <vector>

#include "MegaDroneEngine.h"

std::vector<int> convertJavaArrayToVector(JNIEnv *env, jintArray intArray) {
    std::vector<int> v;
    jsize length = env->GetArrayLength(intArray);
    if (length > 0) {
        jint *elements = env->GetIntArrayElements(intArray, nullptr);
        v.insert(v.end(), &elements[0], &elements[length]);
        // Unpin the memory for the array, or free the copy.
        env->ReleaseIntArrayElements(intArray, elements, 0);
    }
    return v;
}

extern "C" {
/**
 * Start the audio engine
 *
 * @param env
 * @param instance
 * @param jCpuIds - CPU core IDs which the audio process should affine to
 * @return a pointer to the audio engine. This should be passed to other methods
 */
JNIEXPORT jlong JNICALL
Java_com_example_oboe_megadrone_MainActivity_startEngine(JNIEnv *env, jobject /*unused*/,
                                                         jintArray jCpuIds) {
    std::vector<int> cpuIds = convertJavaArrayToVector(env, jCpuIds);
    LOGD("cpu ids size: %d", static_cast<int>(cpuIds.size()));
    MegaDroneEngine  *engine = new MegaDroneEngine(std::move(cpuIds));
    LOGD("Engine Started");
    return reinterpret_cast<jlong>(engine);
}

JNIEXPORT void JNICALL
Java_com_example_oboe_megadrone_MainActivity_stopEngine(JNIEnv *env, jobject instance,
        jlong jEngineHandle) {
    auto engine = reinterpret_cast<MegaDroneEngine*>(jEngineHandle);
    if (engine) {
        delete engine;
    } else {
        LOGD("Engine invalid, call startEngine() to create");
    }
}

JNIEXPORT void JNICALL
Java_com_example_oboe_megadrone_MainActivity_tap(JNIEnv *env, jobject instance,
        jlong jEngineHandle, jboolean isDown) {

    auto *engine = reinterpret_cast<MegaDroneEngine*>(jEngineHandle);
    if (engine) {
        engine->tap(isDown);
    } else {
        LOGE("Engine handle is invalid, call createEngine() to create a new one");
    }
}

JNIEXPORT void JNICALL
Java_com_example_oboe_megadrone_MainActivity_native_1setDefaultStreamValues(JNIEnv *env,
                                                                            jclass type,
                                                                            jint sampleRate,
                                                                            jint framesPerBurst) {
    oboe::DefaultStreamValues::SampleRate = (int32_t) sampleRate;
    oboe::DefaultStreamValues::FramesPerBurst = (int32_t) framesPerBurst;
}

} // extern "C"
<|endoftext|>


<commit_before>// Performance/Harness.cc - C++ performance harness definition
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Defines the class that runs the performance tests.
///
// -----------------------------------------------------------------------------

#include <chrono>
#include <cstdio>
#include <cmath>
#include <iostream>
#include <string>
#include <type_traits>
#include <vector>

#include "Harness.h"

using std::chrono::duration_cast;
using std::chrono::steady_clock;
using std::endl;
using std::function;
using std::ostream;
using std::result_of;
using std::sqrt;
using std::string;
using std::vector;

Harness::Harness(std::ostream* results_stream) :
    results_stream(results_stream),
    measurement_count(10),
    run_count(100),
    repeated_count(100) {}

void Harness::write_to_log(const string& name,
                           const vector<milliseconds_d>& timings) const {
  if (results_stream == nullptr) {
    return;
  }

  (*results_stream) << "\"" << name << "\": [";
  for (const auto& duration : timings) {
    auto millis = duration_cast<milliseconds_d>(duration);
    (*results_stream) << millis.count() << ", ";
  }
  (*results_stream) << "]," << endl;
}

Harness::Statistics Harness::compute_statistics(
    const vector<steady_clock::duration>& timings) const {
  milliseconds_d::rep sum = 0;
  milliseconds_d::rep sqsum = 0;

  for (const auto& duration : timings) {
    auto millis = duration_cast<milliseconds_d>(duration);
    auto count = millis.count();
    sum += count;
    sqsum += count * count;
  }

  auto n = timings.size();
  Statistics stats;
  stats.mean = sum / n;
  stats.stddev = sqrt(sqsum / n - stats.mean * stats.mean);
  return stats;
}
<commit_msg>Change C++ repeat count to match Swift harness<commit_after>// Performance/Harness.cc - C++ performance harness definition
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Defines the class that runs the performance tests.
///
// -----------------------------------------------------------------------------

#include <chrono>
#include <cstdio>
#include <cmath>
#include <iostream>
#include <string>
#include <type_traits>
#include <vector>

#include "Harness.h"

using std::chrono::duration_cast;
using std::chrono::steady_clock;
using std::endl;
using std::function;
using std::ostream;
using std::result_of;
using std::sqrt;
using std::string;
using std::vector;

Harness::Harness(std::ostream* results_stream) :
    results_stream(results_stream),
    measurement_count(10),
    run_count(100),
    repeated_count(10) {}

void Harness::write_to_log(const string& name,
                           const vector<milliseconds_d>& timings) const {
  if (results_stream == nullptr) {
    return;
  }

  (*results_stream) << "\"" << name << "\": [";
  for (const auto& duration : timings) {
    auto millis = duration_cast<milliseconds_d>(duration);
    (*results_stream) << millis.count() << ", ";
  }
  (*results_stream) << "]," << endl;
}

Harness::Statistics Harness::compute_statistics(
    const vector<steady_clock::duration>& timings) const {
  milliseconds_d::rep sum = 0;
  milliseconds_d::rep sqsum = 0;

  for (const auto& duration : timings) {
    auto millis = duration_cast<milliseconds_d>(duration);
    auto count = millis.count();
    sum += count;
    sqsum += count * count;
  }

  auto n = timings.size();
  Statistics stats;
  stats.mean = sum / n;
  stats.stddev = sqrt(sqsum / n - stats.mean * stats.mean);
  return stats;
}
<|endoftext|>


<commit_before>/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2016. All Rights Reserved.                             */
/* Open Source Software - may be modified and shared by FRC teams. The code   */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project.                                                               */
/*----------------------------------------------------------------------------*/

#include "HAL/HAL.h"

#include <signal.h>  // linux for kill
#include <sys/prctl.h>
#include <unistd.h>

#include <cstdlib>
#include <fstream>
#include <iostream>
#include <mutex>
#include <thread>

#include "FRC_NetworkCommunication/CANSessionMux.h"
#include "FRC_NetworkCommunication/FRCComm.h"
#include "FRC_NetworkCommunication/LoadOut.h"
#include "HAL/ChipObject.h"
#include "HAL/Errors.h"
#include "HAL/cpp/priority_mutex.h"
#include "HAL/handles/HandlesInternal.h"
#include "ctre/ctre.h"
#include "visa/visa.h"

using namespace hal;

static std::unique_ptr<tGlobal> global;
static std::unique_ptr<tSysWatchdog> watchdog;

static priority_mutex timeMutex;
static uint32_t timeEpoch = 0;
static uint32_t prevFPGATime = 0;
static HAL_NotifierHandle rolloverNotifier = 0;

using namespace hal;

extern "C" {

HAL_PortHandle HAL_GetPort(int32_t channel) {
  // Dont allow a number that wouldn't fit in a uint8_t
  if (channel < 0 || channel >= 255) return HAL_kInvalidHandle;
  return createPortHandle(channel, 1);
}

/**
 * @deprecated Uses module numbers
 */
HAL_PortHandle HAL_GetPortWithModule(int32_t module, int32_t channel) {
  // Dont allow a number that wouldn't fit in a uint8_t
  if (channel < 0 || channel >= 255) return HAL_kInvalidHandle;
  if (module < 0 || module >= 255) return HAL_kInvalidHandle;
  return createPortHandle(channel, module);
}

const char* HAL_GetErrorMessage(int32_t code) {
  switch (code) {
    case 0:
      return "";
    case CTR_RxTimeout:
      return CTR_RxTimeout_MESSAGE;
    case CTR_TxTimeout:
      return CTR_TxTimeout_MESSAGE;
    case CTR_InvalidParamValue:
      return CTR_InvalidParamValue_MESSAGE;
    case CTR_UnexpectedArbId:
      return CTR_UnexpectedArbId_MESSAGE;
    case CTR_TxFailed:
      return CTR_TxFailed_MESSAGE;
    case CTR_SigNotUpdated:
      return CTR_SigNotUpdated_MESSAGE;
    case NiFpga_Status_FifoTimeout:
      return NiFpga_Status_FifoTimeout_MESSAGE;
    case NiFpga_Status_TransferAborted:
      return NiFpga_Status_TransferAborted_MESSAGE;
    case NiFpga_Status_MemoryFull:
      return NiFpga_Status_MemoryFull_MESSAGE;
    case NiFpga_Status_SoftwareFault:
      return NiFpga_Status_SoftwareFault_MESSAGE;
    case NiFpga_Status_InvalidParameter:
      return NiFpga_Status_InvalidParameter_MESSAGE;
    case NiFpga_Status_ResourceNotFound:
      return NiFpga_Status_ResourceNotFound_MESSAGE;
    case NiFpga_Status_ResourceNotInitialized:
      return NiFpga_Status_ResourceNotInitialized_MESSAGE;
    case NiFpga_Status_HardwareFault:
      return NiFpga_Status_HardwareFault_MESSAGE;
    case NiFpga_Status_IrqTimeout:
      return NiFpga_Status_IrqTimeout_MESSAGE;
    case SAMPLE_RATE_TOO_HIGH:
      return SAMPLE_RATE_TOO_HIGH_MESSAGE;
    case VOLTAGE_OUT_OF_RANGE:
      return VOLTAGE_OUT_OF_RANGE_MESSAGE;
    case LOOP_TIMING_ERROR:
      return LOOP_TIMING_ERROR_MESSAGE;
    case SPI_WRITE_NO_MOSI:
      return SPI_WRITE_NO_MOSI_MESSAGE;
    case SPI_READ_NO_MISO:
      return SPI_READ_NO_MISO_MESSAGE;
    case SPI_READ_NO_DATA:
      return SPI_READ_NO_DATA_MESSAGE;
    case INCOMPATIBLE_STATE:
      return INCOMPATIBLE_STATE_MESSAGE;
    case NO_AVAILABLE_RESOURCES:
      return NO_AVAILABLE_RESOURCES_MESSAGE;
    case RESOURCE_IS_ALLOCATED:
      return RESOURCE_IS_ALLOCATED_MESSAGE;
    case RESOURCE_OUT_OF_RANGE:
      return RESOURCE_OUT_OF_RANGE_MESSAGE;
    case HAL_INVALID_ACCUMULATOR_CHANNEL:
      return HAL_INVALID_ACCUMULATOR_CHANNEL_MESSAGE;
    case HAL_HANDLE_ERROR:
      return HAL_HANDLE_ERROR_MESSAGE;
    case NULL_PARAMETER:
      return NULL_PARAMETER_MESSAGE;
    case ANALOG_TRIGGER_LIMIT_ORDER_ERROR:
      return ANALOG_TRIGGER_LIMIT_ORDER_ERROR_MESSAGE;
    case ANALOG_TRIGGER_PULSE_OUTPUT_ERROR:
      return ANALOG_TRIGGER_PULSE_OUTPUT_ERROR_MESSAGE;
    case PARAMETER_OUT_OF_RANGE:
      return PARAMETER_OUT_OF_RANGE_MESSAGE;
    case HAL_COUNTER_NOT_SUPPORTED:
      return HAL_COUNTER_NOT_SUPPORTED_MESSAGE;
    case ERR_CANSessionMux_InvalidBuffer:
      return ERR_CANSessionMux_InvalidBuffer_MESSAGE;
    case ERR_CANSessionMux_MessageNotFound:
      return ERR_CANSessionMux_MessageNotFound_MESSAGE;
    case WARN_CANSessionMux_NoToken:
      return WARN_CANSessionMux_NoToken_MESSAGE;
    case ERR_CANSessionMux_NotAllowed:
      return ERR_CANSessionMux_NotAllowed_MESSAGE;
    case ERR_CANSessionMux_NotInitialized:
      return ERR_CANSessionMux_NotInitialized_MESSAGE;
    case VI_ERROR_SYSTEM_ERROR:
      return VI_ERROR_SYSTEM_ERROR_MESSAGE;
    case VI_ERROR_INV_OBJECT:
      return VI_ERROR_INV_OBJECT_MESSAGE;
    case VI_ERROR_RSRC_LOCKED:
      return VI_ERROR_RSRC_LOCKED_MESSAGE;
    case VI_ERROR_RSRC_NFOUND:
      return VI_ERROR_RSRC_NFOUND_MESSAGE;
    case VI_ERROR_INV_RSRC_NAME:
      return VI_ERROR_INV_RSRC_NAME_MESSAGE;
    case VI_ERROR_QUEUE_OVERFLOW:
      return VI_ERROR_QUEUE_OVERFLOW_MESSAGE;
    case VI_ERROR_IO:
      return VI_ERROR_IO_MESSAGE;
    case VI_ERROR_ASRL_PARITY:
      return VI_ERROR_ASRL_PARITY_MESSAGE;
    case VI_ERROR_ASRL_FRAMING:
      return VI_ERROR_ASRL_FRAMING_MESSAGE;
    case VI_ERROR_ASRL_OVERRUN:
      return VI_ERROR_ASRL_OVERRUN_MESSAGE;
    case VI_ERROR_RSRC_BUSY:
      return VI_ERROR_RSRC_BUSY_MESSAGE;
    case VI_ERROR_INV_PARAMETER:
      return VI_ERROR_INV_PARAMETER_MESSAGE;
    case HAL_PWM_SCALE_ERROR:
      return HAL_PWM_SCALE_ERROR_MESSAGE;
    case HAL_SERIAL_PORT_NOT_FOUND:
      return HAL_SERIAL_PORT_NOT_FOUND_MESSAGE;
    case HAL_THREAD_PRIORITY_ERROR:
      return HAL_THREAD_PRIORITY_ERROR_MESSAGE;
    case HAL_THREAD_PRIORITY_RANGE_ERROR:
      return HAL_THREAD_PRIORITY_RANGE_ERROR_MESSAGE;
    default:
      return "Unknown error status";
  }
}

/**
 * Returns the runtime type of this HAL
 */
HAL_RuntimeType HAL_GetRuntimeType() { return HAL_Athena; }

/**
 * Return the FPGA Version number.
 * For now, expect this to be competition year.
 * @return FPGA Version number.
 */
int32_t HAL_GetFPGAVersion(int32_t* status) {
  if (!global) {
    *status = NiFpga_Status_ResourceNotInitialized;
    return 0;
  }
  return global->readVersion(status);
}

/**
 * Return the FPGA Revision number.
 * The format of the revision is 3 numbers.
 * The 12 most significant bits are the Major Revision.
 * the next 8 bits are the Minor Revision.
 * The 12 least significant bits are the Build Number.
 * @return FPGA Revision number.
 */
int64_t HAL_GetFPGARevision(int32_t* status) {
  if (!global) {
    *status = NiFpga_Status_ResourceNotInitialized;
    return 0;
  }
  return global->readRevision(status);
}

/**
 * Read the microsecond-resolution timer on the FPGA.
 *
 * @return The current time in microseconds according to the FPGA (since FPGA
 * reset).
 */
uint64_t HAL_GetFPGATime(int32_t* status) {
  if (!global) {
    *status = NiFpga_Status_ResourceNotInitialized;
    return 0;
  }
  std::lock_guard<priority_mutex> lock(timeMutex);
  uint32_t fpgaTime = global->readLocalTime(status);
  if (*status != 0) return 0;
  // check for rollover
  if (fpgaTime < prevFPGATime) ++timeEpoch;
  prevFPGATime = fpgaTime;
  return static_cast<uint64_t>(timeEpoch) << 32 |
         static_cast<uint64_t>(fpgaTime);
}

/**
 * Get the state of the "USER" button on the roboRIO
 * @return true if the button is currently pressed down
 */
HAL_Bool HAL_GetFPGAButton(int32_t* status) {
  if (!global) {
    *status = NiFpga_Status_ResourceNotInitialized;
    return false;
  }
  return global->readUserButton(status);
}

HAL_Bool HAL_GetSystemActive(int32_t* status) {
  if (!watchdog) {
    *status = NiFpga_Status_ResourceNotInitialized;
    return false;
  }
  return watchdog->readStatus_SystemActive(status);
}

HAL_Bool HAL_GetBrownedOut(int32_t* status) {
  if (!watchdog) {
    *status = NiFpga_Status_ResourceNotInitialized;
    return false;
  }
  return !(watchdog->readStatus_PowerAlive(status));
}

static void timerRollover(uint64_t currentTime, HAL_NotifierHandle handle) {
  // reschedule timer for next rollover
  int32_t status = 0;
  HAL_UpdateNotifierAlarm(handle, currentTime + 0x80000000ULL, &status);
}

void HAL_BaseInitialize(int32_t* status) {
  // image 4; Fixes errors caused by multiple processes. Talk to NI about this
  nFPGA::nRoboRIO_FPGANamespace::g_currentTargetClass =
      nLoadOut::kTargetClass_RoboRIO;

  global.reset(tGlobal::create(status));
  watchdog.reset(tSysWatchdog::create(status));
}

/**
 * Call this to start up HAL. This is required for robot programs.
 */
int32_t HAL_Initialize(int32_t mode) {
  setlinebuf(stdin);
  setlinebuf(stdout);

  prctl(PR_SET_PDEATHSIG, SIGTERM);

  FRC_NetworkCommunication_Reserve(nullptr);

  std::atexit([]() {
    // Unregister our new data condition variable.
    setNewDataSem(nullptr);
  });

  int32_t status = 0;
  HAL_BaseInitialize(&status);

  if (!rolloverNotifier)
    rolloverNotifier = HAL_InitializeNotifier(timerRollover, nullptr, &status);
  if (status == 0) {
    uint64_t curTime = HAL_GetFPGATime(&status);
    if (status == 0)
      HAL_UpdateNotifierAlarm(rolloverNotifier, curTime + 0x80000000ULL,
                              &status);
  }

  // Kill any previous robot programs
  std::fstream fs;
  // By making this both in/out, it won't give us an error if it doesnt exist
  fs.open("/var/lock/frc.pid", std::fstream::in | std::fstream::out);
  if (fs.bad()) return 0;

  pid_t pid = 0;
  if (!fs.eof() && !fs.fail()) {
    fs >> pid;
    // see if the pid is around, but we don't want to mess with init id=1, or
    // ourselves
    if (pid >= 2 && kill(pid, 0) == 0 && pid != getpid()) {
      std::cout << "Killing previously running FRC program..." << std::endl;
      kill(pid, SIGTERM);  // try to kill it
      std::this_thread::sleep_for(std::chrono::milliseconds(100));
      if (kill(pid, 0) == 0) {
        // still not successfull
        if (mode == 0) {
          std::cout << "FRC pid " << pid
                    << " did not die within 110ms. Aborting" << std::endl;
          return 0;              // just fail
        } else if (mode == 1) {  // kill -9 it
          kill(pid, SIGKILL);
        } else {
          std::cout << "WARNING: FRC pid " << pid
                    << " did not die within 110ms." << std::endl;
        }
      }
    }
  }
  fs.close();
  // we will re-open it write only to truncate the file
  fs.open("/var/lock/frc.pid", std::fstream::out | std::fstream::trunc);
  fs.seekp(0);
  pid = getpid();
  fs << pid << std::endl;
  fs.close();

  HAL_InitializeDriverStation();

  return 1;
}

int64_t HAL_Report(int32_t resource, int32_t instanceNumber, int32_t context,
                   const char* feature) {
  if (feature == nullptr) {
    feature = "";
  }

  return FRC_NetworkCommunication_nUsageReporting_report(
      resource, instanceNumber, context, feature);
}

// TODO: HACKS
// No need for header definitions, as we should not run from user code.
void NumericArrayResize() {}
void RTSetCleanupProc() {}
void EDVR_CreateReference() {}
void Occur() {}

}  // extern "C"
<commit_msg>Fixes multiple initialization of HAL_BaseInitialize (#400)<commit_after>/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2016. All Rights Reserved.                             */
/* Open Source Software - may be modified and shared by FRC teams. The code   */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project.                                                               */
/*----------------------------------------------------------------------------*/

#include "HAL/HAL.h"

#include <signal.h>  // linux for kill
#include <sys/prctl.h>
#include <unistd.h>

#include <atomic>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <mutex>
#include <thread>

#include "FRC_NetworkCommunication/CANSessionMux.h"
#include "FRC_NetworkCommunication/FRCComm.h"
#include "FRC_NetworkCommunication/LoadOut.h"
#include "HAL/ChipObject.h"
#include "HAL/Errors.h"
#include "HAL/cpp/priority_mutex.h"
#include "HAL/handles/HandlesInternal.h"
#include "ctre/ctre.h"
#include "visa/visa.h"

using namespace hal;

static std::unique_ptr<tGlobal> global;
static std::unique_ptr<tSysWatchdog> watchdog;

static priority_mutex timeMutex;
static uint32_t timeEpoch = 0;
static uint32_t prevFPGATime = 0;
static HAL_NotifierHandle rolloverNotifier = 0;

using namespace hal;

extern "C" {

HAL_PortHandle HAL_GetPort(int32_t channel) {
  // Dont allow a number that wouldn't fit in a uint8_t
  if (channel < 0 || channel >= 255) return HAL_kInvalidHandle;
  return createPortHandle(channel, 1);
}

/**
 * @deprecated Uses module numbers
 */
HAL_PortHandle HAL_GetPortWithModule(int32_t module, int32_t channel) {
  // Dont allow a number that wouldn't fit in a uint8_t
  if (channel < 0 || channel >= 255) return HAL_kInvalidHandle;
  if (module < 0 || module >= 255) return HAL_kInvalidHandle;
  return createPortHandle(channel, module);
}

const char* HAL_GetErrorMessage(int32_t code) {
  switch (code) {
    case 0:
      return "";
    case CTR_RxTimeout:
      return CTR_RxTimeout_MESSAGE;
    case CTR_TxTimeout:
      return CTR_TxTimeout_MESSAGE;
    case CTR_InvalidParamValue:
      return CTR_InvalidParamValue_MESSAGE;
    case CTR_UnexpectedArbId:
      return CTR_UnexpectedArbId_MESSAGE;
    case CTR_TxFailed:
      return CTR_TxFailed_MESSAGE;
    case CTR_SigNotUpdated:
      return CTR_SigNotUpdated_MESSAGE;
    case NiFpga_Status_FifoTimeout:
      return NiFpga_Status_FifoTimeout_MESSAGE;
    case NiFpga_Status_TransferAborted:
      return NiFpga_Status_TransferAborted_MESSAGE;
    case NiFpga_Status_MemoryFull:
      return NiFpga_Status_MemoryFull_MESSAGE;
    case NiFpga_Status_SoftwareFault:
      return NiFpga_Status_SoftwareFault_MESSAGE;
    case NiFpga_Status_InvalidParameter:
      return NiFpga_Status_InvalidParameter_MESSAGE;
    case NiFpga_Status_ResourceNotFound:
      return NiFpga_Status_ResourceNotFound_MESSAGE;
    case NiFpga_Status_ResourceNotInitialized:
      return NiFpga_Status_ResourceNotInitialized_MESSAGE;
    case NiFpga_Status_HardwareFault:
      return NiFpga_Status_HardwareFault_MESSAGE;
    case NiFpga_Status_IrqTimeout:
      return NiFpga_Status_IrqTimeout_MESSAGE;
    case SAMPLE_RATE_TOO_HIGH:
      return SAMPLE_RATE_TOO_HIGH_MESSAGE;
    case VOLTAGE_OUT_OF_RANGE:
      return VOLTAGE_OUT_OF_RANGE_MESSAGE;
    case LOOP_TIMING_ERROR:
      return LOOP_TIMING_ERROR_MESSAGE;
    case SPI_WRITE_NO_MOSI:
      return SPI_WRITE_NO_MOSI_MESSAGE;
    case SPI_READ_NO_MISO:
      return SPI_READ_NO_MISO_MESSAGE;
    case SPI_READ_NO_DATA:
      return SPI_READ_NO_DATA_MESSAGE;
    case INCOMPATIBLE_STATE:
      return INCOMPATIBLE_STATE_MESSAGE;
    case NO_AVAILABLE_RESOURCES:
      return NO_AVAILABLE_RESOURCES_MESSAGE;
    case RESOURCE_IS_ALLOCATED:
      return RESOURCE_IS_ALLOCATED_MESSAGE;
    case RESOURCE_OUT_OF_RANGE:
      return RESOURCE_OUT_OF_RANGE_MESSAGE;
    case HAL_INVALID_ACCUMULATOR_CHANNEL:
      return HAL_INVALID_ACCUMULATOR_CHANNEL_MESSAGE;
    case HAL_HANDLE_ERROR:
      return HAL_HANDLE_ERROR_MESSAGE;
    case NULL_PARAMETER:
      return NULL_PARAMETER_MESSAGE;
    case ANALOG_TRIGGER_LIMIT_ORDER_ERROR:
      return ANALOG_TRIGGER_LIMIT_ORDER_ERROR_MESSAGE;
    case ANALOG_TRIGGER_PULSE_OUTPUT_ERROR:
      return ANALOG_TRIGGER_PULSE_OUTPUT_ERROR_MESSAGE;
    case PARAMETER_OUT_OF_RANGE:
      return PARAMETER_OUT_OF_RANGE_MESSAGE;
    case HAL_COUNTER_NOT_SUPPORTED:
      return HAL_COUNTER_NOT_SUPPORTED_MESSAGE;
    case ERR_CANSessionMux_InvalidBuffer:
      return ERR_CANSessionMux_InvalidBuffer_MESSAGE;
    case ERR_CANSessionMux_MessageNotFound:
      return ERR_CANSessionMux_MessageNotFound_MESSAGE;
    case WARN_CANSessionMux_NoToken:
      return WARN_CANSessionMux_NoToken_MESSAGE;
    case ERR_CANSessionMux_NotAllowed:
      return ERR_CANSessionMux_NotAllowed_MESSAGE;
    case ERR_CANSessionMux_NotInitialized:
      return ERR_CANSessionMux_NotInitialized_MESSAGE;
    case VI_ERROR_SYSTEM_ERROR:
      return VI_ERROR_SYSTEM_ERROR_MESSAGE;
    case VI_ERROR_INV_OBJECT:
      return VI_ERROR_INV_OBJECT_MESSAGE;
    case VI_ERROR_RSRC_LOCKED:
      return VI_ERROR_RSRC_LOCKED_MESSAGE;
    case VI_ERROR_RSRC_NFOUND:
      return VI_ERROR_RSRC_NFOUND_MESSAGE;
    case VI_ERROR_INV_RSRC_NAME:
      return VI_ERROR_INV_RSRC_NAME_MESSAGE;
    case VI_ERROR_QUEUE_OVERFLOW:
      return VI_ERROR_QUEUE_OVERFLOW_MESSAGE;
    case VI_ERROR_IO:
      return VI_ERROR_IO_MESSAGE;
    case VI_ERROR_ASRL_PARITY:
      return VI_ERROR_ASRL_PARITY_MESSAGE;
    case VI_ERROR_ASRL_FRAMING:
      return VI_ERROR_ASRL_FRAMING_MESSAGE;
    case VI_ERROR_ASRL_OVERRUN:
      return VI_ERROR_ASRL_OVERRUN_MESSAGE;
    case VI_ERROR_RSRC_BUSY:
      return VI_ERROR_RSRC_BUSY_MESSAGE;
    case VI_ERROR_INV_PARAMETER:
      return VI_ERROR_INV_PARAMETER_MESSAGE;
    case HAL_PWM_SCALE_ERROR:
      return HAL_PWM_SCALE_ERROR_MESSAGE;
    case HAL_SERIAL_PORT_NOT_FOUND:
      return HAL_SERIAL_PORT_NOT_FOUND_MESSAGE;
    case HAL_THREAD_PRIORITY_ERROR:
      return HAL_THREAD_PRIORITY_ERROR_MESSAGE;
    case HAL_THREAD_PRIORITY_RANGE_ERROR:
      return HAL_THREAD_PRIORITY_RANGE_ERROR_MESSAGE;
    default:
      return "Unknown error status";
  }
}

/**
 * Returns the runtime type of this HAL
 */
HAL_RuntimeType HAL_GetRuntimeType() { return HAL_Athena; }

/**
 * Return the FPGA Version number.
 * For now, expect this to be competition year.
 * @return FPGA Version number.
 */
int32_t HAL_GetFPGAVersion(int32_t* status) {
  if (!global) {
    *status = NiFpga_Status_ResourceNotInitialized;
    return 0;
  }
  return global->readVersion(status);
}

/**
 * Return the FPGA Revision number.
 * The format of the revision is 3 numbers.
 * The 12 most significant bits are the Major Revision.
 * the next 8 bits are the Minor Revision.
 * The 12 least significant bits are the Build Number.
 * @return FPGA Revision number.
 */
int64_t HAL_GetFPGARevision(int32_t* status) {
  if (!global) {
    *status = NiFpga_Status_ResourceNotInitialized;
    return 0;
  }
  return global->readRevision(status);
}

/**
 * Read the microsecond-resolution timer on the FPGA.
 *
 * @return The current time in microseconds according to the FPGA (since FPGA
 * reset).
 */
uint64_t HAL_GetFPGATime(int32_t* status) {
  if (!global) {
    *status = NiFpga_Status_ResourceNotInitialized;
    return 0;
  }
  std::lock_guard<priority_mutex> lock(timeMutex);
  uint32_t fpgaTime = global->readLocalTime(status);
  if (*status != 0) return 0;
  // check for rollover
  if (fpgaTime < prevFPGATime) ++timeEpoch;
  prevFPGATime = fpgaTime;
  return static_cast<uint64_t>(timeEpoch) << 32 |
         static_cast<uint64_t>(fpgaTime);
}

/**
 * Get the state of the "USER" button on the roboRIO
 * @return true if the button is currently pressed down
 */
HAL_Bool HAL_GetFPGAButton(int32_t* status) {
  if (!global) {
    *status = NiFpga_Status_ResourceNotInitialized;
    return false;
  }
  return global->readUserButton(status);
}

HAL_Bool HAL_GetSystemActive(int32_t* status) {
  if (!watchdog) {
    *status = NiFpga_Status_ResourceNotInitialized;
    return false;
  }
  return watchdog->readStatus_SystemActive(status);
}

HAL_Bool HAL_GetBrownedOut(int32_t* status) {
  if (!watchdog) {
    *status = NiFpga_Status_ResourceNotInitialized;
    return false;
  }
  return !(watchdog->readStatus_PowerAlive(status));
}

static void timerRollover(uint64_t currentTime, HAL_NotifierHandle handle) {
  // reschedule timer for next rollover
  int32_t status = 0;
  HAL_UpdateNotifierAlarm(handle, currentTime + 0x80000000ULL, &status);
}

void HAL_BaseInitialize(int32_t* status) {
  static std::atomic_bool initialized{false};
  static priority_mutex initializeMutex;
  // Initial check, as if it's true initialization has finished
  if (initialized) return;

  std::lock_guard<priority_mutex> lock(initializeMutex);
  // Second check in case another thread was waiting
  if (initialized) return;
  // image 4; Fixes errors caused by multiple processes. Talk to NI about this
  nFPGA::nRoboRIO_FPGANamespace::g_currentTargetClass =
      nLoadOut::kTargetClass_RoboRIO;

  global.reset(tGlobal::create(status));
  watchdog.reset(tSysWatchdog::create(status));
  initialized = true;
}

/**
 * Call this to start up HAL. This is required for robot programs.
 */
int32_t HAL_Initialize(int32_t mode) {
  setlinebuf(stdin);
  setlinebuf(stdout);

  prctl(PR_SET_PDEATHSIG, SIGTERM);

  FRC_NetworkCommunication_Reserve(nullptr);

  std::atexit([]() {
    // Unregister our new data condition variable.
    setNewDataSem(nullptr);
  });

  int32_t status = 0;
  HAL_BaseInitialize(&status);

  if (!rolloverNotifier)
    rolloverNotifier = HAL_InitializeNotifier(timerRollover, nullptr, &status);
  if (status == 0) {
    uint64_t curTime = HAL_GetFPGATime(&status);
    if (status == 0)
      HAL_UpdateNotifierAlarm(rolloverNotifier, curTime + 0x80000000ULL,
                              &status);
  }

  // Kill any previous robot programs
  std::fstream fs;
  // By making this both in/out, it won't give us an error if it doesnt exist
  fs.open("/var/lock/frc.pid", std::fstream::in | std::fstream::out);
  if (fs.bad()) return 0;

  pid_t pid = 0;
  if (!fs.eof() && !fs.fail()) {
    fs >> pid;
    // see if the pid is around, but we don't want to mess with init id=1, or
    // ourselves
    if (pid >= 2 && kill(pid, 0) == 0 && pid != getpid()) {
      std::cout << "Killing previously running FRC program..." << std::endl;
      kill(pid, SIGTERM);  // try to kill it
      std::this_thread::sleep_for(std::chrono::milliseconds(100));
      if (kill(pid, 0) == 0) {
        // still not successfull
        if (mode == 0) {
          std::cout << "FRC pid " << pid
                    << " did not die within 110ms. Aborting" << std::endl;
          return 0;              // just fail
        } else if (mode == 1) {  // kill -9 it
          kill(pid, SIGKILL);
        } else {
          std::cout << "WARNING: FRC pid " << pid
                    << " did not die within 110ms." << std::endl;
        }
      }
    }
  }
  fs.close();
  // we will re-open it write only to truncate the file
  fs.open("/var/lock/frc.pid", std::fstream::out | std::fstream::trunc);
  fs.seekp(0);
  pid = getpid();
  fs << pid << std::endl;
  fs.close();

  HAL_InitializeDriverStation();

  return 1;
}

int64_t HAL_Report(int32_t resource, int32_t instanceNumber, int32_t context,
                   const char* feature) {
  if (feature == nullptr) {
    feature = "";
  }

  return FRC_NetworkCommunication_nUsageReporting_report(
      resource, instanceNumber, context, feature);
}

// TODO: HACKS
// No need for header definitions, as we should not run from user code.
void NumericArrayResize() {}
void RTSetCleanupProc() {}
void EDVR_CreateReference() {}
void Occur() {}

}  // extern "C"
<|endoftext|>


<commit_before>#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>

using namespace std;

#define MAX_N       400000
#define MOD         1000000007

int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43};
int flag[45];
int sum[10000];

unsigned int cnt[MAX_N + 1];

int main() {
    int q;
    scanf("%d", &q);

    vector<unsigned int> inputs;
    inputs.reserve(q);

    unsigned int max_n = 0;
    for (size_t i = 0; i < q; i++) {
        unsigned int n;
        scanf("%u", &n);
        if (n > max_n) {
            max_n = n;
        }
        inputs.push_back(n);
    }

    for (size_t i = 0; i < 14; i++) {
        flag[primes[i]] = 1;
    }

    for (size_t i = 3; i <= max_n; i++) {
        if (3 == i) {
            for (size_t j = 1; j <= 9; j++) {
                sum[j] = j;
            }
            for (size_t j = 10; j <= 99; j++) {
                int s = (j / 10) + (j % 10);
                sum[j] = s;
            }
            int c = 0;
            for (size_t j = 100; j <= 999; j++) {
                int s = (j / 100) + sum[(j % 100)];
                sum[j] = s;
                if (flag[s]) {
                    c ++;
                }
            }
            cnt[i] = c;
        }
        else if (4 == i) {
            for (size_t j = 1000; j <= 9999; j++) {
                int s = (j / 1000) + sum[(j % 1000)];
                sum[j] = s;

            }
        }
        else if (5 == i) {

        }
        else {

        }
    }

    for (size_t i = 0; i < q; i++) {
        printf("%u\n", cnt[i]);
    }

    return 0;
}
<commit_msg>20.00 points<commit_after>//
//  main.cpp
//  test
//
//  Created by 吴星煜 on 2018/4/11.
//  Copyright © 2018年 吴星煜. All rights reserved.
//

#include <cmath>
#include <cstdio>
#include <vector>
#include <set>
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>

using namespace std;

#define MAX_N       400000
#define MOD         1000000007
#define DEBUG		0

int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43};
int flag[45];
int sum[10000];
int tmp_sum[2][10000];

unsigned int cnt[MAX_N + 1];

int main() {
    int q;

#if DEBUG
    FILE * fp = fopen("input.txt", "r");
    FILE * fp_out = fopen("output.txt", "w");
    fscanf(fp, "%d", &q);
#else
    scanf("%d", &q);
#endif

    vector<unsigned int> inputs;
    inputs.reserve(q);

    unsigned int max_n = 0;
    for (size_t i = 0; i < q; i++) {
        unsigned int n;
#if DEBUG
        fscanf(fp, "%u", &n);
#else
        scanf("%u", &n);
#endif
        if (n > max_n) {
            max_n = n;
        }
        inputs.push_back(n);
    }

    for (size_t i = 0; i < 14; i++) {
        flag[primes[i]] = 1;
    }

    vector< set<int> > tmp_set(2);

    cnt[1] = 9;
    cnt[2] = 90;
    for (size_t i = 3; i <= max_n; i++) {
        if (3 == i) {
            for (size_t j = 1; j <= 9; j++) {
                if (flag[j]) {
                    sum[j] = j;
                }
            }
            for (size_t j = 10; j <= 99; j++) {
                int s = (j / 10) + (j % 10);
                if (flag[s]) {
                    sum[j] = s;
                }
            }
            int c = 0;
            for (size_t j = 100; j <= 999; j++) {
                int s = (j / 100) + (j % 100) / 10 + (j % 10);
                if (flag[s]) {
                    sum[j] = s;
                    c ++;
                }
            }
            cnt[i] = c;
        }
        else if (4 == i) {
            int c = 0;
            for (size_t j = 1000; j <= 9999; j++) {
                if (sum[(j / 10)] && sum[(j % 1000)]) {
                    int s = (j / 1000) + sum[(j % 1000)];
                    if (flag[s]) {
                        sum[j] = s;
                        c ++;
                    }
                }
            }
            cnt[i] = c;
        }
        else if (5 == i) {
            int c = 0;
            tmp_set[i % 2].clear();
            for (size_t j = 10000; j <= 99999; j++) {
                if (sum[(j / 10)] && sum[(j % 10000)]) {
                    int s = (j / 10000) + sum[(j % 10000)];
                    if (flag[s]) {
                        tmp_sum[i % 2][j % 10000] ++;
                        tmp_set[i % 2].insert(j % 10000);
                        c ++;
                    }
                }
            }
            cnt[i] = c;
        }
        else {
            int c = 0;
            tmp_set[i % 2].clear();
            set<int>::iterator iter = tmp_set[1 - i % 2].begin();
            while (iter != tmp_set[1 - i % 2].end()) {
                for (size_t j = 0; j < 10; j++) {
                    int new_index = (*iter * 10 + j) % 10000;
                    if (sum[new_index]) {
                        int s = sum[new_index] + (*iter / 1000);
                        if (flag[s]) {
                            set<int>::iterator find_it = tmp_set[i % 2].find(new_index);
                            if (find_it == tmp_set[i % 2].end()) {
                                // no found
                                tmp_sum[i % 2][new_index] = tmp_sum[1 - i % 2][*iter];
                            }
                            else {
                                tmp_sum[i % 2][new_index] += tmp_sum[1 - i % 2][*iter];
                                tmp_sum[i % 2][new_index] %= MOD;
                            }
                            c += tmp_sum[1 - i % 2][*iter];
                            c %= MOD;

                            tmp_set[i % 2].insert(new_index);
                        }
                    }
                }

                ++ iter;
            }

            cnt[i] = c;
        }
    }

    for (size_t i = 0; i < q; i++) {
#if DEBUG
        fprintf(fp_out, "%u\n", cnt[inputs[i]]);
#else
        printf("%u\n", cnt[inputs[i]]);
#endif
    }

#if DEBUG
    fclose(fp);
    fclose(fp_out);
#endif

    return 0;
}
<|endoftext|>