<commit_before>/*********************************************************************************
* Copyright (c) 2014 David D. Marshall <ddmarsha@calpoly.edu>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    David D. Marshall - initial code and implementation
********************************************************************************/

#ifndef eli_geom_curve_pseudo_four_digit_hpp
#define eli_geom_curve_pseudo_four_digit_hpp

#include <string>    // std::string
#include <sstream>   // std::ostringstream, std::istringstream
#include <iomanip>   // std::setw
#include <algorithm> // std::transform

#include "eli/code_eli.hpp"

namespace eli
{
  namespace geom
  {
    namespace curve
    {
      namespace pseudo
      {
        template<typename data__>
        class four_digit
        {
          public:
            typedef data__ data_type;
            typedef Eigen::Matrix<data_type, 1, 2> point_type;
            typedef Eigen::Matrix<data_type, 5, 1> coefficient_type;

          public:
            four_digit() : thickness(00), camber(0), camber_loc(0), sharp_te(false)
            {
              recalc_params();
              recalc_coefficients();
            }

            four_digit(const four_digit<data_type> &fs)
             : thickness(fs.thickness), camber(fs.camber), camber_loc(fs.camber_loc),
               sharp_te(fs.sharp_te)
            {
              recalc_params();
              recalc_coefficients();
            }

            coefficient_type get_thickness_coefficients() const {return a;}

            data_type get_t0() const {return static_cast<data_type>(-1);}
            data_type get_tmax() const {return static_cast<data_type>(1);}

            void set_sharp_trailing_edge(bool fl)
            {
              sharp_te=fl;
              recalc_coefficients();
            }
            bool sharp_trailing_edge() const {return sharp_te;}

            bool set_thickness(const data_type &t)
            {
              if (t<100)
              {
                thickness=t;
                recalc_params();
                return true;
              }
              return false;
            }
            data_type get_thickness() const {return thickness;}

            bool set_camber(const data_type &cam, const data_type &cam_loc)
            {
              if ( (cam<50) && (cam_loc<10) && (cam_loc>0))
              {
                camber=cam;
                camber_loc=cam_loc;
                recalc_params();
                return true;
              }

              return false;
            }
            data_type get_maximum_camber() const {return camber;}
            data_type get_maximum_camber_location() const {return camber_loc;}

            bool set_name(const std::string &name)
            {
              std::istringstream istr(name);
              std::string buffer;

              // get first character and eat preceding white space
              istr >> std::setw(4) >> buffer;
              if ((buffer == "NACA") || (buffer == "naca") || (buffer=="Naca"))
              {
                unsigned short mm, pp;
                char buf[3] = "\n\n";

                istr >> std::setw(4) >> buffer;
                buf[0]=buffer[0]; mm=std::atoi(buf);
                buf[0]=buffer[1]; pp=std::atoi(buf);

                if (set_camber(mm, pp))
                {
                  buf[0]=buffer[2];
                  buf[1]=buffer[3];
                  if (set_thickness(std::atoi(buf)))
                    return true;
                }
              }

              return false;
            }

            std::string get_name() const
            {
              std::ostringstream str;

              str.fill('0');
              str << "NACA " << std::setw(1) << camber << std::setw(1) << camber_loc << std::setw(2) << thickness;
              return str.str();
            }

            point_type f(const data_type &xi) const
            {
              point_type x, xp, xpp;

              evaluate(x, xp, xpp, xi);

              return x;
            }

            point_type fp(const data_type &xi) const
            {
              point_type x, xp, xpp;

              evaluate(x, xp, xpp, xi);

              return xp;
            }

            point_type fpp(const data_type &xi) const
            {
              point_type x, xp, xpp;

              evaluate(x, xp, xpp, xi);

              return xpp;
            }

            void evaluate(point_type &x, point_type &xp, point_type &xpp, const data_type &xi) const
            {
              // check to make sure given valid parametric value
              assert((xi>=-1) && (xi<=1));

              data_type xc, xcp, yc, ycp, ycpp, ycppp, yt, ytp, ytpp;
              const data_type one(1), two(2), three(3);
              bool lower;

              // calculate the lower surface
              if (xi<0)
              {
                xcp=-one;
                xc=-xi;
                lower=true;
              }
              // calculate the upper surface
              else
              {
                if (xi==0)
                {
                  xcp=0;
                }
                else
                {
                  xcp=one;
                }

                xc=xi;
                lower=false;
              }

              // calculate the supporting quantities needed
              calc_camber(yc, ycp, ycpp, ycppp, xc, lower);
              calc_thickness(yt, ytp, ytpp, xc, lower);

              data_type tmp1, cos_theta, cos2_theta, cos3_theta, sin_theta;

              tmp1=std::sqrt(one+ycp*ycp);
              cos_theta=one/tmp1;
              sin_theta=ycp/tmp1;
              cos2_theta=cos_theta*cos_theta;
              cos3_theta=cos2_theta*cos_theta;

              // calculate the info
              x(0)=xc-yt*sin_theta;
              x(1)=yc+yt*cos_theta;
              xp(0)=xcp-ytp*sin_theta-yt*cos3_theta*ycpp;
              xp(1)=ycp+ytp*cos_theta-yt*cos2_theta*sin_theta*ycpp;
              xpp(0)=-ytpp*sin_theta-two*ytp*cos3_theta*ycpp
                    +yt*cos2_theta*(three*cos2_theta*sin_theta*ycpp*ycpp-ycppp);
              xpp(1)=ycpp+ytpp*cos_theta-two*ytp*sin_theta*cos2_theta*ycpp
                    -yt*cos_theta*((two-cos2_theta)*cos2_theta*ycpp*ycpp-sin_theta*ycppp);
            }

            point_type tangent(const data_type &xi) const
            {
              point_type tgt(fp(xi));

              tgt.normalize();
              return tgt;
            }

          protected:
            void recalc_params()
            {
              data_type ten(10), one_hundred(100);

              p=camber/one_hundred;
              m=camber_loc/ten;
              t=thickness/one_hundred;
            }

            void recalc_coefficients()
            {
              typedef Eigen::Matrix<data_type, 5, 5> coefficient_matrix_type;

              coefficient_matrix_type coef_mat;
              coefficient_type rhs;
              coefficient_type orig_a;

              // set the specified coefficients
              orig_a << static_cast<data_type>(0.2969),
                        static_cast<data_type>(-0.1260),
                        static_cast<data_type>(-0.3516),
                        static_cast<data_type>(0.2843),
                        static_cast<data_type>(-0.1015);

              // if blunt trailing edge, then use specified coefficients
              if (!sharp_trailing_edge())
              {
                a=orig_a;
                return;
              }

              // if want sharp trailing edge then find "actual" constraints that
              // are placed on thickness distribution

              // calculate the constraint coefficients
              calc_four_digit_args(coef_mat, 0, static_cast<data_type>(1));        // (1) trailing edge location
              calc_four_digit_der_args(coef_mat, 1, static_cast<data_type>(1));    // (2) trailing edge slope
              calc_four_digit_args(coef_mat, 2, static_cast<data_type>(0.1));      // (3) leading edge shape
              calc_four_digit_args(coef_mat, 3, static_cast<data_type>(0.3));      // (4) thickness at x/c=0.3 (should be max thickness location, but isn't)
              calc_four_digit_der_args(coef_mat, 4, static_cast<data_type>(0.3));  // (5) slope at x/c=0.3 (should be zero slope at max thickness, but isn't)

              // calculate the corresponding constraints for the blunt trailing edge
              rhs=coef_mat*orig_a;

              // correct the trailing edge thickness constraint to zero while leaving the rest un changed
              rhs(0)=static_cast<data_type>(0);
              a=coef_mat.lu().solve(rhs);
            }

            template<typename Derived1>
            static void calc_four_digit_args(Eigen::MatrixBase<Derived1> &A, const typename Derived1::Index &i, const data_type &xi)
            {
              data_type xi2(xi*xi), xi3(xi2*xi), xi4(xi3*xi);

              A(i,0)=std::sqrt(xi);
              A(i,1)=xi;
              A(i,2)=xi2;
              A(i,3)=xi3;
              A(i,4)=xi4;
            }

            template<typename Derived1>
            static void calc_four_digit_der_args(Eigen::MatrixBase<Derived1> &A, const typename Derived1::Index &i, const data_type &xi)
            {
              data_type xi2(xi*xi), xi3(xi2*xi);

              A(i,0)=static_cast<data_type>(0.5)/std::sqrt(xi);
              A(i,1)=static_cast<data_type>(1);
              A(i,2)=static_cast<data_type>(2)*xi;
              A(i,3)=static_cast<data_type>(3)*xi2;
              A(i,4)=static_cast<data_type>(4)*xi3;
            }
            void calc_camber(data_type &y, data_type &yp, data_type &ypp, data_type &yppp, const data_type &xi, bool lower) const
            {
              // check to make sure given valid parametric value
              assert((xi>=0) && (xi<=1));

              data_type zero(0), one(1), two(2);

              // short circuit if no camber
              if (camber==0)
              {
                y=zero;
                yp=zero;
                ypp=zero;
                yppp=zero;

                return;
              }

              if (xi<=m)
              {
                data_type pm2=p/(m*m);

                y=pm2*(xi*(two*m-xi));
                yp=two*pm2*(m-xi);
                ypp=-two*pm2;
                yppp=zero;
              }
              else
              {
                data_type p1m2=p/(one+m*(m-two));

                y=p1m2*(one-two*m+xi*(two*m-xi));
                yp=two*p1m2*(m-xi);
                ypp=-two*p1m2;
                yppp=zero;

                if (lower)
                {
                  yp*=-one;
                  yppp*=-one;
                }
              }
            }

            void calc_thickness(data_type &y, data_type &yp, data_type &ypp, const data_type &xi, bool lower) const
            {
              // check to make sure given valid parametric value
              assert((xi>=0) && (xi<=1));

              const data_type zero(0), one(1), two(2), three(3), four(4), six(6), twelve(12), half(one/two), quarter(one/four);
              const data_type xi2(xi*xi), xi3(xi*xi2), xi4(xi2*xi2), sqrtxi(std::sqrt(xi));
              const data_type trat(t/static_cast<data_type>(0.20));

              // short circuit for no thickness
              if (thickness==0)
              {
                y=zero;
                yp=zero;
                ypp=zero;
                return;
              }

              if (xi==0)
              {
                y=zero;
                yp=one/std::numeric_limits<data_type>::epsilon();
                ypp=yp;
                return;
              }
              else if ((xi==1) && sharp_trailing_edge())
              {
                y=zero;
                yp=trat*(a.sum()-half*a(0));
                ypp=trat*(-quarter*a(0)+two*a(2)+six*a(3)+twelve*a(4));
                if (lower)
                {
                  ypp*=-one;
                }
                return;
              }

              y=trat*(a(0)*sqrtxi+a(1)*xi+a(2)*xi2+a(3)*xi3+a(4)*xi4);
              yp=trat*(half*a(0)/sqrtxi+a(1)+two*a(2)*xi+three*a(3)*xi2+four*a(4)*xi3);
              ypp=trat*(-quarter*a(0)/sqrtxi/xi+two*a(2)+six*a(3)*xi+twelve*a(4)*xi2);

              if (lower)
              {
                y*=-one;
                ypp*=-one;
              }
            }

          private:
            data_type thickness;    // thickness index (integer [00,99] with practical limit of [00, 30].
                                    // Index is interpreted as 100 times the maximum thickness.
            data_type camber;       // max camber index (integer [0,9]). Index will be
                                    // interpreted as 100 times the maximum camber.
            data_type camber_loc;   // chord-wise location of maximum camber index (integer [0,9]).
                                    // Index is interpreted as 10 times the maximum camber location.

            data_type m;  // location of maximum camber
            data_type p;  // maximum camber
            data_type t;  // maximum thickness
            bool sharp_te; // flag to indicate if the trailing edge should be sharp
            coefficient_type a; // coefficients for thickness distribution
        };
      }
    }
  }
}
#endif
<commit_msg>Defined index_type needed for some algorithms using pseudo curves.<commit_after>/*********************************************************************************
* Copyright (c) 2014 David D. Marshall <ddmarsha@calpoly.edu>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*    David D. Marshall - initial code and implementation
********************************************************************************/

#ifndef eli_geom_curve_pseudo_four_digit_hpp
#define eli_geom_curve_pseudo_four_digit_hpp

#include <string>    // std::string
#include <sstream>   // std::ostringstream, std::istringstream
#include <iomanip>   // std::setw
#include <algorithm> // std::transform

#include "eli/code_eli.hpp"

namespace eli
{
  namespace geom
  {
    namespace curve
    {
      namespace pseudo
      {
        template<typename data__>
        class four_digit
        {
          public:
            typedef data__ data_type;
            typedef Eigen::Matrix<data_type, 1, 2> point_type;
            typedef Eigen::Matrix<data_type, 5, 1> coefficient_type;
            typedef typename point_type::Index index_type;

          public:
            four_digit() : thickness(00), camber(0), camber_loc(0), sharp_te(false)
            {
              recalc_params();
              recalc_coefficients();
            }

            four_digit(const four_digit<data_type> &fs)
             : thickness(fs.thickness), camber(fs.camber), camber_loc(fs.camber_loc),
               sharp_te(fs.sharp_te)
            {
              recalc_params();
              recalc_coefficients();
            }

            coefficient_type get_thickness_coefficients() const {return a;}

            data_type get_t0() const {return static_cast<data_type>(-1);}
            data_type get_tmax() const {return static_cast<data_type>(1);}

            void set_sharp_trailing_edge(bool fl)
            {
              sharp_te=fl;
              recalc_coefficients();
            }
            bool sharp_trailing_edge() const {return sharp_te;}

            bool set_thickness(const data_type &t)
            {
              if (t<100)
              {
                thickness=t;
                recalc_params();
                return true;
              }
              return false;
            }
            data_type get_thickness() const {return thickness;}

            bool set_camber(const data_type &cam, const data_type &cam_loc)
            {
              if ( (cam<50) && (cam_loc<10) && (cam_loc>0))
              {
                camber=cam;
                camber_loc=cam_loc;
                recalc_params();
                return true;
              }

              return false;
            }
            data_type get_maximum_camber() const {return camber;}
            data_type get_maximum_camber_location() const {return camber_loc;}

            bool set_name(const std::string &name)
            {
              std::istringstream istr(name);
              std::string buffer;

              // get first character and eat preceding white space
              istr >> std::setw(4) >> buffer;
              if ((buffer == "NACA") || (buffer == "naca") || (buffer=="Naca"))
              {
                unsigned short mm, pp;
                char buf[3] = "\n\n";

                istr >> std::setw(4) >> buffer;
                buf[0]=buffer[0]; mm=std::atoi(buf);
                buf[0]=buffer[1]; pp=std::atoi(buf);

                if (set_camber(mm, pp))
                {
                  buf[0]=buffer[2];
                  buf[1]=buffer[3];
                  if (set_thickness(std::atoi(buf)))
                    return true;
                }
              }

              return false;
            }

            std::string get_name() const
            {
              std::ostringstream str;

              str.fill('0');
              str << "NACA " << std::setw(1) << camber << std::setw(1) << camber_loc << std::setw(2) << thickness;
              return str.str();
            }

            point_type f(const data_type &xi) const
            {
              point_type x, xp, xpp;

              evaluate(x, xp, xpp, xi);

              return x;
            }

            point_type fp(const data_type &xi) const
            {
              point_type x, xp, xpp;

              evaluate(x, xp, xpp, xi);

              return xp;
            }

            point_type fpp(const data_type &xi) const
            {
              point_type x, xp, xpp;

              evaluate(x, xp, xpp, xi);

              return xpp;
            }

            void evaluate(point_type &x, point_type &xp, point_type &xpp, const data_type &xi) const
            {
              // check to make sure given valid parametric value
              assert((xi>=-1) && (xi<=1));

              data_type xc, xcp, yc, ycp, ycpp, ycppp, yt, ytp, ytpp;
              const data_type one(1), two(2), three(3);
              bool lower;

              // calculate the lower surface
              if (xi<0)
              {
                xcp=-one;
                xc=-xi;
                lower=true;
              }
              // calculate the upper surface
              else
              {
                if (xi==0)
                {
                  xcp=0;
                }
                else
                {
                  xcp=one;
                }

                xc=xi;
                lower=false;
              }

              // calculate the supporting quantities needed
              calc_camber(yc, ycp, ycpp, ycppp, xc, lower);
              calc_thickness(yt, ytp, ytpp, xc, lower);

              data_type tmp1, cos_theta, cos2_theta, cos3_theta, sin_theta;

              tmp1=std::sqrt(one+ycp*ycp);
              cos_theta=one/tmp1;
              sin_theta=ycp/tmp1;
              cos2_theta=cos_theta*cos_theta;
              cos3_theta=cos2_theta*cos_theta;

              // calculate the info
              x(0)=xc-yt*sin_theta;
              x(1)=yc+yt*cos_theta;
              xp(0)=xcp-ytp*sin_theta-yt*cos3_theta*ycpp;
              xp(1)=ycp+ytp*cos_theta-yt*cos2_theta*sin_theta*ycpp;
              xpp(0)=-ytpp*sin_theta-two*ytp*cos3_theta*ycpp
                    +yt*cos2_theta*(three*cos2_theta*sin_theta*ycpp*ycpp-ycppp);
              xpp(1)=ycpp+ytpp*cos_theta-two*ytp*sin_theta*cos2_theta*ycpp
                    -yt*cos_theta*((two-cos2_theta)*cos2_theta*ycpp*ycpp-sin_theta*ycppp);
            }

            point_type tangent(const data_type &xi) const
            {
              point_type tgt(fp(xi));

              tgt.normalize();
              return tgt;
            }

          protected:
            void recalc_params()
            {
              data_type ten(10), one_hundred(100);

              p=camber/one_hundred;
              m=camber_loc/ten;
              t=thickness/one_hundred;
            }

            void recalc_coefficients()
            {
              typedef Eigen::Matrix<data_type, 5, 5> coefficient_matrix_type;

              coefficient_matrix_type coef_mat;
              coefficient_type rhs;
              coefficient_type orig_a;

              // set the specified coefficients
              orig_a << static_cast<data_type>(0.2969),
                        static_cast<data_type>(-0.1260),
                        static_cast<data_type>(-0.3516),
                        static_cast<data_type>(0.2843),
                        static_cast<data_type>(-0.1015);

              // if blunt trailing edge, then use specified coefficients
              if (!sharp_trailing_edge())
              {
                a=orig_a;
                return;
              }

              // if want sharp trailing edge then find "actual" constraints that
              // are placed on thickness distribution

              // calculate the constraint coefficients
              calc_four_digit_args(coef_mat, 0, static_cast<data_type>(1));        // (1) trailing edge location
              calc_four_digit_der_args(coef_mat, 1, static_cast<data_type>(1));    // (2) trailing edge slope
              calc_four_digit_args(coef_mat, 2, static_cast<data_type>(0.1));      // (3) leading edge shape
              calc_four_digit_args(coef_mat, 3, static_cast<data_type>(0.3));      // (4) thickness at x/c=0.3 (should be max thickness location, but isn't)
              calc_four_digit_der_args(coef_mat, 4, static_cast<data_type>(0.3));  // (5) slope at x/c=0.3 (should be zero slope at max thickness, but isn't)

              // calculate the corresponding constraints for the blunt trailing edge
              rhs=coef_mat*orig_a;

              // correct the trailing edge thickness constraint to zero while leaving the rest un changed
              rhs(0)=static_cast<data_type>(0);
              a=coef_mat.lu().solve(rhs);
            }

            template<typename Derived1>
            static void calc_four_digit_args(Eigen::MatrixBase<Derived1> &A, const typename Derived1::Index &i, const data_type &xi)
            {
              data_type xi2(xi*xi), xi3(xi2*xi), xi4(xi3*xi);

              A(i,0)=std::sqrt(xi);
              A(i,1)=xi;
              A(i,2)=xi2;
              A(i,3)=xi3;
              A(i,4)=xi4;
            }

            template<typename Derived1>
            static void calc_four_digit_der_args(Eigen::MatrixBase<Derived1> &A, const typename Derived1::Index &i, const data_type &xi)
            {
              data_type xi2(xi*xi), xi3(xi2*xi);

              A(i,0)=static_cast<data_type>(0.5)/std::sqrt(xi);
              A(i,1)=static_cast<data_type>(1);
              A(i,2)=static_cast<data_type>(2)*xi;
              A(i,3)=static_cast<data_type>(3)*xi2;
              A(i,4)=static_cast<data_type>(4)*xi3;
            }
            void calc_camber(data_type &y, data_type &yp, data_type &ypp, data_type &yppp, const data_type &xi, bool lower) const
            {
              // check to make sure given valid parametric value
              assert((xi>=0) && (xi<=1));

              data_type zero(0), one(1), two(2);

              // short circuit if no camber
              if (camber==0)
              {
                y=zero;
                yp=zero;
                ypp=zero;
                yppp=zero;

                return;
              }

              if (xi<=m)
              {
                data_type pm2=p/(m*m);

                y=pm2*(xi*(two*m-xi));
                yp=two*pm2*(m-xi);
                ypp=-two*pm2;
                yppp=zero;
              }
              else
              {
                data_type p1m2=p/(one+m*(m-two));

                y=p1m2*(one-two*m+xi*(two*m-xi));
                yp=two*p1m2*(m-xi);
                ypp=-two*p1m2;
                yppp=zero;

                if (lower)
                {
                  yp*=-one;
                  yppp*=-one;
                }
              }
            }

            void calc_thickness(data_type &y, data_type &yp, data_type &ypp, const data_type &xi, bool lower) const
            {
              // check to make sure given valid parametric value
              assert((xi>=0) && (xi<=1));

              const data_type zero(0), one(1), two(2), three(3), four(4), six(6), twelve(12), half(one/two), quarter(one/four);
              const data_type xi2(xi*xi), xi3(xi*xi2), xi4(xi2*xi2), sqrtxi(std::sqrt(xi));
              const data_type trat(t/static_cast<data_type>(0.20));

              // short circuit for no thickness
              if (thickness==0)
              {
                y=zero;
                yp=zero;
                ypp=zero;
                return;
              }

              if (xi==0)
              {
                y=zero;
                yp=one/std::numeric_limits<data_type>::epsilon();
                ypp=yp;
                return;
              }
              else if ((xi==1) && sharp_trailing_edge())
              {
                y=zero;
                yp=trat*(a.sum()-half*a(0));
                ypp=trat*(-quarter*a(0)+two*a(2)+six*a(3)+twelve*a(4));
                if (lower)
                {
                  ypp*=-one;
                }
                return;
              }

              y=trat*(a(0)*sqrtxi+a(1)*xi+a(2)*xi2+a(3)*xi3+a(4)*xi4);
              yp=trat*(half*a(0)/sqrtxi+a(1)+two*a(2)*xi+three*a(3)*xi2+four*a(4)*xi3);
              ypp=trat*(-quarter*a(0)/sqrtxi/xi+two*a(2)+six*a(3)*xi+twelve*a(4)*xi2);

              if (lower)
              {
                y*=-one;
                ypp*=-one;
              }
            }

          private:
            data_type thickness;    // thickness index (integer [00,99] with practical limit of [00, 30].
                                    // Index is interpreted as 100 times the maximum thickness.
            data_type camber;       // max camber index (integer [0,9]). Index will be
                                    // interpreted as 100 times the maximum camber.
            data_type camber_loc;   // chord-wise location of maximum camber index (integer [0,9]).
                                    // Index is interpreted as 10 times the maximum camber location.

            data_type m;  // location of maximum camber
            data_type p;  // maximum camber
            data_type t;  // maximum thickness
            bool sharp_te; // flag to indicate if the trailing edge should be sharp
            coefficient_type a; // coefficients for thickness distribution
        };
      }
    }
  }
}
#endif
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2018 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include "etl/expr/base_temporary_expr.hpp"

#include "etl/impl/cudnn/bias_batch_mean.hpp"

namespace etl {

/*!
 * \brief A transposition expression.
 * \tparam A The transposed type
 */
template <typename A, bool Mean>
struct bias_batch_mean_4d_expr : base_temporary_expr_un<bias_batch_mean_4d_expr<A, Mean>, A> {
    using value_type = value_t<A>;                           ///< The type of value of the expression
    using this_type  = bias_batch_mean_4d_expr<A, Mean>;     ///< The type of this expression
    using base_type  = base_temporary_expr_un<this_type, A>; ///< The base type
    using sub_traits = decay_traits<A>;                      ///< The traits of the sub type

    static constexpr auto storage_order = sub_traits::storage_order; ///< The sub storage order

    /*!
     * \brief Indicates if the temporary expression can be directly evaluated
     * using only GPU.
     */
    static constexpr bool gpu_computable = !Mean && cudnn_enabled && is_floating<A>;

    /*!
     * \brief Construct a new expression
     * \param a The sub expression
     */
    explicit bias_batch_mean_4d_expr(A a) : base_type(a) {
        //Nothing else to init
    }

    /*!
     * \brief Validate the transposition dimensions
     * \param a The input matrix
     * \þaram c The output matrix
     */
    template <typename C>
    static void check([[maybe_unused]] const A& a, [[maybe_unused]] const C& c) {
        static_assert(etl::dimensions<C>() == 1, "The output of bias_batch_mean_4d is a vector");
        static_assert(etl::dimensions<A>() == 4, "The input of bias_batch_mean_4d is a 4D matrix");

        if constexpr (all_fast<A, C>) {
            static_assert(etl::dim<1, A>() == etl::dim<0, C>(), "Invalid dimensions for bias_batch_mean_4d");
        } else {
            cpp_assert(etl::dim<1>(a) == etl::dim<0>(c), "Invalid dimensions for bias_batch_mean_4d");
        }
    }

    // Assignment functions

    /*!
     * \brief Assign to a matrix of the same storage order
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_4d only supported for ETL expressions");

        auto& a = this->a();

        using T = value_t<A>;

        check(a, lhs);

        if constexpr (!Mean && cudnn_enabled && all_floating<A, L>) {
            impl::cudnn::bias_batch_mean_4d(smart_forward_gpu(a), lhs);
        } else {
            const auto N = etl::size(a) / etl::size(lhs);
            const auto K = etl::size(lhs);

            standard_evaluator::pre_assign_rhs(a);

            a.ensure_cpu_up_to_date();
            a.ensure_gpu_up_to_date();

            auto batch_fun_k = [&](const size_t first, const size_t last) {
                for (size_t k = first; k < last; ++k) {
                    T mean(0);

                    for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                        mean += sum(a(b)(k));
                    }

                    if constexpr (Mean) {
                        lhs(k) = mean / N;
                    } else {
                        lhs(k) = mean;
                    }
                }
            };

            engine_dispatch_1d_serial(batch_fun_k, 0, K, 2UL);
        }
    }

    /*!
     * \brief Add to the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_add_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_4d only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        a.ensure_cpu_up_to_date();
        a.ensure_gpu_up_to_date();

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            for (size_t k = first; k < last; ++k) {
                T mean(0);

                for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                    mean += sum(a(b)(k));
                }

                if constexpr (Mean) {
                    lhs(k) += mean / N;
                } else {
                    lhs(k) += mean;
                }
            }
        };

        engine_dispatch_1d_serial(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Sub from the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_sub_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_4d only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        a.ensure_cpu_up_to_date();
        a.ensure_gpu_up_to_date();

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            for (size_t k = first; k < last; ++k) {
                T mean(0);

                for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                    mean += sum(a(b)(k));
                }

                if constexpr (Mean) {
                    lhs(k) -= mean / N;
                } else {
                    lhs(k) -= mean;
                }
            }
        };

        engine_dispatch_1d_serial(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Multiply the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_mul_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_4d only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        a.ensure_cpu_up_to_date();
        a.ensure_gpu_up_to_date();

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            for (size_t k = first; k < last; ++k) {
                T mean(0);

                for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                    mean += sum(a(b)(k));
                }

                if constexpr (Mean) {
                    lhs(k) *= mean / N;
                } else {
                    lhs(k) *= mean;
                }
            }
        };

        engine_dispatch_1d_serial(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Divide the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_div_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_4d only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        a.ensure_cpu_up_to_date();
        a.ensure_gpu_up_to_date();

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            for (size_t k = first; k < last; ++k) {
                T mean(0);

                for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                    mean += sum(a(b)(k));
                }

                if constexpr (Mean) {
                    lhs(k) /= mean / N;
                } else {
                    lhs(k) /= mean;
                }
            }
        };

        engine_dispatch_1d_serial(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Modulo the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_mod_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_4d only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        a.ensure_cpu_up_to_date();
        a.ensure_gpu_up_to_date();

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            for (size_t k = first; k < last; ++k) {
                T mean(0);

                for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                    mean += sum(a(b)(k));
                }

                if constexpr (Mean) {
                    lhs(k) %= mean / N;
                } else {
                    lhs(k) %= mean;
                }
            }
        };

        engine_dispatch_1d_serial(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Print a representation of the expression on the given stream
     * \param os The output stream
     * \param expr The expression to print
     * \return the output stream
     */
    friend std::ostream& operator<<(std::ostream& os, const bias_batch_mean_4d_expr& expr) {
        if (Mean) {
            return os << "bias_batch_mean_4d(" << expr._a << ")";
        } else {
            return os << "bias_batch_sum_4d(" << expr._a << ")";
        }
    }
};

/*!
 * \brief Traits for a transpose expression
 * \tparam A The transposed sub type
 */
template <typename A, bool Mean>
struct etl_traits<etl::bias_batch_mean_4d_expr<A, Mean>> {
    using expr_t     = etl::bias_batch_mean_4d_expr<A, Mean>; ///< The expression type
    using sub_expr_t = std::decay_t<A>;                       ///< The sub expression type
    using sub_traits = etl_traits<sub_expr_t>;                ///< The sub traits
    using value_type = value_t<A>;                            ///< The value type of the expression

    static constexpr bool is_etl         = true;                                 ///< Indicates if the type is an ETL expression
    static constexpr bool is_transformer = false;                                ///< Indicates if the type is a transformer
    static constexpr bool is_view        = false;                                ///< Indicates if the type is a view
    static constexpr bool is_magic_view  = false;                                ///< Indicates if the type is a magic view
    static constexpr bool is_fast        = sub_traits::is_fast;                  ///< Indicates if the expression is fast
    static constexpr bool is_linear      = false;                                ///< Indicates if the expression is linear
    static constexpr bool is_thread_safe = true;                                 ///< Indicates if the expression is thread safe
    static constexpr bool is_value       = false;                                ///< Indicates if the expression is of value type
    static constexpr bool is_direct      = true;                                 ///< Indicates if the expression has direct memory access
    static constexpr bool is_generator   = false;                                ///< Indicates if the expression is a generator
    static constexpr bool is_padded      = false;                                ///< Indicates if the expression is padded
    static constexpr bool is_aligned     = true;                                 ///< Indicates if the expression is padded
    static constexpr bool is_temporary   = true;                                 ///< Indicates if the expression needs a evaluator visitor
    static constexpr bool gpu_computable = is_gpu_t<value_type> && cuda_enabled; ///< Indicates if the expression can be computed on GPU
    static constexpr order storage_order = sub_traits::storage_order;            ///< The expression's storage order

    /*!
     * \brief Indicates if the expression is vectorizable using the
     * given vector mode
     * \tparam V The vector mode
     */
    template <vector_mode_t V>
    static constexpr bool vectorizable = true;

    /*!
     * \brief Returns the DDth dimension of the expression
     * \return the DDth dimension of the expression
     */
    template <size_t DD>
    static constexpr size_t dim() {
        static_assert(DD == 0, "Invalid dimensions access");
        return decay_traits<A>::template dim<1>();
    }

    /*!
     * \brief Returns the dth dimension of the expression
     * \param e The sub expression
     * \param d The dimension to get
     * \return the dth dimension of the expression
     */
    static size_t dim(const expr_t& e, size_t d) {
        cpp_assert(d == 0, "Invalid dimensions access");
        cpp_unused(d);
        return etl::dim<1>(e._a);
    }

    /*!
     * \brief Returns the size of the expression
     * \param e The sub expression
     * \return the size of the expression
     */
    static size_t size(const expr_t& e) {
        return etl::dim<1>(e._a);
    }

    /*!
     * \brief Returns the size of the expression
     * \return the size of the expression
     */
    static constexpr size_t size() {
        return decay_traits<A>::template dim<1>();
    }

    /*!
     * \brief Returns the number of dimensions of the expression
     * \return the number of dimensions of the expression
     */
    static constexpr size_t dimensions() {
        return 1;
    }
};

/*!
 * \brief Returns the transpose of the given expression.
 * \param value The expression
 * \return The transpose of the given expression.
 */
template <typename E>
bias_batch_mean_4d_expr<detail::build_type<E>, true> bias_batch_mean_4d(const E& value) {
    static_assert(is_etl_expr<E>, "etl::bias_batch_mean_4d can only be used on ETL expressions");
    static_assert(is_4d<E>, "etl::bias_batch_mean_4d is only defined for 4D input");

    return bias_batch_mean_4d_expr<detail::build_type<E>, true>{value};
}

/*!
 * \brief Returns the transpose of the given expression.
 * \param value The expression
 * \return The transpose of the given expression.
 */
template <typename E>
bias_batch_mean_4d_expr<detail::build_type<E>, false> bias_batch_sum_4d(const E& value) {
    static_assert(is_etl_expr<E>, "etl::bias_batch_sum_4d can only be used on ETL expressions");
    static_assert(is_4d<E>, "etl::bias_batch_sum_4d is only defined for 4D input");

    return bias_batch_mean_4d_expr<detail::build_type<E>, false>{value};
}

} //end of namespace etl
<commit_msg>Silence warnings<commit_after>//=======================================================================
// Copyright (c) 2014-2018 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include "etl/expr/base_temporary_expr.hpp"

#include "etl/impl/cudnn/bias_batch_mean.hpp"

namespace etl {

/*!
 * \brief A transposition expression.
 * \tparam A The transposed type
 */
template <typename A, bool Mean>
struct bias_batch_mean_4d_expr : base_temporary_expr_un<bias_batch_mean_4d_expr<A, Mean>, A> {
    using value_type = value_t<A>;                           ///< The type of value of the expression
    using this_type  = bias_batch_mean_4d_expr<A, Mean>;     ///< The type of this expression
    using base_type  = base_temporary_expr_un<this_type, A>; ///< The base type
    using sub_traits = decay_traits<A>;                      ///< The traits of the sub type

    static constexpr auto storage_order = sub_traits::storage_order; ///< The sub storage order

    /*!
     * \brief Indicates if the temporary expression can be directly evaluated
     * using only GPU.
     */
    static constexpr bool gpu_computable = !Mean && cudnn_enabled && is_floating<A>;

    /*!
     * \brief Construct a new expression
     * \param a The sub expression
     */
    explicit bias_batch_mean_4d_expr(A a) : base_type(a) {
        //Nothing else to init
    }

    /*!
     * \brief Validate the transposition dimensions
     * \param a The input matrix
     * \þaram c The output matrix
     */
    template <typename C>
    static void check([[maybe_unused]] const A& a, [[maybe_unused]] const C& c) {
        static_assert(etl::dimensions<C>() == 1, "The output of bias_batch_mean_4d is a vector");
        static_assert(etl::dimensions<A>() == 4, "The input of bias_batch_mean_4d is a 4D matrix");

        if constexpr (all_fast<A, C>) {
            static_assert(etl::dim<1, A>() == etl::dim<0, C>(), "Invalid dimensions for bias_batch_mean_4d");
        } else {
            cpp_assert(etl::dim<1>(a) == etl::dim<0>(c), "Invalid dimensions for bias_batch_mean_4d");
        }
    }

    // Assignment functions

    /*!
     * \brief Assign to a matrix of the same storage order
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_4d only supported for ETL expressions");

        auto& a = this->a();

        using T = value_t<A>;

        check(a, lhs);

        if constexpr (!Mean && cudnn_enabled && all_floating<A, L>) {
            impl::cudnn::bias_batch_mean_4d(smart_forward_gpu(a), lhs);
        } else {
            const auto N = etl::size(a) / etl::size(lhs);
            const auto K = etl::size(lhs);

            standard_evaluator::pre_assign_rhs(a);

            a.ensure_cpu_up_to_date();
            a.ensure_gpu_up_to_date();

            auto batch_fun_k = [&](const size_t first, const size_t last) {
                for (size_t k = first; k < last; ++k) {
                    T mean(0);

                    for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                        mean += sum(a(b)(k));
                    }

                    if constexpr (Mean) {
                        lhs(k) = mean / N;
                    } else {
                        lhs(k) = mean;
                    }
                }
            };

            engine_dispatch_1d_serial(batch_fun_k, 0, K, 2UL);
        }
    }

    /*!
     * \brief Add to the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_add_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_4d only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        a.ensure_cpu_up_to_date();
        a.ensure_gpu_up_to_date();

        const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            for (size_t k = first; k < last; ++k) {
                T mean(0);

                for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                    mean += sum(a(b)(k));
                }

                if constexpr (Mean) {
                    lhs(k) += mean / N;
                } else {
                    lhs(k) += mean;
                }
            }
        };

        engine_dispatch_1d_serial(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Sub from the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_sub_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_4d only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        a.ensure_cpu_up_to_date();
        a.ensure_gpu_up_to_date();

        [[maybe_unused]] const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            for (size_t k = first; k < last; ++k) {
                T mean(0);

                for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                    mean += sum(a(b)(k));
                }

                if constexpr (Mean) {
                    lhs(k) -= mean / N;
                } else {
                    lhs(k) -= mean;
                }
            }
        };

        engine_dispatch_1d_serial(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Multiply the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_mul_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_4d only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        a.ensure_cpu_up_to_date();
        a.ensure_gpu_up_to_date();

        [[maybe_unused]] const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            for (size_t k = first; k < last; ++k) {
                T mean(0);

                for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                    mean += sum(a(b)(k));
                }

                if constexpr (Mean) {
                    lhs(k) *= mean / N;
                } else {
                    lhs(k) *= mean;
                }
            }
        };

        engine_dispatch_1d_serial(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Divide the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_div_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_4d only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        a.ensure_cpu_up_to_date();
        a.ensure_gpu_up_to_date();

        [[maybe_unused]] const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            for (size_t k = first; k < last; ++k) {
                T mean(0);

                for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                    mean += sum(a(b)(k));
                }

                if constexpr (Mean) {
                    lhs(k) /= mean / N;
                } else {
                    lhs(k) /= mean;
                }
            }
        };

        engine_dispatch_1d_serial(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Modulo the given left-hand-side expression
     * \param lhs The expression to which assign
     */
    template <typename L>
    void assign_mod_to(L&& lhs) const {
        static_assert(all_etl_expr<A, L>, "bias_batch_mean_4d only supported for ETL expressions");

        auto& a = this->a();

        standard_evaluator::pre_assign_rhs(a);

        a.ensure_cpu_up_to_date();
        a.ensure_gpu_up_to_date();

        [[maybe_unused]] const auto N = etl::size(a) / etl::size(lhs);
        const auto K = etl::size(lhs);

        using T = value_t<A>;

        check(a, lhs);

        auto batch_fun_k = [&](const size_t first, const size_t last) {
            for (size_t k = first; k < last; ++k) {
                T mean(0);

                for (size_t b = 0; b < etl::dim<0>(a); ++b) {
                    mean += sum(a(b)(k));
                }

                if constexpr (Mean) {
                    lhs(k) %= mean / N;
                } else {
                    lhs(k) %= mean;
                }
            }
        };

        engine_dispatch_1d_serial(batch_fun_k, 0, K, 2UL);
    }

    /*!
     * \brief Print a representation of the expression on the given stream
     * \param os The output stream
     * \param expr The expression to print
     * \return the output stream
     */
    friend std::ostream& operator<<(std::ostream& os, const bias_batch_mean_4d_expr& expr) {
        if (Mean) {
            return os << "bias_batch_mean_4d(" << expr._a << ")";
        } else {
            return os << "bias_batch_sum_4d(" << expr._a << ")";
        }
    }
};

/*!
 * \brief Traits for a transpose expression
 * \tparam A The transposed sub type
 */
template <typename A, bool Mean>
struct etl_traits<etl::bias_batch_mean_4d_expr<A, Mean>> {
    using expr_t     = etl::bias_batch_mean_4d_expr<A, Mean>; ///< The expression type
    using sub_expr_t = std::decay_t<A>;                       ///< The sub expression type
    using sub_traits = etl_traits<sub_expr_t>;                ///< The sub traits
    using value_type = value_t<A>;                            ///< The value type of the expression

    static constexpr bool is_etl         = true;                                 ///< Indicates if the type is an ETL expression
    static constexpr bool is_transformer = false;                                ///< Indicates if the type is a transformer
    static constexpr bool is_view        = false;                                ///< Indicates if the type is a view
    static constexpr bool is_magic_view  = false;                                ///< Indicates if the type is a magic view
    static constexpr bool is_fast        = sub_traits::is_fast;                  ///< Indicates if the expression is fast
    static constexpr bool is_linear      = false;                                ///< Indicates if the expression is linear
    static constexpr bool is_thread_safe = true;                                 ///< Indicates if the expression is thread safe
    static constexpr bool is_value       = false;                                ///< Indicates if the expression is of value type
    static constexpr bool is_direct      = true;                                 ///< Indicates if the expression has direct memory access
    static constexpr bool is_generator   = false;                                ///< Indicates if the expression is a generator
    static constexpr bool is_padded      = false;                                ///< Indicates if the expression is padded
    static constexpr bool is_aligned     = true;                                 ///< Indicates if the expression is padded
    static constexpr bool is_temporary   = true;                                 ///< Indicates if the expression needs a evaluator visitor
    static constexpr bool gpu_computable = is_gpu_t<value_type> && cuda_enabled; ///< Indicates if the expression can be computed on GPU
    static constexpr order storage_order = sub_traits::storage_order;            ///< The expression's storage order

    /*!
     * \brief Indicates if the expression is vectorizable using the
     * given vector mode
     * \tparam V The vector mode
     */
    template <vector_mode_t V>
    static constexpr bool vectorizable = true;

    /*!
     * \brief Returns the DDth dimension of the expression
     * \return the DDth dimension of the expression
     */
    template <size_t DD>
    static constexpr size_t dim() {
        static_assert(DD == 0, "Invalid dimensions access");
        return decay_traits<A>::template dim<1>();
    }

    /*!
     * \brief Returns the dth dimension of the expression
     * \param e The sub expression
     * \param d The dimension to get
     * \return the dth dimension of the expression
     */
    static size_t dim(const expr_t& e, size_t d) {
        cpp_assert(d == 0, "Invalid dimensions access");
        cpp_unused(d);
        return etl::dim<1>(e._a);
    }

    /*!
     * \brief Returns the size of the expression
     * \param e The sub expression
     * \return the size of the expression
     */
    static size_t size(const expr_t& e) {
        return etl::dim<1>(e._a);
    }

    /*!
     * \brief Returns the size of the expression
     * \return the size of the expression
     */
    static constexpr size_t size() {
        return decay_traits<A>::template dim<1>();
    }

    /*!
     * \brief Returns the number of dimensions of the expression
     * \return the number of dimensions of the expression
     */
    static constexpr size_t dimensions() {
        return 1;
    }
};

/*!
 * \brief Returns the transpose of the given expression.
 * \param value The expression
 * \return The transpose of the given expression.
 */
template <typename E>
bias_batch_mean_4d_expr<detail::build_type<E>, true> bias_batch_mean_4d(const E& value) {
    static_assert(is_etl_expr<E>, "etl::bias_batch_mean_4d can only be used on ETL expressions");
    static_assert(is_4d<E>, "etl::bias_batch_mean_4d is only defined for 4D input");

    return bias_batch_mean_4d_expr<detail::build_type<E>, true>{value};
}

/*!
 * \brief Returns the transpose of the given expression.
 * \param value The expression
 * \return The transpose of the given expression.
 */
template <typename E>
bias_batch_mean_4d_expr<detail::build_type<E>, false> bias_batch_sum_4d(const E& value) {
    static_assert(is_etl_expr<E>, "etl::bias_batch_sum_4d can only be used on ETL expressions");
    static_assert(is_4d<E>, "etl::bias_batch_sum_4d is only defined for 4D input");

    return bias_batch_mean_4d_expr<detail::build_type<E>, false>{value};
}

} //end of namespace etl
<|endoftext|>


<commit_before>// Nonius - C++ benchmarking tool
//
// Written in 2014 by Martinho Fernandes <martinho.fernandes@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>

// Dumb std::function implementation for consistent call overhead

#ifndef NONIUS_DETAIL_BENCHMARK_FUNCTION_HPP
#define NONIUS_DETAIL_BENCHMARK_FUNCTION_HPP

#include <nonius/chronometer.h++>
#include <nonius/detail/complete_invoke.h++>

#include <type_traits>
#include <utility>
#include <memory>

namespace nonius {
    namespace detail {
        template <typename T>
        using Decay = typename std::decay<T>::type;
        template <typename T, typename U>
        struct is_related
        : std::is_same<Decay<T>, Decay<U>> {};

        struct benchmark_function {
        private:
            struct concept {
                virtual void call(chronometer meter) const = 0;
                virtual concept* clone() const = 0;
                virtual ~concept() = default;
            };
            template <typename Fun>
            struct model : public concept {
                model(Fun&& fun) : fun(std::move(fun)) {}
                model(Fun const& fun) : fun(fun) {}

                model<Fun>* clone() const override { return new model<Fun>(*this); }

                void call(chronometer meter) const override {
                    call(meter, is_callable<Fun(chronometer)>());
                }
                void call(chronometer meter, std::true_type) const {
                    fun(meter);
                }
                void call(chronometer meter, std::false_type) const {
                    meter.measure(fun);
                }

                Fun fun;
            };
        public:
            template <typename Fun,
                      typename std::enable_if<!is_related<Fun, benchmark_function>::value, int>::type = 0>
            benchmark_function(Fun&& fun)
            : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {}

            benchmark_function(benchmark_function&& that)
            : f(std::move(that.f)) {}

            benchmark_function(benchmark_function const& that)
            : f(that.f->clone()) {}

            void operator()(chronometer meter) const { f->call(meter); }
        private:
            std::unique_ptr<concept> f;
        };
    } // namespace detail
} // namespace nonius

#endif // NONIUS_DETAIL_BENCHMARK_FUNCTION_HPP

<commit_msg>Add missing op=<commit_after>// Nonius - C++ benchmarking tool
//
// Written in 2014 by Martinho Fernandes <martinho.fernandes@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>

// Dumb std::function implementation for consistent call overhead

#ifndef NONIUS_DETAIL_BENCHMARK_FUNCTION_HPP
#define NONIUS_DETAIL_BENCHMARK_FUNCTION_HPP

#include <nonius/chronometer.h++>
#include <nonius/detail/complete_invoke.h++>

#include <type_traits>
#include <utility>
#include <memory>

namespace nonius {
    namespace detail {
        template <typename T>
        using Decay = typename std::decay<T>::type;
        template <typename T, typename U>
        struct is_related
        : std::is_same<Decay<T>, Decay<U>> {};

        struct benchmark_function {
        private:
            struct concept {
                virtual void call(chronometer meter) const = 0;
                virtual concept* clone() const = 0;
                virtual ~concept() = default;
            };
            template <typename Fun>
            struct model : public concept {
                model(Fun&& fun) : fun(std::move(fun)) {}
                model(Fun const& fun) : fun(fun) {}

                model<Fun>* clone() const override { return new model<Fun>(*this); }

                void call(chronometer meter) const override {
                    call(meter, is_callable<Fun(chronometer)>());
                }
                void call(chronometer meter, std::true_type) const {
                    fun(meter);
                }
                void call(chronometer meter, std::false_type) const {
                    meter.measure(fun);
                }

                Fun fun;
            };
        public:
            template <typename Fun,
                      typename std::enable_if<!is_related<Fun, benchmark_function>::value, int>::type = 0>
            benchmark_function(Fun&& fun)
            : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {}

            benchmark_function(benchmark_function&& that)
            : f(std::move(that.f)) {}

            benchmark_function(benchmark_function const& that)
            : f(that.f->clone()) {}

            benchmark_function& operator=(benchmark_function&& that) {
                f = std::move(that.f);
                return *this;
            }

            benchmark_function& operator=(benchmark_function const& that) {
                f.reset(that.f->clone());
                return *this;
            }

            void operator()(chronometer meter) const { f->call(meter); }
        private:
            std::unique_ptr<concept> f;
        };
    } // namespace detail
} // namespace nonius

#endif // NONIUS_DETAIL_BENCHMARK_FUNCTION_HPP

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: modsizeexceeded.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2007-01-29 15:06:18 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basic.hxx"
#include "modsizeexceeded.hxx"

#include <framework/interaction.hxx>
#include <com/sun/star/script/ModuleSizeExceededRequest.hpp>

using namespace com::sun::star;
using namespace cppu;
using namespace rtl;
using namespace osl;

ModuleSizeExceeded::ModuleSizeExceeded( const uno::Sequence< ::rtl::OUString >& sModules )
{
    script::ModuleSizeExceededRequest aReq;
    aReq.Names = sModules;

    m_aRequest <<= aReq;

    m_xAbort.set( uno::Reference< task::XInteractionAbort >(new framework::ContinuationAbort), uno::UNO_QUERY );
    m_xApprove.set( uno::Reference< task::XInteractionApprove >(new framework::ContinuationApprove ), uno::UNO_QUERY );
    m_lContinuations.realloc( 2 );
    m_lContinuations[0] =  m_xApprove;
    m_lContinuations[1] = m_xAbort;
}

sal_Bool
ModuleSizeExceeded::isAbort() const
{
    framework::ContinuationAbort* pBase = static_cast< framework::ContinuationAbort* >( m_xAbort.get() );
    return pBase->isSelected();
}

sal_Bool
ModuleSizeExceeded::isApprove() const
{
    framework::ContinuationApprove* pBase = static_cast< framework::ContinuationApprove* >( m_xApprove.get() );
    return pBase->isSelected();
}

<commit_msg>INTEGRATION: CWS changefileheader (1.2.112); FILE MERGED 2008/03/28 16:07:51 rt 1.2.112.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: modsizeexceeded.cxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basic.hxx"
#include "modsizeexceeded.hxx"

#include <framework/interaction.hxx>
#include <com/sun/star/script/ModuleSizeExceededRequest.hpp>

using namespace com::sun::star;
using namespace cppu;
using namespace rtl;
using namespace osl;

ModuleSizeExceeded::ModuleSizeExceeded( const uno::Sequence< ::rtl::OUString >& sModules )
{
    script::ModuleSizeExceededRequest aReq;
    aReq.Names = sModules;

    m_aRequest <<= aReq;

    m_xAbort.set( uno::Reference< task::XInteractionAbort >(new framework::ContinuationAbort), uno::UNO_QUERY );
    m_xApprove.set( uno::Reference< task::XInteractionApprove >(new framework::ContinuationApprove ), uno::UNO_QUERY );
    m_lContinuations.realloc( 2 );
    m_lContinuations[0] =  m_xApprove;
    m_lContinuations[1] = m_xAbort;
}

sal_Bool
ModuleSizeExceeded::isAbort() const
{
    framework::ContinuationAbort* pBase = static_cast< framework::ContinuationAbort* >( m_xAbort.get() );
    return pBase->isSelected();
}

sal_Bool
ModuleSizeExceeded::isApprove() const
{
    framework::ContinuationApprove* pBase = static_cast< framework::ContinuationApprove* >( m_xApprove.get() );
    return pBase->isSelected();
}

<|endoftext|>


<commit_before>// Virvo - Virtual Reality Volume Rendering
// Copyright (C) 1999-2003 University of Stuttgart, 2004-2005 Brown University
// Contact: Jurgen P. Schulze, jschulze@ucsd.edu
//
// This file is part of Virvo.
//
// Virvo is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library (see license.txt); if not, write to the
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

#include <iostream>

#include <string.h>
#include "vvopengl.h"
#include "vvdebugmsg.h"

#ifdef VV_DEBUG_MEMORY
#include <crtdbg.h>
#define new new(_NORMAL_BLOCK,__FILE__, __LINE__)
#endif

#include "vvgltools.h"

using namespace std;

//============================================================================
// Method Definitions
//============================================================================

//----------------------------------------------------------------------------
/** Check OpenGL for errors.
    @param  error string if there was an error, otherwise return NULL
*/
void vvGLTools::printGLError(const char* msg)
{
  const GLenum err = glGetError();
  if(err != GL_NO_ERROR)
  {
    const char* str = (const char*)gluErrorString(err);
    cerr << "GL error: " << msg << ", " << str << endl;
  }
}

vvGLTools::GLInfo vvGLTools::getGLInfo()
{
  GLInfo result;

  result.vendor = (const char*)glGetString(GL_VENDOR);
  result.renderer = (const char*)glGetString(GL_RENDERER);
  result.version = (const char*)glGetString(GL_VERSION);

  return result;
}

//----------------------------------------------------------------------------
/** Checks OpenGL for a specific OpenGL version.
    @param major OpenGL major version to check
    @param minor OpenGL minor version to check
    @param release OpenGL release version to check
    @return true if version is supported
*/
bool vvGLTools::isGLVersionSupported(int major, int minor, int release)
{
  (void)release;
  // Get version string from OpenGL:
  const GLubyte* verstring = glGetString(GL_VERSION);
  if (verstring=='\0') return false;

  int ver[3] = { 0, 0, 0 };
  int idx = 0;
  for (const GLubyte *p = verstring;
      *p && *p != ' ' && idx < 3;
      ++p)
  {
    if (*p == '.')
    {
      ++idx;
    }
    else if (*p >= '0' && *p <= '9')
    {
      ver[idx] *= 10;
      ver[idx] += *p-'0';
    }
    else
      return false;
  }

  vvDebugMsg::msg(3, "GL version ", ver[0], ver[1], ver[2]);

  if(ver[0] < major)
    return false;
  if(ver[0] > major)
    return true;

  if(ver[1] < minor)
    return false;
  if(ver[1] >= minor)
    return true;

  return false;
}

//----------------------------------------------------------------------------
/** Checks OpenGL for a specific extension.
    @param extension OpenGL extension to check for (e.g. "GL_EXT_bgra")
    @return true if extension is supported
*/
bool vvGLTools::isGLextensionSupported(const char* extension)
{
  // Check requested extension name for existence and for spaces:
  const GLubyte* where = (GLubyte*)strchr(extension, ' ');
  if (where || *extension=='\0') return false;

  // Get extensions string from OpenGL:
  const GLubyte* extensions = glGetString(GL_EXTENSIONS);
  if (extensions=='\0') return false;

  // Parse OpenGL extensions string:
  const GLubyte* start = extensions;
  for (;;)
  {
    where = (GLubyte*)strstr((const char*)start, extension);
    if (!where) return false;
    const GLubyte* terminator = where + strlen(extension);
    if (where==start || *(where - 1)==' ')
      if (*terminator==' ' || *terminator=='\0')
        return true;
    start = terminator;
  }
}

//----------------------------------------------------------------------------
/** Display the OpenGL extensions which are supported by the system at
  run time.
  @param style display style
*/
void vvGLTools::displayOpenGLextensions(const DisplayStyle style)
{
  char* extCopy;                                  // local copy of extensions string for modifications

  const char* extensions = (const char*)glGetString(GL_EXTENSIONS);

  switch (style)
  {
    default:
    case CONSECUTIVE:
      cerr << extensions << endl;
      break;
    case ONE_BY_ONE:
      extCopy = new char[strlen(extensions) + 1];
      strcpy(extCopy, extensions);
      for (int i=0; i<(int)strlen(extCopy); ++i)
        if (extCopy[i] == ' ') extCopy[i] = '\n';
      cerr << extCopy << endl;
      delete[] extCopy;
      break;
  }
}

//----------------------------------------------------------------------------
/** Check for some specific OpenGL extensions.
  Displays the status of volume rendering related extensions, each on a separate line.
*/
void vvGLTools::checkOpenGLextensions()
{
  const char* status[2] = {"supported", "not found"};

  cerr << "GL_EXT_texture3D...............";
  cerr << ((vvGLTools::isGLextensionSupported("GL_EXT_texture3D")) ? status[0] : status[1]) << endl;

  cerr << "GL_EXT_texture_edge_clamp......";
  cerr << ((vvGLTools::isGLextensionSupported("GL_EXT_texture_edge_clamp")) ? status[0] : status[1]) << endl;

  cerr << "GL_SGI_texture_color_table.....";
  cerr << ((vvGLTools::isGLextensionSupported("GL_SGI_texture_color_table")) ? status[0] : status[1]) << endl;

  cerr << "GL_EXT_paletted_texture........";
  cerr << ((vvGLTools::isGLextensionSupported("GL_EXT_paletted_texture")) ? status[0] : status[1]) << endl;

  cerr << "GL_EXT_blend_equation..........";
  cerr << ((vvGLTools::isGLextensionSupported("GL_EXT_blend_equation")) ? status[0] : status[1]) << endl;

  cerr << "GL_EXT_shared_texture_palette..";
  cerr << ((vvGLTools::isGLextensionSupported("GL_EXT_shared_texture_palette")) ? status[0] : status[1]) << endl;

  cerr << "GL_EXT_blend_minmax............";
  cerr << ((vvGLTools::isGLextensionSupported("GL_EXT_blend_minmax")) ? status[0] : status[1]) << endl;

  cerr << "GL_ARB_multitexture............";
  cerr << ((vvGLTools::isGLextensionSupported("GL_ARB_multitexture")) ? status[0] : status[1]) << endl;

  cerr << "GL_NV_texture_shader...........";
  cerr << ((vvGLTools::isGLextensionSupported("GL_NV_texture_shader")) ? status[0] : status[1]) << endl;

  cerr << "GL_NV_texture_shader2..........";
  cerr << ((vvGLTools::isGLextensionSupported("GL_NV_texture_shader2")) ? status[0] : status[1]) << endl;

  cerr << "GL_NV_texture_shader3..........";
  cerr << ((vvGLTools::isGLextensionSupported("GL_NV_texture_shader3")) ? status[0] : status[1]) << endl;

  cerr << "GL_ARB_texture_env_combine.....";
  cerr << ((vvGLTools::isGLextensionSupported("GL_ARB_texture_env_combine")) ? status[0] : status[1]) << endl;

  cerr << "GL_NV_register_combiners.......";
  cerr << ((vvGLTools::isGLextensionSupported("GL_NV_register_combiners")) ? status[0] : status[1]) << endl;

  cerr << "GL_NV_register_combiners2......";
  cerr << ((vvGLTools::isGLextensionSupported("GL_NV_register_combiners2")) ? status[0] : status[1]) << endl;

  cerr << "GL_ARB_fragment_program........";
  cerr << ((vvGLTools::isGLextensionSupported("GL_ARB_fragment_program")) ? status[0] : status[1]) << endl;

  cerr << "GL_ATI_fragment_shader.........";
  cerr << ((vvGLTools::isGLextensionSupported("GL_ATI_fragment_shader")) ? status[0] : status[1]) << endl;

  cerr << "GL_ARB_imaging.................";
  cerr << ((vvGLTools::isGLextensionSupported("GL_ARB_imaging")) ? status[0] : status[1]) << endl;
}

//----------------------------------------------------------------------------
/** Draw view aligned quad. If no vertex coordinates are specified,
    these default to: (-1.0f, -1.0f) (1.0f, 1.0f). No multi texture coordinates
    supported.
*/
void vvGLTools::drawViewAlignedQuad(const float x1, const float y1,
                                    const float x2, const float y2)
{
  glBegin(GL_QUADS);
    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
    glNormal3f(0.0f, 0.0f, 1.0f);

    glTexCoord2f(0.0f, 0.0f);
    glVertex2f(x1, y1);

    glTexCoord2f(1.0f, 0.0f);
    glVertex2f(x2, y1);

    glTexCoord2f(1.0f, 1.0f);
    glVertex2f(x2, y2);

    glTexCoord2f(0.0f, 1.0f);
    glVertex2f(x1, y2);
  glEnd();
}

//----------------------------------------------------------------------------
/** Get OpenGL viewport info: 0 ==> x, 1 ==> y, 2 ==> width, 3 ==> height.
*/
vvGLTools::Viewport vvGLTools::getViewport()
{
  Viewport result;
  glGetIntegerv(GL_VIEWPORT, result.values);
  return result;
}

//----------------------------------------------------------------------------
/** Query the color specificied using glClearColor (rgba)
*/
vvVector4 vvGLTools::queryClearColor()
{
  vvVector4 result;
  glGetFloatv(GL_COLOR_CLEAR_VALUE, result.e);
  return result;
}

//----------------------------------------------------------------------------
/** Get the current modelview matrix.
  @param a matrix which will be set to the current modelview matrix
*/
void vvGLTools::getModelviewMatrix(vvMatrix* mv)
{
  GLfloat glmatrix[16];                           // OpenGL compatible matrix

  vvDebugMsg::msg(3, "vvRenderer::getModelviewMatrix()");
  glGetFloatv(GL_MODELVIEW_MATRIX, glmatrix);
  mv->getGL((float*)glmatrix);
}

//----------------------------------------------------------------------------
/** Get the current projection matrix.
  @param a matrix which will be set to the current projection matrix
*/
void vvGLTools::getProjectionMatrix(vvMatrix* pm)
{
  vvDebugMsg::msg(3, "vvRenderer::getProjectionMatrix()");

  GLfloat glmatrix[16];                           // OpenGL compatible matrix
  glGetFloatv(GL_PROJECTION_MATRIX, glmatrix);
  pm->getGL((float*)glmatrix);
}

//----------------------------------------------------------------------------
/** Set the OpenGL modelview matrix.
  @param new OpenGL modelview matrix
*/
void vvGLTools::setModelviewMatrix(const vvMatrix* mv)
{
  vvDebugMsg::msg(3, "vvRenderer::setModelviewMatrix()");

  GLfloat glmatrix[16];                           // OpenGL compatible matrix
  mv->makeGL((float*)glmatrix);
  glMatrixMode(GL_MODELVIEW);
  glLoadMatrixf(glmatrix);
}

//----------------------------------------------------------------------------
/** Set the OpenGL projection matrix.
  @param new OpenGL projection matrix
*/
void vvGLTools::setProjectionMatrix(const vvMatrix* pm)
{
  vvDebugMsg::msg(3, "vvRenderer::setProjectionMatrix()");

  GLfloat glmatrix[16];                           // OpenGL compatible matrix
  pm->makeGL((float*)glmatrix);
  glMatrixMode(GL_PROJECTION);
  glLoadMatrixf(glmatrix);
  glMatrixMode(GL_MODELVIEW);
}

//============================================================================
// End of File
//============================================================================
<commit_msg>Minor change.<commit_after>// Virvo - Virtual Reality Volume Rendering
// Copyright (C) 1999-2003 University of Stuttgart, 2004-2005 Brown University
// Contact: Jurgen P. Schulze, jschulze@ucsd.edu
//
// This file is part of Virvo.
//
// Virvo is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library (see license.txt); if not, write to the
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

#include <iostream>

#include <string.h>
#include "vvopengl.h"
#include "vvdebugmsg.h"

#ifdef VV_DEBUG_MEMORY
#include <crtdbg.h>
#define new new(_NORMAL_BLOCK,__FILE__, __LINE__)
#endif

#include "vvgltools.h"

using namespace std;

//============================================================================
// Method Definitions
//============================================================================

//----------------------------------------------------------------------------
/** Check OpenGL for errors.
    @param  error string if there was an error, otherwise return NULL
*/
void vvGLTools::printGLError(const char* msg)
{
  const GLenum err = glGetError();
  if(err != GL_NO_ERROR)
  {
    const char* str = (const char*)gluErrorString(err);
    cerr << "GL error: " << msg << ", " << str << endl;
  }
}

vvGLTools::GLInfo vvGLTools::getGLInfo()
{
  GLInfo result;

  result.vendor = (const char*)glGetString(GL_VENDOR);
  result.renderer = (const char*)glGetString(GL_RENDERER);
  result.version = (const char*)glGetString(GL_VERSION);

  return result;
}

//----------------------------------------------------------------------------
/** Checks OpenGL for a specific OpenGL version.
    @param major OpenGL major version to check
    @param minor OpenGL minor version to check
    @param release OpenGL release version to check
    @return true if version is supported
*/
bool vvGLTools::isGLVersionSupported(int major, int minor, int release)
{
  (void)release;
  // Get version string from OpenGL:
  const GLubyte* verstring = glGetString(GL_VERSION);
  if (verstring=='\0') return false;

  int ver[3] = { 0, 0, 0 };
  int idx = 0;
  for (const GLubyte *p = verstring;
      *p && *p != ' ' && idx < 3;
      ++p)
  {
    if (*p == '.')
    {
      ++idx;
    }
    else if (*p >= '0' && *p <= '9')
    {
      ver[idx] *= 10;
      ver[idx] += *p-'0';
    }
    else
      return false;
  }

  vvDebugMsg::msg(3, "GL version ", ver[0], ver[1], ver[2]);

  if(ver[0] < major)
    return false;
  if(ver[0] > major)
    return true;

  if(ver[1] < minor)
    return false;
  if(ver[1] >= minor)
    return true;

  return false;
}

//----------------------------------------------------------------------------
/** Checks OpenGL for a specific extension.
    @param extension OpenGL extension to check for (e.g. "GL_EXT_bgra")
    @return true if extension is supported
*/
bool vvGLTools::isGLextensionSupported(const char* extension)
{
  // Check requested extension name for existence and for spaces:
  const GLubyte* where = (GLubyte*)strchr(extension, ' ');
  if (where || *extension=='\0') return false;

  // Get extensions string from OpenGL:
  const GLubyte* extensions = glGetString(GL_EXTENSIONS);
  if (extensions=='\0') return false;

  // Parse OpenGL extensions string:
  const GLubyte* start = extensions;
  for (;;)
  {
    where = (GLubyte*)strstr((const char*)start, extension);
    if (!where) return false;
    const GLubyte* terminator = where + strlen(extension);
    if (where==start || *(where - 1)==' ')
      if (*terminator==' ' || *terminator=='\0')
        return true;
    start = terminator;
  }
}

//----------------------------------------------------------------------------
/** Display the OpenGL extensions which are supported by the system at
  run time.
  @param style display style
*/
void vvGLTools::displayOpenGLextensions(const DisplayStyle style)
{
  char* extCopy;                                  // local copy of extensions string for modifications

  const char* extensions = (const char*)glGetString(GL_EXTENSIONS);

  switch (style)
  {
    default:
    case CONSECUTIVE:
      cerr << extensions << endl;
      break;
    case ONE_BY_ONE:
      extCopy = new char[strlen(extensions) + 1];
      strcpy(extCopy, extensions);
      for (int i=0; i<(int)strlen(extCopy); ++i)
        if (extCopy[i] == ' ') extCopy[i] = '\n';
      cerr << extCopy << endl;
      delete[] extCopy;
      break;
  }
}

//----------------------------------------------------------------------------
/** Check for some specific OpenGL extensions.
  Displays the status of volume rendering related extensions, each on a separate line.
*/
void vvGLTools::checkOpenGLextensions()
{
  const char* status[2] = {"supported", "not found"};

  cerr << "GL_EXT_texture3D...............";
  cerr << ((vvGLTools::isGLextensionSupported("GL_EXT_texture3D")) ? status[0] : status[1]) << endl;

  cerr << "GL_EXT_texture_edge_clamp......";
  cerr << ((vvGLTools::isGLextensionSupported("GL_EXT_texture_edge_clamp")) ? status[0] : status[1]) << endl;

  cerr << "GL_SGI_texture_color_table.....";
  cerr << ((vvGLTools::isGLextensionSupported("GL_SGI_texture_color_table")) ? status[0] : status[1]) << endl;

  cerr << "GL_EXT_paletted_texture........";
  cerr << ((vvGLTools::isGLextensionSupported("GL_EXT_paletted_texture")) ? status[0] : status[1]) << endl;

  cerr << "GL_EXT_blend_equation..........";
  cerr << ((vvGLTools::isGLextensionSupported("GL_EXT_blend_equation")) ? status[0] : status[1]) << endl;

  cerr << "GL_EXT_shared_texture_palette..";
  cerr << ((vvGLTools::isGLextensionSupported("GL_EXT_shared_texture_palette")) ? status[0] : status[1]) << endl;

  cerr << "GL_EXT_blend_minmax............";
  cerr << ((vvGLTools::isGLextensionSupported("GL_EXT_blend_minmax")) ? status[0] : status[1]) << endl;

  cerr << "GL_ARB_multitexture............";
  cerr << ((vvGLTools::isGLextensionSupported("GL_ARB_multitexture")) ? status[0] : status[1]) << endl;

  cerr << "GL_NV_texture_shader...........";
  cerr << ((vvGLTools::isGLextensionSupported("GL_NV_texture_shader")) ? status[0] : status[1]) << endl;

  cerr << "GL_NV_texture_shader2..........";
  cerr << ((vvGLTools::isGLextensionSupported("GL_NV_texture_shader2")) ? status[0] : status[1]) << endl;

  cerr << "GL_NV_texture_shader3..........";
  cerr << ((vvGLTools::isGLextensionSupported("GL_NV_texture_shader3")) ? status[0] : status[1]) << endl;

  cerr << "GL_ARB_texture_env_combine.....";
  cerr << ((vvGLTools::isGLextensionSupported("GL_ARB_texture_env_combine")) ? status[0] : status[1]) << endl;

  cerr << "GL_NV_register_combiners.......";
  cerr << ((vvGLTools::isGLextensionSupported("GL_NV_register_combiners")) ? status[0] : status[1]) << endl;

  cerr << "GL_NV_register_combiners2......";
  cerr << ((vvGLTools::isGLextensionSupported("GL_NV_register_combiners2")) ? status[0] : status[1]) << endl;

  cerr << "GL_ARB_fragment_program........";
  cerr << ((vvGLTools::isGLextensionSupported("GL_ARB_fragment_program")) ? status[0] : status[1]) << endl;

  cerr << "GL_ATI_fragment_shader.........";
  cerr << ((vvGLTools::isGLextensionSupported("GL_ATI_fragment_shader")) ? status[0] : status[1]) << endl;

  cerr << "GL_ARB_imaging.................";
  cerr << ((vvGLTools::isGLextensionSupported("GL_ARB_imaging")) ? status[0] : status[1]) << endl;
}

//----------------------------------------------------------------------------
/** Draw view aligned quad. If no vertex coordinates are specified,
    these default to: (-1.0f, -1.0f) (1.0f, 1.0f). No multi texture coordinates
    supported.
*/
void vvGLTools::drawViewAlignedQuad(const float x1, const float y1,
                                    const float x2, const float y2)
{
  glBegin(GL_QUADS);
    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
    glNormal3f(0.0f, 0.0f, 1.0f);

    glTexCoord2f(0.0f, 0.0f);
    glVertex2f(x1, y1);

    glTexCoord2f(1.0f, 0.0f);
    glVertex2f(x2, y1);

    glTexCoord2f(1.0f, 1.0f);
    glVertex2f(x2, y2);

    glTexCoord2f(0.0f, 1.0f);
    glVertex2f(x1, y2);
  glEnd();
}

//----------------------------------------------------------------------------
/** Get OpenGL viewport info: 0 ==> x, 1 ==> y, 2 ==> width, 3 ==> height.
*/
vvGLTools::Viewport vvGLTools::getViewport()
{
  Viewport result;
  glGetIntegerv(GL_VIEWPORT, result.values);
  return result;
}

//----------------------------------------------------------------------------
/** Query the color specificied using glClearColor (rgba)
*/
vvVector4 vvGLTools::queryClearColor()
{
  vvVector4 result;
  glGetFloatv(GL_COLOR_CLEAR_VALUE, result.e);
  return result;
}

//----------------------------------------------------------------------------
/** Get the current modelview matrix.
  @param a matrix which will be set to the current modelview matrix
*/
void vvGLTools::getModelviewMatrix(vvMatrix* mv)
{
  GLfloat glmatrix[16];                           // OpenGL compatible matrix

  vvDebugMsg::msg(3, "vvRenderer::getModelviewMatrix()");
  glGetFloatv(GL_MODELVIEW_MATRIX, glmatrix);
  mv->getGL((float*)glmatrix);
}

//----------------------------------------------------------------------------
/** Get the current projection matrix.
  @param a matrix which will be set to the current projection matrix
*/
void vvGLTools::getProjectionMatrix(vvMatrix* pm)
{
  vvDebugMsg::msg(3, "vvRenderer::getProjectionMatrix()");

  GLfloat glmatrix[16];                           // OpenGL compatible matrix
  glGetFloatv(GL_PROJECTION_MATRIX, glmatrix);
  pm->getGL((float*)glmatrix);
}

//----------------------------------------------------------------------------
/** Set the OpenGL modelview matrix.
    Adjusts the opengl matrix mode to GL_MODELVIEW.
  @param new OpenGL modelview matrix
*/
void vvGLTools::setModelviewMatrix(const vvMatrix* mv)
{
  vvDebugMsg::msg(3, "vvRenderer::setModelviewMatrix()");

  GLfloat glmatrix[16];                           // OpenGL compatible matrix
  mv->makeGL((float*)glmatrix);
  glMatrixMode(GL_MODELVIEW);
  glLoadMatrixf(glmatrix);
}

//----------------------------------------------------------------------------
/** Set the OpenGL projection matrix.
    Adjusts the opengl matrix mode to GL_PROJECTION.
  @param new OpenGL projection matrix
*/
void vvGLTools::setProjectionMatrix(const vvMatrix* pm)
{
  vvDebugMsg::msg(3, "vvRenderer::setProjectionMatrix()");

  GLfloat glmatrix[16];                           // OpenGL compatible matrix
  pm->makeGL((float*)glmatrix);
  glMatrixMode(GL_PROJECTION);
  glLoadMatrixf(glmatrix);
}

//============================================================================
// End of File
//============================================================================
<|endoftext|>


<commit_before>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python.hpp>
#include <libtorrent/torrent_info.hpp>
#include "libtorrent/intrusive_ptr_base.hpp"

using namespace boost::python;
using namespace libtorrent;

namespace
{

  std::vector<announce_entry>::const_iterator begin_trackers(torrent_info& i)
  {
      return i.trackers().begin();
  }

  std::vector<announce_entry>::const_iterator end_trackers(torrent_info& i)
  {
      return i.trackers().end();
  }

  void add_node(torrent_info& ti, char const* hostname, int port)
  {
      ti.add_node(std::make_pair(hostname, port));
  }

  list nodes(torrent_info const& ti)
  {
      list result;

      typedef std::vector<std::pair<std::string, int> > list_type;

      for (list_type::const_iterator i = ti.nodes().begin(); i != ti.nodes().end(); ++i)
      {
          result.append(make_tuple(i->first, i->second));
      }

      return result;
  }

  std::vector<file_entry>::const_iterator begin_files(torrent_info& i, bool storage)
  {
      return i.begin_files(storage);
  }

  std::vector<file_entry>::const_iterator end_files(torrent_info& i, bool storage)
  {
      return i.end_files(storage);
  }

  //list files(torrent_info const& ti, bool storage) {
  list files(torrent_info const& ti, bool storage) {
      list result;

      typedef std::vector<file_entry> list_type;

      for (list_type::const_iterator i = ti.begin_files(storage); i != ti.end_files(storage); ++i)
          result.append(*i);

      return result;
  }

} // namespace unnamed

void bind_torrent_info()
{
    return_value_policy<copy_const_reference> copy;

    class_<torrent_info, boost::intrusive_ptr<torrent_info> >("torrent_info")
        .def(init<entry const&>())
        .def(init<sha1_hash const&>())

        .def("add_tracker", &torrent_info::add_tracker, (arg("url"), arg("tier")=0))
        .def("add_url_seed", &torrent_info::add_url_seed)

        .def("name", &torrent_info::name, copy)
        .def("comment", &torrent_info::comment, copy)
        .def("creator", &torrent_info::creator, copy)
        .def("total_size", &torrent_info::total_size)
        .def("piece_length", &torrent_info::piece_length)
        .def("num_pieces", &torrent_info::num_pieces)
        .def("info_hash", &torrent_info::info_hash, copy)

        .def("hash_for_piece", &torrent_info::hash_for_piece, copy)
        .def("piece_size", &torrent_info::piece_size)

        .def("num_files", &torrent_info::num_files, (arg("storage")=false))
        .def("file_at", &torrent_info::file_at, return_internal_reference<>())
        .def("files", &files, (arg("storage")=false))

        .def("priv", &torrent_info::priv)
        .def("trackers", range(begin_trackers, end_trackers))

        .def("creation_date", &torrent_info::creation_date)

        .def("add_node", &add_node)
        .def("nodes", &nodes)
        ;

    class_<file_entry>("file_entry")
       .add_property(
            "path"
          , make_getter(
                &file_entry::path, return_value_policy<copy_non_const_reference>()
            )
        )
        .def_readonly("offset", &file_entry::offset)
        .def_readonly("size", &file_entry::size)
        ;

    class_<announce_entry>("announce_entry", init<std::string const&>())
        .def_readwrite("url", &announce_entry::url)
        .def_readwrite("tier", &announce_entry::tier)
        ;
}

<commit_msg>boost python fix<commit_after>// Copyright Daniel Wallin 2006. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <boost/python.hpp>
#include <libtorrent/torrent_info.hpp>
#include "libtorrent/intrusive_ptr_base.hpp"

using namespace boost::python;
using namespace libtorrent;

namespace
{

  std::vector<announce_entry>::const_iterator begin_trackers(torrent_info& i)
  {
      return i.trackers().begin();
  }

  std::vector<announce_entry>::const_iterator end_trackers(torrent_info& i)
  {
      return i.trackers().end();
  }

  void add_node(torrent_info& ti, char const* hostname, int port)
  {
      ti.add_node(std::make_pair(hostname, port));
  }

  list nodes(torrent_info const& ti)
  {
      list result;

      typedef std::vector<std::pair<std::string, int> > list_type;

      for (list_type::const_iterator i = ti.nodes().begin(); i != ti.nodes().end(); ++i)
      {
          result.append(make_tuple(i->first, i->second));
      }

      return result;
  }

  std::vector<file_entry>::const_iterator begin_files(torrent_info& i, bool storage)
  {
      return i.begin_files(storage);
  }

  std::vector<file_entry>::const_iterator end_files(torrent_info& i, bool storage)
  {
      return i.end_files(storage);
  }

  //list files(torrent_info const& ti, bool storage) {
  list files(torrent_info const& ti, bool storage) {
      list result;

      typedef std::vector<file_entry> list_type;

      for (list_type::const_iterator i = ti.begin_files(storage); i != ti.end_files(storage); ++i)
          result.append(*i);

      return result;
  }

} // namespace unnamed

void bind_torrent_info()
{
    return_value_policy<copy_const_reference> copy;

    class_<torrent_info, boost::intrusive_ptr<torrent_info> >("torrent_info")
        .def(init<entry const&>())
        .def(init<sha1_hash const&>())

        .def("add_tracker", &torrent_info::add_tracker, (arg("url"), arg("tier")=0))
        .def("add_url_seed", &torrent_info::add_url_seed)

        .def("name", &torrent_info::name, copy)
        .def("comment", &torrent_info::comment, copy)
        .def("creator", &torrent_info::creator, copy)
        .def("total_size", &torrent_info::total_size)
        .def("piece_length", &torrent_info::piece_length)
        .def("num_pieces", &torrent_info::num_pieces)
        .def("info_hash", &torrent_info::info_hash, copy)

        .def("hash_for_piece", &torrent_info::hash_for_piece)
        .def("piece_size", &torrent_info::piece_size)

        .def("num_files", &torrent_info::num_files, (arg("storage")=false))
        .def("file_at", &torrent_info::file_at, return_internal_reference<>())
        .def("files", &files, (arg("storage")=false))

        .def("priv", &torrent_info::priv)
        .def("trackers", range(begin_trackers, end_trackers))

        .def("creation_date", &torrent_info::creation_date)

        .def("add_node", &add_node)
        .def("nodes", &nodes)
        ;

    class_<file_entry>("file_entry")
       .add_property(
            "path"
          , make_getter(
                &file_entry::path, return_value_policy<copy_non_const_reference>()
            )
        )
        .def_readonly("offset", &file_entry::offset)
        .def_readonly("size", &file_entry::size)
        ;

    class_<announce_entry>("announce_entry", init<std::string const&>())
        .def_readwrite("url", &announce_entry::url)
        .def_readwrite("tier", &announce_entry::tier)
        ;
}

<|endoftext|>