<commit_before>// @(#)root/reflex:$Id$
// Author: Stefan Roiser 2004

// Copyright CERN, CH-1211 Geneva 23, 2004-2006, All rights reserved.
//
// Permission to use, copy, modify, and distribute this software for any
// purpose is hereby granted without fee, provided that this copyright and
// permissions notice appear in all copies and derivatives.
//
// This software is provided "as is" without express or implied warranty.

#ifndef REFLEX_BUILD
# define REFLEX_BUILD
#endif

#include "FunctionMember.h"

#include "Reflex/Scope.h"
#include "Reflex/Object.h"
#include "Reflex/internal/OwnedMember.h"
#include "Reflex/DictionaryGenerator.h"

#include "Function.h"
#include "Reflex/Tools.h"

//-------------------------------------------------------------------------------
Reflex::FunctionMember::FunctionMember(const char* nam,
                                       const Type& typ,
                                       StubFunction stubFP,
                                       void* stubCtx,
                                       const char* parameters,
                                       unsigned int modifiers,
                                       TYPE memType)
//-------------------------------------------------------------------------------
   : MemberBase(nam, typ, memType, modifiers),
   fStubFP(stubFP),
   fStubCtx(stubCtx),
   fParameterNames(std::vector<std::string>()),
   fParameterDefaults(std::vector<std::string>()),
   fReqParameters(0) {
// Contruct a FunctionMember (see FunctionBuilder)
   UpdateFunctionParameterNames(parameters);
}

//-------------------------------------------------------------------------------
std::string
Reflex::FunctionMember::Name(unsigned int mod) const {
//-------------------------------------------------------------------------------
// Construct the qualified (if requested) name of the function member.
   std::string s;
   s.reserve(30); // an arbitrary, reasonable number

   if (0 != (mod & (QUALIFIED | Q))) {
      if (IsPublic()) {
         s += "public ";
      }

      if (IsProtected()) {
         s += "protected ";
      }

      if (IsPrivate()) {
         s += "private ";
      }

      if (IsExtern()) {
         s += "extern ";
      }

      if (IsStatic()) {
         s += "static ";
      }

      if (IsInline()) {
         s += "inline ";
      }

      if (IsVirtual()) {
         s += "virtual ";
      }

      if (IsExplicit()) {
         s += "explicit ";
      }
   }

   s += MemberBase::Name(mod);

   return s;
} // Name

/*/-------------------------------------------------------------------------------
   Reflex::Object
   Reflex::FunctionMember::Invoke( const Object & obj,
   const std::vector < Object > & paramList ) const {
   //-----------------------------------------------------------------------------
   if ( paramList.size() < FunctionParameterSize(true)) {
   throw RuntimeError("Not enough parameters given to function ");
   return Object();
   }
   void * mem = CalculateBaseObject( obj );
   std::vector < void * > paramValues;
   // needs more checking FIXME
   for (std::vector<Object>::const_iterator it = paramList.begin();
   it != paramList.end(); ++it ) paramValues.push_back(it->Address());
   return Object(TypeOf().ReturnType(), fStubFP( mem, paramValues, fStubCtx ));
   }
 */

//-------------------------------------------------------------------------------
void
Reflex::FunctionMember::Invoke(const Object& obj,
                               Object* ret,
                               const std::vector<void*>& paramList) const {
//-----------------------------------------------------------------------------
// Invoke this function member with object obj, return value (it it exists)
// goes into Object ret.
   if (paramList.size() < FunctionParameterSize(true)) {
      throw RuntimeError("Not enough parameters given to function ");
   }
   void* mem = CalculateBaseObject(obj);
   static Type tVoid = Type::ByName("void");
   void* retaddr = 0;

   if (ret && TypeOf().ReturnType() != tVoid) {
      retaddr = ret->Address();
   }
   // parameters need more checking FIXME
   fStubFP(retaddr, mem, paramList, fStubCtx);
} // Invoke

/*/-------------------------------------------------------------------------------
   Reflex::Object
   Reflex::FunctionMember::Invoke( const std::vector < Object > & paramList ) const {
   //-------------------------------------------------------------------------------
   std::vector < void * > paramValues;
   // needs more checking FIXME
   for (std::vector<Object>::const_iterator it = paramList.begin();
   it != paramList.end(); ++it ) paramValues.push_back(it->Address());
   return Object(TypeOf().ReturnType(), fStubFP( 0, paramValues, fStubCtx ));
   }
 */

//-------------------------------------------------------------------------------
void
Reflex::FunctionMember::Invoke(Object* ret,
                               const std::vector<void*>& paramList) const {
//-------------------------------------------------------------------------------
// Call static function, return value (it it exists) goes into Object ret.

   static Type tVoid = Type::ByName("void");
   void* retaddr = 0;

   if (ret && TypeOf().ReturnType() != tVoid) {
      retaddr = ret->Address();
   }
   // parameters need more checking FIXME
   fStubFP(retaddr, 0, paramList, fStubCtx);
}

//-------------------------------------------------------------------------------
size_t
Reflex::FunctionMember::FunctionParameterSize(bool required) const {
//-------------------------------------------------------------------------------
// Return number of function parameters. If required = true return number without default params.
   if (required) {
      return fReqParameters;
   } else { return TypeOf().FunctionParameterSize(); }
}

//-------------------------------------------------------------------------------
void
Reflex::FunctionMember::GenerateDict(DictionaryGenerator& generator) const {
//-------------------------------------------------------------------------------
// Generate Dictionary information about itself.

   std::string mName = Name();

   if (mName != "__getNewDelFunctions" && mName != "__getBasesTable") {
      // The return type
      const Type& retT = TypeOf().ReturnType();

      // Get function return type, register that to "used types"
      std::string returntype = generator.GetTypeNumber(TypeOf().ReturnType());

      // Prevents __getNewDelFunctions getting into AddFunctionMember twice
      //if(generator.IsNewType( TypeOf() ) && Name()!="__getNewDelFunctions" ) {

      if (IsPrivate()) {
         generator.AddIntoShadow(Name(SCOPED) + "();\n");
      }

      // Get a number for the function type
      //std::string number = generator.GetTypeNumber( TypeOf() );

      std::stringstream temp;
      temp << generator.fMethodCounter;
      std::string number = temp.str();

      ++generator.fMethodCounter;

      // Get current Namespace location
      std::string namespc = DeclaringScope().Name(SCOPED);

      std::stringstream tempcounter;
      tempcounter << generator.fMethodCounter;

      // Free function, shall be added into Instances-field only
      if (DeclaringScope().IsNamespace()) {
         generator.AddIntoInstances("      Type t" + tempcounter.str() + " = FunctionTypeBuilder(type_" + returntype);

      } else { // "normal" function, inside a class
         generator.AddIntoFree(".AddFunctionMember(FunctionTypeBuilder(type_" + returntype);
      }

      // Get the parameters for function
      for (Type_Iterator params = TypeOf().FunctionParameter_Begin();
           params != TypeOf().FunctionParameter_End(); ++params) {
         if (DeclaringScope().IsNamespace()) {
            generator.AddIntoInstances(", type_" + generator.GetTypeNumber((*params)));

         } else {
            generator.AddIntoFree(", type_" + generator.GetTypeNumber((*params)));
         }

      }

      if (DeclaringScope().IsNamespace()) {
         generator.AddIntoInstances(");  FunctionBuilder(t" + tempcounter.str() + ", \""
                                    + Name() + "\", function_" + number);  //function name
      } else { // normal function
         generator.AddIntoFree("), \"" + Name() + "\"");  //function name
      }

      if (IsConstructor()) {
         generator.AddIntoFree(", constructor_");
      } else if (IsDestructor()) {
         generator.AddIntoFree(", destructor_");
      }

      if (IsConstructor()) {
         generator.AddIntoClasses("static void* constructor_");

      } else if (IsDestructor()) {
         generator.AddIntoClasses("static void* destructor_");

      } else {
         if (!(DeclaringScope().IsNamespace())) {
            generator.AddIntoFree(", method_");

            generator.AddIntoClasses("\nstatic void* method_");

         } else {
            // free function
            generator.AddIntoClasses("\nstatic void* function_");
         }
      }

      if (!(DeclaringScope().IsNamespace())) {
         generator.AddIntoFree(number);                                     //method_n

      }
      generator.AddIntoClasses(number);

      if (IsConstructor()) {   // these have parameters
         generator.AddIntoClasses("(void* mem, const std::vector<void*>&");

         if (FunctionParameterSize()) {
            generator.AddIntoClasses(" arg");
         }

         generator.AddIntoClasses(", void*)\n{");
         generator.AddIntoClasses("\n  return ::new(mem) " + namespc);
         generator.AddIntoClasses("(");

      } //is constructor/destructor with parameters
      else if (IsDestructor()) {
         generator.AddIntoClasses("(void * o, const std::vector<void*>&, void *) {\n");
         generator.AddIntoClasses("  ((" + namespc + "*)o)->~" + DeclaringScope().Name() + "(");
      } else {
         // method function with parameters

         if (DeclaringScope().IsNamespace()) {
            generator.AddIntoClasses(" (void*, const std::vector<void*>&"); // arg, void*)\n{");

         } else {
            generator.AddIntoClasses(" (void* o, const std::vector<void*>&"); // arg, void*)\n{");
         }

         if (FunctionParameterSize() > 0) {
            generator.AddIntoClasses(" arg");
         }

         generator.AddIntoClasses(", void*)\n{");

         if (retT.Name() != "void") {
            if (retT.IsFundamental()) {
               generator.AddIntoClasses("static " + retT.Name(SCOPED) + " ret;\n");
               generator.AddIntoClasses("ret = ");
            } else if (retT.IsReference() || retT.IsPointer()) {
               generator.AddIntoClasses("return (void*)");

               if (retT.IsReference()) {
                  generator.AddIntoClasses("&");
               }
            } else { // compound type
               generator.AddIntoClasses("return new " + retT.Name(SCOPED) + "(");
            }
         }

         if (DeclaringScope().IsNamespace()) {
            generator.AddIntoClasses(Name() + "( ");

         } else {
            generator.AddIntoClasses("((" + namespc + "*)o)->" + Name() + "( ");
         }

      }

      // Add to Stub Functions with some parameters
      if (FunctionParameterSize() > 0) {
         unsigned args = 0;

         // Get all parameters
         for (Type_Iterator methpara = TypeOf().FunctionParameter_Begin();
              methpara != TypeOf().FunctionParameter_End(); ++methpara) {
            // get params for the function, can include pointers or references
            std::string param = generator.GetParams(*methpara);

            std::stringstream temp2;
            temp2 << args;

            // We de-deference parameter only, if it's not a pointer
            if (!methpara->IsPointer()) {
               generator.AddIntoClasses("*");
            }

            generator.AddIntoClasses("(");

            //if( methpara->IsConst()) generator.AddIntoClasses("const ");

            std::string paraT = methpara->Name(SCOPED | QUALIFIED);

            if (methpara->IsReference()) {
               paraT = paraT.substr(0, paraT.length() - 1);
            }

            generator.AddIntoClasses(paraT);

            if (!methpara->IsPointer()) {
               generator.AddIntoClasses("*");
            }

            generator.AddIntoClasses(") arg[" + temp2.str() + "]");

            //still parameters left
            if ((args + 1) < FunctionParameterSize()) {
               generator.AddIntoClasses(", ");
            }

            ++args;
            //fundam

         }

      } // funct. params!=0

      if (IsConstructor()) {
         generator.AddIntoClasses(");\n} \n");

      } else {
         generator.AddIntoClasses(")");

         if (retT.Name() == "void") {
            generator.AddIntoClasses(";\n  return 0;\n");
         } else if (retT.IsFundamental()) {
            generator.AddIntoClasses(";\n  return & ret;\n");
         } else if (retT.IsPointer() || retT.IsReference()) {
            generator.AddIntoClasses(";\n");
         } else { // compound type
            generator.AddIntoClasses(");\n");
         }

         generator.AddIntoClasses("\n} \n"); //);
      }

      if (DeclaringScope().IsNamespace()) {
         generator.AddIntoInstances(", 0");
      } else {
         generator.AddIntoFree(", 0");
      }

      if (DeclaringScope().IsNamespace()) {
         generator.AddIntoInstances(", \"");
      } else { generator.AddIntoFree(", \""); }

      // Get the names of the function param.types (like MyInt)
      if (TypeOf().FunctionParameterSize()) {
         unsigned dot = 0;
         Type_Iterator params;
         StdString_Iterator parnam;

         for (params = TypeOf().FunctionParameter_Begin(), parnam = FunctionParameterName_Begin();
              params != TypeOf().FunctionParameter_End(), parnam != FunctionParameterName_End();
              ++params, ++parnam) {
            // THESE SHOULD ALSO INCLUDE DEFAULT VALUES,
            // LIKE int i=5 FunctionParameterDefault_Begin(), _End
            //

            if (DeclaringScope().IsNamespace()) {
               generator.AddIntoInstances((*parnam));

               if ((dot + 1) < FunctionParameterSize()) {
                  generator.AddIntoInstances(";");
               }
            } else {
               generator.AddIntoFree((*parnam));

               if ((dot + 1) < FunctionParameterSize()) {
                  generator.AddIntoFree(";");
               }
            }
            ++dot;
         }

      }

      if (DeclaringScope().IsNamespace()) {
         generator.AddIntoInstances("\"");
      } else { generator.AddIntoFree("\""); }

      if (DeclaringScope().IsNamespace()) {  // free func
         generator.AddIntoInstances(", ");

         if (IsPublic()) {
            generator.AddIntoInstances("PUBLIC");
         } else if (IsPrivate()) {
            generator.AddIntoInstances("PRIVATE");
         } else if (IsProtected()) {
            generator.AddIntoInstances("PROTECTED");
         }

         if (IsArtificial()) {
            generator.AddIntoInstances(" | ARTIFICIAL");
         }

         generator.AddIntoInstances(");\n");

         ++generator.fMethodCounter;

      } else {
         generator.AddIntoFree(", ");

         if (IsPublic()) {
            generator.AddIntoFree("PUBLIC");
         } else if (IsPrivate()) {
            generator.AddIntoFree("PRIVATE");
         } else if (IsProtected()) {
            generator.AddIntoFree("PROTECTED");
         }

         if (IsVirtual()) {
            generator.AddIntoFree(" | VIRTUAL");
         }

         if (IsArtificial()) {
            generator.AddIntoFree(" | ARTIFICIAL");
         }

         if (IsConstructor()) {
            generator.AddIntoFree(" | CONSTRUCTOR");
         }

         if (IsDestructor()) {
            generator.AddIntoFree(" | DESTRUCTOR");
         }

         generator.AddIntoFree(")\n");
      }
   }
} // GenerateDict

//-------------------------------------------------------------------------------
void
Reflex::FunctionMember::UpdateFunctionParameterNames(const char* parameters) {
//-------------------------------------------------------------------------------
// Obtain the names and default values of the function parameters
// The "real" number of parameters is obtained from the function type

   fParameterNames.clear();
   bool hadDefaultValues = !fParameterDefaults.empty();
   size_t numDefaultParams = 0;
   size_t type_npar = MemberBase::TypeOf().FunctionParameterSize();
   std::vector<std::string> params;

   if (parameters) {
      Tools::StringSplit(params, parameters, ";");
   }
   size_t npar = std::min(type_npar, params.size());

   for (size_t i = 0; i < npar; ++i) {
      size_t pos = params[i].find("=");
      fParameterNames.push_back(params[i].substr(0, pos));

      if (pos != std::string::npos) {
         if (hadDefaultValues) {
            throw RuntimeError("Attempt to redefine default values of parameters!");
         } else {
            fParameterDefaults.push_back(params[i].substr(pos + 1));
            ++numDefaultParams;
         }
      } else if (!hadDefaultValues) {
         fParameterDefaults.push_back("");
      }
   }

   // padding with blanks
   for (size_t i = npar; i < type_npar; ++i) {
      fParameterNames.push_back("");

      if (!hadDefaultValues) {
         fParameterDefaults.push_back("");
      }
   }

   if (!hadDefaultValues) {
      fReqParameters = type_npar - numDefaultParams;
   }
} // UpdateFunctionParameterNames
<commit_msg>Fix bogus expression found by clang.<commit_after>// @(#)root/reflex:$Id$
// Author: Stefan Roiser 2004

// Copyright CERN, CH-1211 Geneva 23, 2004-2006, All rights reserved.
//
// Permission to use, copy, modify, and distribute this software for any
// purpose is hereby granted without fee, provided that this copyright and
// permissions notice appear in all copies and derivatives.
//
// This software is provided "as is" without express or implied warranty.

#ifndef REFLEX_BUILD
# define REFLEX_BUILD
#endif

#include "FunctionMember.h"

#include "Reflex/Scope.h"
#include "Reflex/Object.h"
#include "Reflex/internal/OwnedMember.h"
#include "Reflex/DictionaryGenerator.h"

#include "Function.h"
#include "Reflex/Tools.h"

//-------------------------------------------------------------------------------
Reflex::FunctionMember::FunctionMember(const char* nam,
                                       const Type& typ,
                                       StubFunction stubFP,
                                       void* stubCtx,
                                       const char* parameters,
                                       unsigned int modifiers,
                                       TYPE memType)
//-------------------------------------------------------------------------------
   : MemberBase(nam, typ, memType, modifiers),
   fStubFP(stubFP),
   fStubCtx(stubCtx),
   fParameterNames(std::vector<std::string>()),
   fParameterDefaults(std::vector<std::string>()),
   fReqParameters(0) {
// Contruct a FunctionMember (see FunctionBuilder)
   UpdateFunctionParameterNames(parameters);
}

//-------------------------------------------------------------------------------
std::string
Reflex::FunctionMember::Name(unsigned int mod) const {
//-------------------------------------------------------------------------------
// Construct the qualified (if requested) name of the function member.
   std::string s;
   s.reserve(30); // an arbitrary, reasonable number

   if (0 != (mod & (QUALIFIED | Q))) {
      if (IsPublic()) {
         s += "public ";
      }

      if (IsProtected()) {
         s += "protected ";
      }

      if (IsPrivate()) {
         s += "private ";
      }

      if (IsExtern()) {
         s += "extern ";
      }

      if (IsStatic()) {
         s += "static ";
      }

      if (IsInline()) {
         s += "inline ";
      }

      if (IsVirtual()) {
         s += "virtual ";
      }

      if (IsExplicit()) {
         s += "explicit ";
      }
   }

   s += MemberBase::Name(mod);

   return s;
} // Name

/*/-------------------------------------------------------------------------------
   Reflex::Object
   Reflex::FunctionMember::Invoke( const Object & obj,
   const std::vector < Object > & paramList ) const {
   //-----------------------------------------------------------------------------
   if ( paramList.size() < FunctionParameterSize(true)) {
   throw RuntimeError("Not enough parameters given to function ");
   return Object();
   }
   void * mem = CalculateBaseObject( obj );
   std::vector < void * > paramValues;
   // needs more checking FIXME
   for (std::vector<Object>::const_iterator it = paramList.begin();
   it != paramList.end(); ++it ) paramValues.push_back(it->Address());
   return Object(TypeOf().ReturnType(), fStubFP( mem, paramValues, fStubCtx ));
   }
 */

//-------------------------------------------------------------------------------
void
Reflex::FunctionMember::Invoke(const Object& obj,
                               Object* ret,
                               const std::vector<void*>& paramList) const {
//-----------------------------------------------------------------------------
// Invoke this function member with object obj, return value (it it exists)
// goes into Object ret.
   if (paramList.size() < FunctionParameterSize(true)) {
      throw RuntimeError("Not enough parameters given to function ");
   }
   void* mem = CalculateBaseObject(obj);
   static Type tVoid = Type::ByName("void");
   void* retaddr = 0;

   if (ret && TypeOf().ReturnType() != tVoid) {
      retaddr = ret->Address();
   }
   // parameters need more checking FIXME
   fStubFP(retaddr, mem, paramList, fStubCtx);
} // Invoke

/*/-------------------------------------------------------------------------------
   Reflex::Object
   Reflex::FunctionMember::Invoke( const std::vector < Object > & paramList ) const {
   //-------------------------------------------------------------------------------
   std::vector < void * > paramValues;
   // needs more checking FIXME
   for (std::vector<Object>::const_iterator it = paramList.begin();
   it != paramList.end(); ++it ) paramValues.push_back(it->Address());
   return Object(TypeOf().ReturnType(), fStubFP( 0, paramValues, fStubCtx ));
   }
 */

//-------------------------------------------------------------------------------
void
Reflex::FunctionMember::Invoke(Object* ret,
                               const std::vector<void*>& paramList) const {
//-------------------------------------------------------------------------------
// Call static function, return value (it it exists) goes into Object ret.

   static Type tVoid = Type::ByName("void");
   void* retaddr = 0;

   if (ret && TypeOf().ReturnType() != tVoid) {
      retaddr = ret->Address();
   }
   // parameters need more checking FIXME
   fStubFP(retaddr, 0, paramList, fStubCtx);
}

//-------------------------------------------------------------------------------
size_t
Reflex::FunctionMember::FunctionParameterSize(bool required) const {
//-------------------------------------------------------------------------------
// Return number of function parameters. If required = true return number without default params.
   if (required) {
      return fReqParameters;
   } else { return TypeOf().FunctionParameterSize(); }
}

//-------------------------------------------------------------------------------
void
Reflex::FunctionMember::GenerateDict(DictionaryGenerator& generator) const {
//-------------------------------------------------------------------------------
// Generate Dictionary information about itself.

   std::string mName = Name();

   if (mName != "__getNewDelFunctions" && mName != "__getBasesTable") {
      // The return type
      const Type& retT = TypeOf().ReturnType();

      // Get function return type, register that to "used types"
      std::string returntype = generator.GetTypeNumber(TypeOf().ReturnType());

      // Prevents __getNewDelFunctions getting into AddFunctionMember twice
      //if(generator.IsNewType( TypeOf() ) && Name()!="__getNewDelFunctions" ) {

      if (IsPrivate()) {
         generator.AddIntoShadow(Name(SCOPED) + "();\n");
      }

      // Get a number for the function type
      //std::string number = generator.GetTypeNumber( TypeOf() );

      std::stringstream temp;
      temp << generator.fMethodCounter;
      std::string number = temp.str();

      ++generator.fMethodCounter;

      // Get current Namespace location
      std::string namespc = DeclaringScope().Name(SCOPED);

      std::stringstream tempcounter;
      tempcounter << generator.fMethodCounter;

      // Free function, shall be added into Instances-field only
      if (DeclaringScope().IsNamespace()) {
         generator.AddIntoInstances("      Type t" + tempcounter.str() + " = FunctionTypeBuilder(type_" + returntype);

      } else { // "normal" function, inside a class
         generator.AddIntoFree(".AddFunctionMember(FunctionTypeBuilder(type_" + returntype);
      }

      // Get the parameters for function
      for (Type_Iterator params = TypeOf().FunctionParameter_Begin();
           params != TypeOf().FunctionParameter_End(); ++params) {
         if (DeclaringScope().IsNamespace()) {
            generator.AddIntoInstances(", type_" + generator.GetTypeNumber((*params)));

         } else {
            generator.AddIntoFree(", type_" + generator.GetTypeNumber((*params)));
         }

      }

      if (DeclaringScope().IsNamespace()) {
         generator.AddIntoInstances(");  FunctionBuilder(t" + tempcounter.str() + ", \""
                                    + Name() + "\", function_" + number);  //function name
      } else { // normal function
         generator.AddIntoFree("), \"" + Name() + "\"");  //function name
      }

      if (IsConstructor()) {
         generator.AddIntoFree(", constructor_");
      } else if (IsDestructor()) {
         generator.AddIntoFree(", destructor_");
      }

      if (IsConstructor()) {
         generator.AddIntoClasses("static void* constructor_");

      } else if (IsDestructor()) {
         generator.AddIntoClasses("static void* destructor_");

      } else {
         if (!(DeclaringScope().IsNamespace())) {
            generator.AddIntoFree(", method_");

            generator.AddIntoClasses("\nstatic void* method_");

         } else {
            // free function
            generator.AddIntoClasses("\nstatic void* function_");
         }
      }

      if (!(DeclaringScope().IsNamespace())) {
         generator.AddIntoFree(number);                                     //method_n

      }
      generator.AddIntoClasses(number);

      if (IsConstructor()) {   // these have parameters
         generator.AddIntoClasses("(void* mem, const std::vector<void*>&");

         if (FunctionParameterSize()) {
            generator.AddIntoClasses(" arg");
         }

         generator.AddIntoClasses(", void*)\n{");
         generator.AddIntoClasses("\n  return ::new(mem) " + namespc);
         generator.AddIntoClasses("(");

      } //is constructor/destructor with parameters
      else if (IsDestructor()) {
         generator.AddIntoClasses("(void * o, const std::vector<void*>&, void *) {\n");
         generator.AddIntoClasses("  ((" + namespc + "*)o)->~" + DeclaringScope().Name() + "(");
      } else {
         // method function with parameters

         if (DeclaringScope().IsNamespace()) {
            generator.AddIntoClasses(" (void*, const std::vector<void*>&"); // arg, void*)\n{");

         } else {
            generator.AddIntoClasses(" (void* o, const std::vector<void*>&"); // arg, void*)\n{");
         }

         if (FunctionParameterSize() > 0) {
            generator.AddIntoClasses(" arg");
         }

         generator.AddIntoClasses(", void*)\n{");

         if (retT.Name() != "void") {
            if (retT.IsFundamental()) {
               generator.AddIntoClasses("static " + retT.Name(SCOPED) + " ret;\n");
               generator.AddIntoClasses("ret = ");
            } else if (retT.IsReference() || retT.IsPointer()) {
               generator.AddIntoClasses("return (void*)");

               if (retT.IsReference()) {
                  generator.AddIntoClasses("&");
               }
            } else { // compound type
               generator.AddIntoClasses("return new " + retT.Name(SCOPED) + "(");
            }
         }

         if (DeclaringScope().IsNamespace()) {
            generator.AddIntoClasses(Name() + "( ");

         } else {
            generator.AddIntoClasses("((" + namespc + "*)o)->" + Name() + "( ");
         }

      }

      // Add to Stub Functions with some parameters
      if (FunctionParameterSize() > 0) {
         unsigned args = 0;

         // Get all parameters
         for (Type_Iterator methpara = TypeOf().FunctionParameter_Begin();
              methpara != TypeOf().FunctionParameter_End(); ++methpara) {
            // get params for the function, can include pointers or references
            std::string param = generator.GetParams(*methpara);

            std::stringstream temp2;
            temp2 << args;

            // We de-deference parameter only, if it's not a pointer
            if (!methpara->IsPointer()) {
               generator.AddIntoClasses("*");
            }

            generator.AddIntoClasses("(");

            //if( methpara->IsConst()) generator.AddIntoClasses("const ");

            std::string paraT = methpara->Name(SCOPED | QUALIFIED);

            if (methpara->IsReference()) {
               paraT = paraT.substr(0, paraT.length() - 1);
            }

            generator.AddIntoClasses(paraT);

            if (!methpara->IsPointer()) {
               generator.AddIntoClasses("*");
            }

            generator.AddIntoClasses(") arg[" + temp2.str() + "]");

            //still parameters left
            if ((args + 1) < FunctionParameterSize()) {
               generator.AddIntoClasses(", ");
            }

            ++args;
            //fundam

         }

      } // funct. params!=0

      if (IsConstructor()) {
         generator.AddIntoClasses(");\n} \n");

      } else {
         generator.AddIntoClasses(")");

         if (retT.Name() == "void") {
            generator.AddIntoClasses(";\n  return 0;\n");
         } else if (retT.IsFundamental()) {
            generator.AddIntoClasses(";\n  return & ret;\n");
         } else if (retT.IsPointer() || retT.IsReference()) {
            generator.AddIntoClasses(";\n");
         } else { // compound type
            generator.AddIntoClasses(");\n");
         }

         generator.AddIntoClasses("\n} \n"); //);
      }

      if (DeclaringScope().IsNamespace()) {
         generator.AddIntoInstances(", 0");
      } else {
         generator.AddIntoFree(", 0");
      }

      if (DeclaringScope().IsNamespace()) {
         generator.AddIntoInstances(", \"");
      } else { generator.AddIntoFree(", \""); }

      // Get the names of the function param.types (like MyInt)
      if (TypeOf().FunctionParameterSize()) {
         unsigned dot = 0;
         Type_Iterator params;
         StdString_Iterator parnam;

         for (params = TypeOf().FunctionParameter_Begin(), parnam = FunctionParameterName_Begin();
              params != TypeOf().FunctionParameter_End() && parnam != FunctionParameterName_End();
              ++params, ++parnam) {
            // THESE SHOULD ALSO INCLUDE DEFAULT VALUES,
            // LIKE int i=5 FunctionParameterDefault_Begin(), _End
            //

            if (DeclaringScope().IsNamespace()) {
               generator.AddIntoInstances((*parnam));

               if ((dot + 1) < FunctionParameterSize()) {
                  generator.AddIntoInstances(";");
               }
            } else {
               generator.AddIntoFree((*parnam));

               if ((dot + 1) < FunctionParameterSize()) {
                  generator.AddIntoFree(";");
               }
            }
            ++dot;
         }

      }

      if (DeclaringScope().IsNamespace()) {
         generator.AddIntoInstances("\"");
      } else { generator.AddIntoFree("\""); }

      if (DeclaringScope().IsNamespace()) {  // free func
         generator.AddIntoInstances(", ");

         if (IsPublic()) {
            generator.AddIntoInstances("PUBLIC");
         } else if (IsPrivate()) {
            generator.AddIntoInstances("PRIVATE");
         } else if (IsProtected()) {
            generator.AddIntoInstances("PROTECTED");
         }

         if (IsArtificial()) {
            generator.AddIntoInstances(" | ARTIFICIAL");
         }

         generator.AddIntoInstances(");\n");

         ++generator.fMethodCounter;

      } else {
         generator.AddIntoFree(", ");

         if (IsPublic()) {
            generator.AddIntoFree("PUBLIC");
         } else if (IsPrivate()) {
            generator.AddIntoFree("PRIVATE");
         } else if (IsProtected()) {
            generator.AddIntoFree("PROTECTED");
         }

         if (IsVirtual()) {
            generator.AddIntoFree(" | VIRTUAL");
         }

         if (IsArtificial()) {
            generator.AddIntoFree(" | ARTIFICIAL");
         }

         if (IsConstructor()) {
            generator.AddIntoFree(" | CONSTRUCTOR");
         }

         if (IsDestructor()) {
            generator.AddIntoFree(" | DESTRUCTOR");
         }

         generator.AddIntoFree(")\n");
      }
   }
} // GenerateDict

//-------------------------------------------------------------------------------
void
Reflex::FunctionMember::UpdateFunctionParameterNames(const char* parameters) {
//-------------------------------------------------------------------------------
// Obtain the names and default values of the function parameters
// The "real" number of parameters is obtained from the function type

   fParameterNames.clear();
   bool hadDefaultValues = !fParameterDefaults.empty();
   size_t numDefaultParams = 0;
   size_t type_npar = MemberBase::TypeOf().FunctionParameterSize();
   std::vector<std::string> params;

   if (parameters) {
      Tools::StringSplit(params, parameters, ";");
   }
   size_t npar = std::min(type_npar, params.size());

   for (size_t i = 0; i < npar; ++i) {
      size_t pos = params[i].find("=");
      fParameterNames.push_back(params[i].substr(0, pos));

      if (pos != std::string::npos) {
         if (hadDefaultValues) {
            throw RuntimeError("Attempt to redefine default values of parameters!");
         } else {
            fParameterDefaults.push_back(params[i].substr(pos + 1));
            ++numDefaultParams;
         }
      } else if (!hadDefaultValues) {
         fParameterDefaults.push_back("");
      }
   }

   // padding with blanks
   for (size_t i = npar; i < type_npar; ++i) {
      fParameterNames.push_back("");

      if (!hadDefaultValues) {
         fParameterDefaults.push_back("");
      }
   }

   if (!hadDefaultValues) {
      fReqParameters = type_npar - numDefaultParams;
   }
} // UpdateFunctionParameterNames
<|endoftext|>


<commit_before>#include "libbbn-ni-r.h"

//global to hold on to session handle
NiFpga_Session session;
bool isOpen = false;

//Initialize FPGA on loading the library -- constructor hook in header
void init() {
  NiFpga_Status status = NiFpga_Initialize();
}

//Cleanup NI library -- destructor hook in header
void cleanup(){
  if (isOpen) {NiFpga_Close(session, 0);};
  NiFpga_Finalize();
}

BBN_NI_R_STATUS open_load_run(){
  NiFpga_Status status = NiFpga_Open("../" NiFpga_SimpleDigitizer_VI_Bitfile,
                                      NiFpga_SimpleDigitizer_VI_Signature,
                                      "RIO0", 0, &session);
  if (status == NiFpga_Status_Success){
    isOpen = true;
  }
  return status;
}

BBN_NI_R_STATUS set_numSamples(uint32_t numSamples){
  NiFpga_Status status = NiFpga_WriteU32(session, NiFpga_SimpleDigitizer_VI_ControlU32_NumberofSamples, numSamples);
  return status;
};
BBN_NI_R_STATUS get_numSamples(uint32_t* numSamples){
  NiFpga_Status status = NiFpga_ReadU32(session, NiFpga_SimpleDigitizer_VI_ControlU32_NumberofSamples, numSamples);
  return status;
};

BBN_NI_R_STATUS set_sampleInterval(double sampleInterval){
  uint32_t sampleInterval_us = static_cast<uint32_t>(sampleInterval/1e6);
  NiFpga_Status status = NiFpga_WriteU32(session, NiFpga_SimpleDigitizer_VI_ControlU32_SampleIntervaluSec, sampleInterval * 1000000);
  return status;
};
BBN_NI_R_STATUS get_sampleInterval(double* sampleInterval){
  uint32_t sampleInterval_us;
  NiFpga_Status status = NiFpga_ReadU32(session, NiFpga_SimpleDigitizer_VI_ControlU32_SampleIntervaluSec, &sampleInterval_us);
  *sampleInterval = static_cast<double>(sampleInterval_us) / 1000000;
  return status;
};

BBN_NI_R_STATUS enable_acquisition(){
  return NiFpga_WriteBool(session, NiFpga_SimpleDigitizer_VI_ControlBool_Acquire, NiFpga_True);
}

BBN_NI_R_STATUS disable_acquisition(){
  return NiFpga_WriteBool(session, NiFpga_SimpleDigitizer_VI_ControlBool_Acquire, NiFpga_False);
}

BBN_NI_R_STATUS trigger(){
  //Toggle the trigger rising-edge
  NiFpga_Status status = NiFpga_WriteBool(session, NiFpga_SimpleDigitizer_VI_ControlBool_Trigger, NiFpga_False);
  NiFpga_MergeStatus(&status, NiFpga_WriteBool(session, NiFpga_SimpleDigitizer_VI_ControlBool_Trigger, NiFpga_True));
  return status;
}

BBN_NI_R_STATUS transfer_waveform(unsigned numPoints, int16_t* data, double timeOut){
  // Ask for a number of points from the FIFO
  // Assumes memory has been correctly allocated
  uint32_t timeOut_ms = timeOut*1e3;
  return NiFpga_ReadFifoI16(session, NiFpga_SimpleDigitizer_VI_TargetToHostFifoI16_AIFIFO, data, numPoints, timeOut_ms, nullptr);
}
<commit_msg>Skip some temporary variables<commit_after>#include "libbbn-ni-r.h"

//global to hold on to session handle
NiFpga_Session session;
bool isOpen = false;

//Initialize FPGA on loading the library -- constructor hook in header
void init() {
  NiFpga_Status status = NiFpga_Initialize();
}

//Cleanup NI library -- destructor hook in header
void cleanup(){
  if (isOpen) {NiFpga_Close(session, 0);};
  NiFpga_Finalize();
}

BBN_NI_R_STATUS open_load_run(){
  NiFpga_Status status = NiFpga_Open("../" NiFpga_SimpleDigitizer_VI_Bitfile,
                                      NiFpga_SimpleDigitizer_VI_Signature,
                                      "RIO0", 0, &session);
  if (status == NiFpga_Status_Success){
    isOpen = true;
  }
  return status;
}

BBN_NI_R_STATUS set_numSamples(uint32_t numSamples){
  return NiFpga_WriteU32(session, NiFpga_SimpleDigitizer_VI_ControlU32_NumberofSamples, numSamples);
};

BBN_NI_R_STATUS get_numSamples(uint32_t* numSamples){
  return NiFpga_ReadU32(session, NiFpga_SimpleDigitizer_VI_ControlU32_NumberofSamples, numSamples);
};

BBN_NI_R_STATUS set_sampleInterval(double sampleInterval){
  uint32_t sampleInterval_us = static_cast<uint32_t>(sampleInterval/1e6);
  NiFpga_Status status = NiFpga_WriteU32(session, NiFpga_SimpleDigitizer_VI_ControlU32_SampleIntervaluSec, sampleInterval * 1000000);
  return status;
};
BBN_NI_R_STATUS get_sampleInterval(double* sampleInterval){
  uint32_t sampleInterval_us;
  NiFpga_Status status = NiFpga_ReadU32(session, NiFpga_SimpleDigitizer_VI_ControlU32_SampleIntervaluSec, &sampleInterval_us);
  *sampleInterval = static_cast<double>(sampleInterval_us) / 1000000;
  return status;
};

BBN_NI_R_STATUS enable_acquisition(){
  return NiFpga_WriteBool(session, NiFpga_SimpleDigitizer_VI_ControlBool_Acquire, NiFpga_True);
}

BBN_NI_R_STATUS disable_acquisition(){
  return NiFpga_WriteBool(session, NiFpga_SimpleDigitizer_VI_ControlBool_Acquire, NiFpga_False);
}

BBN_NI_R_STATUS trigger(){
  //Toggle the trigger rising-edge
  NiFpga_Status status = NiFpga_WriteBool(session, NiFpga_SimpleDigitizer_VI_ControlBool_Trigger, NiFpga_False);
  NiFpga_MergeStatus(&status, NiFpga_WriteBool(session, NiFpga_SimpleDigitizer_VI_ControlBool_Trigger, NiFpga_True));
  return status;
}

BBN_NI_R_STATUS transfer_waveform(unsigned numPoints, int16_t* data, double timeOut){
  // Ask for a number of points from the FIFO
  // Assumes memory has been correctly allocated
  uint32_t timeOut_ms = timeOut*1e3;
  return NiFpga_ReadFifoI16(session, NiFpga_SimpleDigitizer_VI_TargetToHostFifoI16_AIFIFO, data, numPoints, timeOut_ms, nullptr);
}
<|endoftext|>


<commit_before>
#include "NSprite.h"

void NSprite::loadGraphic(NAssetPath asset, int frameWidth,
                          int frameHeight) {
    // load BMP asset and save to _graphic
    // use asset loader to get full path
    std::string asset_full_path = NAssetLoader::get_full_path(asset);
    SDL_Surface *assetBmp = NAssetLoader::load_bmp_ex(asset_full_path);

    if (frameWidth == 0) {
        frameWidth = this->width = assetBmp->w;
    } else {
        this->width = frameWidth;
    }
    if (frameHeight == 0) {
        frameHeight = this->height = assetBmp->h;
    } else {
        this->height = frameHeight;
    }

    this->_vertFrames = assetBmp->h / frameHeight;
    this->_horizFrames = assetBmp->w / frameWidth;

    this->_frameWidth = this->width;
    this->_frameHeight = this->height;

    this->_graphic = assetBmp;
}

void NSprite::update(float dt) {
    this->animation.update(dt);
}

void NSprite::render(NG2 *g2) {
    // render the sprite to the screen
    // MAJOR TODO for improvements
    if (this->_graphic != nullptr) {
        // blit the frame
        int frameX = (animation.frameIndex % this->_horizFrames) * this->_frameWidth;
        int frameY = animation.frameIndex / this->_horizFrames;
        g2->blit_sub_image(this->_graphic,
            this->x - this->offset.getX(), this->y - this->offset.getY(),
            frameX, frameY,
            this->_frameWidth, this->_frameHeight);
    }
    NEntity::render(g2);
}

void NSprite::destroy() {
    // free _graphic
    if (this->_graphic != nullptr) {
        SDL_FreeSurface(this->_graphic);
        this->_graphic = nullptr;
    }

    NEntity::destroy();
}
<commit_msg>fix animation frameY calculation<commit_after>
#include "NSprite.h"

void NSprite::loadGraphic(NAssetPath asset, int frameWidth,
                          int frameHeight) {
    // load BMP asset and save to _graphic
    // use asset loader to get full path
    std::string asset_full_path = NAssetLoader::get_full_path(asset);
    SDL_Surface *assetBmp = NAssetLoader::load_bmp_ex(asset_full_path);

    if (frameWidth == 0) {
        frameWidth = this->width = assetBmp->w;
    } else {
        this->width = frameWidth;
    }
    if (frameHeight == 0) {
        frameHeight = this->height = assetBmp->h;
    } else {
        this->height = frameHeight;
    }

    this->_vertFrames = assetBmp->h / frameHeight;
    this->_horizFrames = assetBmp->w / frameWidth;

    this->_frameWidth = this->width;
    this->_frameHeight = this->height;

    this->_graphic = assetBmp;
}

void NSprite::update(float dt) {
    this->animation.update(dt);
}

void NSprite::render(NG2 *g2) {
    // render the sprite to the screen
    // MAJOR TODO for improvements
    if (this->_graphic != nullptr) {
        // blit the frame
        int frameX = (animation.frameIndex % this->_horizFrames) * this->_frameWidth;
        int frameY = (animation.frameIndex / this->_horizFrames) * this->_frameHeight;
        g2->blit_sub_image(this->_graphic,
            this->x - this->offset.getX(), this->y - this->offset.getY(),
            frameX, frameY,
            this->_frameWidth, this->_frameHeight);
    }
    NEntity::render(g2);
}

void NSprite::destroy() {
    // free _graphic
    if (this->_graphic != nullptr) {
        SDL_FreeSurface(this->_graphic);
        this->_graphic = nullptr;
    }

    NEntity::destroy();
}
<|endoftext|>


<commit_before>//===--- PrintASTTests.cpp ----------------------------------------- C++-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "AST.h"
#include "Annotations.h"
#include "Protocol.h"
#include "SourceCode.h"
#include "TestTU.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "gmock/gmock.h"
#include "gtest/gtest-param-test.h"
#include "gtest/gtest.h"
#include "gtest/internal/gtest-param-util-generated.h"

namespace clang {
namespace clangd {
namespace {

using ::testing::ElementsAreArray;

struct Case {
  const char *AnnotatedCode;
  std::vector<const char *> Expected;
};
class ASTUtils : public ::testing::Test,
                 public ::testing::WithParamInterface<Case> {};

TEST_P(ASTUtils, PrintTemplateArgs) {
  auto Pair = GetParam();
  Annotations Test(Pair.AnnotatedCode);
  auto AST = TestTU::withCode(Test.code()).build();
  struct Visitor : RecursiveASTVisitor<Visitor> {
    Visitor(std::vector<Position> Points) : Points(std::move(Points)) {}
    bool VisitNamedDecl(const NamedDecl *ND) {
      if (TemplateArgsAtPoints.size() == Points.size())
        return true;
      auto Pos = sourceLocToPosition(ND->getASTContext().getSourceManager(),
                                     ND->getLocation());
      if (Pos != Points[TemplateArgsAtPoints.size()])
        return true;
      TemplateArgsAtPoints.push_back(printTemplateSpecializationArgs(*ND));
      return true;
    }
    std::vector<std::string> TemplateArgsAtPoints;
    const std::vector<Position> Points;
  };
  Visitor V(Test.points());
  V.TraverseDecl(AST.getASTContext().getTranslationUnitDecl());
  EXPECT_THAT(V.TemplateArgsAtPoints, ElementsAreArray(Pair.Expected));
}

INSTANTIATE_TEST_CASE_P(ASTUtilsTests, ASTUtils,
                        ::testing::ValuesIn(std::vector<Case>({
                            {
                                R"cpp(
                                  template <class X> class Bar {};
                                  template <> class ^Bar<double> {};)cpp",
                                {"<double>"}},
                            {
                                R"cpp(
                                  template <class X> class Bar {};
                                  template <class T, class U,
                                  template<typename> class Z, int Q>
                                  struct Foo {};
                                  template struct ^Foo<int, bool, Bar, 8>;
                                  template <typename T>
                                  struct ^Foo<T *, T, Bar, 3> {};)cpp",
                                {"<int, bool, Bar, 8>", "<T *, T, Bar, 3>"}},
                            {
                                R"cpp(
                                  template <int ...> void Foz() {};
                                  template <> void ^Foz<3, 5, 8>() {};)cpp",
                                {"<3, 5, 8>"}},
                            {
                                R"cpp(
                                  template <class X> class Bar {};
                                  template <template <class> class ...>
                                  class Aux {};
                                  template <> class ^Aux<Bar, Bar> {};
                                  template <template <class> T>
                                  class ^Aux<T, T> {};)cpp",
                                {"<Bar, Bar>", "<T, T>"}},
                            {
                                R"cpp(
                                  template <typename T> T var = 1234;
                                  template <> int ^var<int> = 1;)cpp",
                                {"<int>"}},
                            {
                                R"cpp(
                                  template <typename T> struct Foo;
                                  struct Bar { friend class Foo<int>; };
                                  template <> struct ^Foo<int> {};)cpp",
                                {"<int>"}},
                        })));
} // namespace
} // namespace clangd
} // namespace clang
<commit_msg>Fix gcc compilation warning in test case [NFC]<commit_after>//===--- PrintASTTests.cpp ----------------------------------------- C++-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "AST.h"
#include "Annotations.h"
#include "Protocol.h"
#include "SourceCode.h"
#include "TestTU.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "gmock/gmock.h"
#include "gtest/gtest-param-test.h"
#include "gtest/gtest.h"
#include "gtest/internal/gtest-param-util-generated.h"

namespace clang {
namespace clangd {
namespace {

using ::testing::ElementsAreArray;

struct Case {
  const char *AnnotatedCode;
  std::vector<const char *> Expected;
};
class ASTUtils : public ::testing::Test,
                 public ::testing::WithParamInterface<Case> {};

TEST_P(ASTUtils, PrintTemplateArgs) {
  auto Pair = GetParam();
  Annotations Test(Pair.AnnotatedCode);
  auto AST = TestTU::withCode(Test.code()).build();
  struct Visitor : RecursiveASTVisitor<Visitor> {
    Visitor(std::vector<Position> Points) : Points(std::move(Points)) {}
    bool VisitNamedDecl(const NamedDecl *ND) {
      if (TemplateArgsAtPoints.size() == Points.size())
        return true;
      auto Pos = sourceLocToPosition(ND->getASTContext().getSourceManager(),
                                     ND->getLocation());
      if (Pos != Points[TemplateArgsAtPoints.size()])
        return true;
      TemplateArgsAtPoints.push_back(printTemplateSpecializationArgs(*ND));
      return true;
    }
    std::vector<std::string> TemplateArgsAtPoints;
    const std::vector<Position> Points;
  };
  Visitor V(Test.points());
  V.TraverseDecl(AST.getASTContext().getTranslationUnitDecl());
  EXPECT_THAT(V.TemplateArgsAtPoints, ElementsAreArray(Pair.Expected));
}

INSTANTIATE_TEST_CASE_P(ASTUtilsTests, ASTUtils,
                        ::testing::ValuesIn(std::vector<Case>({
                            {
                                R"cpp(
                                  template <class X> class Bar {};
                                  template <> class ^Bar<double> {};)cpp",
                                {"<double>"}},
                            {
                                R"cpp(
                                  template <class X> class Bar {};
                                  template <class T, class U,
                                  template<typename> class Z, int Q>
                                  struct Foo {};
                                  template struct ^Foo<int, bool, Bar, 8>;
                                  template <typename T>
                                  struct ^Foo<T *, T, Bar, 3> {};)cpp",
                                {"<int, bool, Bar, 8>", "<T *, T, Bar, 3>"}},
                            {
                                R"cpp(
                                  template <int ...> void Foz() {};
                                  template <> void ^Foz<3, 5, 8>() {};)cpp",
                                {"<3, 5, 8>"}},
                            {
                                R"cpp(
                                  template <class X> class Bar {};
                                  template <template <class> class ...>
                                  class Aux {};
                                  template <> class ^Aux<Bar, Bar> {};
                                  template <template <class> T>
                                  class ^Aux<T, T> {};)cpp",
                                {"<Bar, Bar>", "<T, T>"}},
                            {
                                R"cpp(
                                  template <typename T> T var = 1234;
                                  template <> int ^var<int> = 1;)cpp",
                                {"<int>"}},
                            {
                                R"cpp(
                                  template <typename T> struct Foo;
                                  struct Bar { friend class Foo<int>; };
                                  template <> struct ^Foo<int> {};)cpp",
                                {"<int>"}},
                        })),);
} // namespace
} // namespace clangd
} // namespace clang
<|endoftext|>


<commit_before>#include "TransformTool.h"
void TransformToolImpl::StartupModule()
{
}
void TransformToolImpl::ShutdownModule()
{
}
IMPLEMENT_MODULE(TransformToolImpl, Module)<commit_msg>fix error<commit_after>#include "TransformTool.h"
void TransformToolImpl::StartupModule()
{
}
void TransformToolImpl::ShutdownModule()
{
}
IMPLEMENT_GAME_MODULE(TransformToolImpl, TransformTool)<|endoftext|>


<commit_before>// $Id$
//
//  Copyright (C) 2003-2008 Greg Landrum and Rational Discovery LLC
//
//   @@ All Rights Reserved  @@
//
#include <GraphMol/RDKitBase.h>
#include <DataStructs/ExplicitBitVect.h>
#include <DataStructs/BitOps.h>
#include "Fingerprints.h"
#include <GraphMol/Subgraphs/Subgraphs.h>
#include <GraphMol/Subgraphs/SubgraphUtils.h>
#include <RDGeneral/Invariant.h>
#include <boost/random.hpp>
#include <limits.h>
#include <boost/functional/hash.hpp>
#include <algorithm>

namespace RDKit{
  // caller owns the result, it must be deleted
  ExplicitBitVect *DaylightFingerprintMol(const ROMol &mol,
                                          unsigned int minPath,
					  unsigned int maxPath,
					  unsigned int fpSize,
                                          unsigned int nBitsPerHash,
					  bool useHs,
					  double tgtDensity,
                                          unsigned int minSize){
    PRECONDITION(minPath!=0,"minPath==0");
    PRECONDITION(maxPath>=minPath,"maxPath<minPath");
    PRECONDITION(fpSize!=0,"fpSize==0");
    PRECONDITION(nBitsPerHash!=0,"nBitsPerHash==0");

    typedef boost::minstd_rand rng_type;
    typedef boost::uniform_int<> distrib_type;
    typedef boost::variate_generator<rng_type &,distrib_type> source_type;
    rng_type generator(42u);

    //
    // if we generate arbitrarily sized ints then mod them down to the
    // appropriate size, we can guarantee that a fingerprint of
    // size x has the same bits set as one of size 2x that's been folded
    // in half.  This is a nice guarantee to have.
    //
    distrib_type dist(0,INT_MAX);
    source_type randomSource(generator,dist);

    ExplicitBitVect *res = new ExplicitBitVect(fpSize);
    INT_PATH_LIST_MAP allPaths = findAllSubgraphsOfLengthsMtoN(mol,minPath,maxPath,
							       useHs);
    for(INT_PATH_LIST_MAP_CI paths=allPaths.begin();paths!=allPaths.end();paths++){
      for( PATH_LIST_CI pathIt=paths->second.begin();
	   pathIt!=paths->second.end();
	   pathIt++ ){
	const PATH_TYPE &path=*pathIt;
	float balabanJ = static_cast<float>(MolOps::computeBalabanJ(mol,true,true,
								    &path,false));

        //boost::hash<float> floatHasher;
	//unsigned long seed = floatHasher(balabanJ);
        unsigned long seed = *(unsigned long *)&balabanJ;
	generator.seed(static_cast<rng_type::result_type>(seed));

	for(unsigned int i=0;i<nBitsPerHash;i++){
	  unsigned int bit = randomSource();
	  bit %= fpSize;
	  res->SetBit(bit);
	}
      }
    }

    // EFF: this could be faster by folding by more than a factor
    // of 2 each time, but we're not going to be spending much
    // time here anyway
    while( static_cast<double>(res->GetNumOnBits())/res->GetNumBits() < tgtDensity &&
	   res->GetNumBits() >= 2*minSize ){
      ExplicitBitVect *tmpV=FoldFingerprint(*res,2);
      delete res;
      res = tmpV;
    }

    return res;
  }

  // caller owns the result, it must be deleted
  ExplicitBitVect *RDKFingerprintMol(const ROMol &mol,unsigned int minPath,
                                      unsigned int maxPath,
                                      unsigned int fpSize,unsigned int nBitsPerHash,
                                      bool useHs,
                                      double tgtDensity,unsigned int minSize){
    PRECONDITION(minPath!=0,"minPath==0");
    PRECONDITION(maxPath>=minPath,"maxPath<minPath");
    PRECONDITION(fpSize!=0,"fpSize==0");
    PRECONDITION(nBitsPerHash!=0,"nBitsPerHash==0");

    typedef boost::mt19937 rng_type;
    typedef boost::uniform_int<> distrib_type;
    typedef boost::variate_generator<rng_type &,distrib_type> source_type;
    rng_type generator(42u);

    //
    // if we generate arbitrarily sized ints then mod them down to the
    // appropriate size, we can guarantee that a fingerprint of
    // size x has the same bits set as one of size 2x that's been folded
    // in half.  This is a nice guarantee to have.
    //
    distrib_type dist(0,INT_MAX);
    source_type randomSource(generator,dist);

    ExplicitBitVect *res = new ExplicitBitVect(fpSize);
    INT_PATH_LIST_MAP allPaths = findAllSubgraphsOfLengthsMtoN(mol,minPath,maxPath,
							       useHs);
    for(INT_PATH_LIST_MAP_CI paths=allPaths.begin();paths!=allPaths.end();paths++){
      for( PATH_LIST_CI pathIt=paths->second.begin();
	   pathIt!=paths->second.end();
	   pathIt++ ){
	const PATH_TYPE &path=*pathIt;
#ifdef VERBOSE_FINGERPRINTING
        std::cerr<<"Path: ";
        std::copy(path.begin(),path.end(),std::ostream_iterator<int>(std::cerr,", "));
        std::cerr<<std::endl;
#endif
        // initialize the bond hashes to the number of neighbors the bond has in the path:
        std::vector<unsigned int> bondNbrs(path.size());
        std::fill(bondNbrs.begin(),bondNbrs.end(),0);
        std::set<unsigned int> atomsInPath;
        std::vector<unsigned int> bondHashes;
        bondHashes.reserve(path.size()+1);
        for(unsigned int i=0;i<path.size();++i){
          const Bond *bi = mol.getBondWithIdx(path[i]);
          atomsInPath.insert(bi->getBeginAtomIdx());
          atomsInPath.insert(bi->getEndAtomIdx());
          for(unsigned int j=i+1;j<path.size();++j){
            const Bond *bj = mol.getBondWithIdx(path[j]);
            if(bi->getBeginAtomIdx()==bj->getBeginAtomIdx() ||
               bi->getBeginAtomIdx()==bj->getEndAtomIdx() ||
               bi->getEndAtomIdx()==bj->getBeginAtomIdx() ||
               bi->getEndAtomIdx()==bj->getEndAtomIdx() ){
              ++bondNbrs[i];
              ++bondNbrs[j];
            }
          }
#ifdef VERBOSE_FINGERPRINTING
          std::cerr<<"   bond("<<i<<"):"<<bondNbrs[i]<<std::endl;
#endif
          // we have the count of neighbors for bond bi, compute its hash:
          unsigned int a1Hash,a2Hash;
          a1Hash = (bi->getBeginAtom()->getAtomicNum()%128)<<1 | bi->getBeginAtom()->getIsAromatic();
          a2Hash = (bi->getEndAtom()->getAtomicNum()%128)<<1 | bi->getEndAtom()->getIsAromatic();
          if(a1Hash<a2Hash) std::swap(a1Hash,a2Hash);
          unsigned int bondHash;
          if(bi->getIsAromatic()){
            // makes sure aromatic bonds always hash the same:
            bondHash = Bond::AROMATIC;
          } else {
            bondHash = bi->getBondType();
          }
          unsigned int nBitsInHash=0;
          unsigned int ourHash=bondNbrs[i]%8; // 3 bits here
          nBitsInHash+=3;
          ourHash |= (bondHash%16)<<nBitsInHash; // 4 bits here
          nBitsInHash+=4;
          ourHash |= a1Hash<<nBitsInHash; // 8 bits
          nBitsInHash+=8;
          ourHash |= a2Hash<<nBitsInHash; // 8 bits
          bondHashes.insert(std::lower_bound(bondHashes.begin(),bondHashes.end(),ourHash),ourHash);
        }

        // finally, we will add the number of distinct atoms in the path at the end
        // of the vect. This allows us to distinguish C1CC1 from CC(C)C
        bondHashes.push_back(atomsInPath.size());

        // hash the path to generate a seed:
        boost::hash<std::vector<unsigned int> > vectHasher;
	unsigned long seed = vectHasher(bondHashes);

#ifdef VERBOSE_FINGERPRINTING
        std::cerr<<" hash: "<<seed<<std::endl;
#endif
        // originally it seemed like a good idea to track hashes we've already
        // seen in order to avoid resetting them. In some benchmarking I did, that
        // seemed to actually result in a longer runtime (at least when using
        // an std::set to store the hashes)
        generator.seed(static_cast<rng_type::result_type>(seed));
        for(unsigned int i=0;i<nBitsPerHash;i++){
          unsigned int bit = randomSource();
          bit %= fpSize;
          res->SetBit(bit);
        }
      }
    }

    // EFF: this could be faster by folding by more than a factor
    // of 2 each time, but we're not going to be spending much
    // time here anyway
    if(tgtDensity>0.0){
      while( static_cast<double>(res->GetNumOnBits())/res->GetNumBits() < tgtDensity &&
             res->GetNumBits() >= 2*minSize ){
        ExplicitBitVect *tmpV=FoldFingerprint(*res,2);
        delete res;
        res = tmpV;
      }
    }

    return res;
  }

}
<commit_msg>be a bit more specific about sizes<commit_after>// $Id$
//
//  Copyright (C) 2003-2008 Greg Landrum and Rational Discovery LLC
//
//   @@ All Rights Reserved  @@
//
#include <GraphMol/RDKitBase.h>
#include <DataStructs/ExplicitBitVect.h>
#include <DataStructs/BitOps.h>
#include "Fingerprints.h"
#include <GraphMol/Subgraphs/Subgraphs.h>
#include <GraphMol/Subgraphs/SubgraphUtils.h>
#include <RDGeneral/Invariant.h>
#include <boost/random.hpp>
#include <limits.h>
#include <boost/functional/hash.hpp>
#include <boost/cstdint.hpp>
#include <algorithm>

namespace RDKit{
  // caller owns the result, it must be deleted
  ExplicitBitVect *DaylightFingerprintMol(const ROMol &mol,
                                          unsigned int minPath,
					  unsigned int maxPath,
					  unsigned int fpSize,
                                          unsigned int nBitsPerHash,
					  bool useHs,
					  double tgtDensity,
                                          unsigned int minSize){
    PRECONDITION(minPath!=0,"minPath==0");
    PRECONDITION(maxPath>=minPath,"maxPath<minPath");
    PRECONDITION(fpSize!=0,"fpSize==0");
    PRECONDITION(nBitsPerHash!=0,"nBitsPerHash==0");

    typedef boost::minstd_rand rng_type;
    typedef boost::uniform_int<> distrib_type;
    typedef boost::variate_generator<rng_type &,distrib_type> source_type;
    rng_type generator(42u);

    //
    // if we generate arbitrarily sized ints then mod them down to the
    // appropriate size, we can guarantee that a fingerprint of
    // size x has the same bits set as one of size 2x that's been folded
    // in half.  This is a nice guarantee to have.
    //
    distrib_type dist(0,INT_MAX);
    source_type randomSource(generator,dist);

    ExplicitBitVect *res = new ExplicitBitVect(fpSize);
    INT_PATH_LIST_MAP allPaths = findAllSubgraphsOfLengthsMtoN(mol,minPath,maxPath,
							       useHs);
    for(INT_PATH_LIST_MAP_CI paths=allPaths.begin();paths!=allPaths.end();paths++){
      for( PATH_LIST_CI pathIt=paths->second.begin();
	   pathIt!=paths->second.end();
	   pathIt++ ){
	const PATH_TYPE &path=*pathIt;
	float balabanJ = static_cast<float>(MolOps::computeBalabanJ(mol,true,true,
								    &path,false));

        //boost::hash<float> floatHasher;
	//unsigned long seed = floatHasher(balabanJ);
        //unsigned long seed = *(unsigned long *)&balabanJ;
        boost::uint32_t seed = *(boost::uint32_t *)&balabanJ;
	generator.seed(static_cast<rng_type::result_type>(seed));
	for(unsigned int i=0;i<nBitsPerHash;i++){
	  unsigned int bit = randomSource();
	  bit %= fpSize;
	  res->SetBit(bit);
	}
      }
    }

    // EFF: this could be faster by folding by more than a factor
    // of 2 each time, but we're not going to be spending much
    // time here anyway
    while( static_cast<double>(res->GetNumOnBits())/res->GetNumBits() < tgtDensity &&
	   res->GetNumBits() >= 2*minSize ){
      ExplicitBitVect *tmpV=FoldFingerprint(*res,2);
      delete res;
      res = tmpV;
    }

    return res;
  }

  // caller owns the result, it must be deleted
  ExplicitBitVect *RDKFingerprintMol(const ROMol &mol,unsigned int minPath,
                                      unsigned int maxPath,
                                      unsigned int fpSize,unsigned int nBitsPerHash,
                                      bool useHs,
                                      double tgtDensity,unsigned int minSize){
    PRECONDITION(minPath!=0,"minPath==0");
    PRECONDITION(maxPath>=minPath,"maxPath<minPath");
    PRECONDITION(fpSize!=0,"fpSize==0");
    PRECONDITION(nBitsPerHash!=0,"nBitsPerHash==0");

    typedef boost::mt19937 rng_type;
    typedef boost::uniform_int<> distrib_type;
    typedef boost::variate_generator<rng_type &,distrib_type> source_type;
    rng_type generator(42u);

    //
    // if we generate arbitrarily sized ints then mod them down to the
    // appropriate size, we can guarantee that a fingerprint of
    // size x has the same bits set as one of size 2x that's been folded
    // in half.  This is a nice guarantee to have.
    //
    distrib_type dist(0,INT_MAX);
    source_type randomSource(generator,dist);

    ExplicitBitVect *res = new ExplicitBitVect(fpSize);
    INT_PATH_LIST_MAP allPaths = findAllSubgraphsOfLengthsMtoN(mol,minPath,maxPath,
							       useHs);
    for(INT_PATH_LIST_MAP_CI paths=allPaths.begin();paths!=allPaths.end();paths++){
      for( PATH_LIST_CI pathIt=paths->second.begin();
	   pathIt!=paths->second.end();
	   pathIt++ ){
	const PATH_TYPE &path=*pathIt;
#ifdef VERBOSE_FINGERPRINTING
        std::cerr<<"Path: ";
        std::copy(path.begin(),path.end(),std::ostream_iterator<int>(std::cerr,", "));
        std::cerr<<std::endl;
#endif
        // initialize the bond hashes to the number of neighbors the bond has in the path:
        std::vector<unsigned int> bondNbrs(path.size());
        std::fill(bondNbrs.begin(),bondNbrs.end(),0);
        std::set<unsigned int> atomsInPath;
        std::vector<unsigned int> bondHashes;
        bondHashes.reserve(path.size()+1);
        for(unsigned int i=0;i<path.size();++i){
          const Bond *bi = mol.getBondWithIdx(path[i]);
          atomsInPath.insert(bi->getBeginAtomIdx());
          atomsInPath.insert(bi->getEndAtomIdx());
          for(unsigned int j=i+1;j<path.size();++j){
            const Bond *bj = mol.getBondWithIdx(path[j]);
            if(bi->getBeginAtomIdx()==bj->getBeginAtomIdx() ||
               bi->getBeginAtomIdx()==bj->getEndAtomIdx() ||
               bi->getEndAtomIdx()==bj->getBeginAtomIdx() ||
               bi->getEndAtomIdx()==bj->getEndAtomIdx() ){
              ++bondNbrs[i];
              ++bondNbrs[j];
            }
          }
#ifdef VERBOSE_FINGERPRINTING
          std::cerr<<"   bond("<<i<<"):"<<bondNbrs[i]<<std::endl;
#endif
          // we have the count of neighbors for bond bi, compute its hash:
          unsigned int a1Hash,a2Hash;
          a1Hash = (bi->getBeginAtom()->getAtomicNum()%128)<<1 | bi->getBeginAtom()->getIsAromatic();
          a2Hash = (bi->getEndAtom()->getAtomicNum()%128)<<1 | bi->getEndAtom()->getIsAromatic();
          if(a1Hash<a2Hash) std::swap(a1Hash,a2Hash);
          unsigned int bondHash;
          if(bi->getIsAromatic()){
            // makes sure aromatic bonds always hash the same:
            bondHash = Bond::AROMATIC;
          } else {
            bondHash = bi->getBondType();
          }
          unsigned int nBitsInHash=0;
          unsigned int ourHash=bondNbrs[i]%8; // 3 bits here
          nBitsInHash+=3;
          ourHash |= (bondHash%16)<<nBitsInHash; // 4 bits here
          nBitsInHash+=4;
          ourHash |= a1Hash<<nBitsInHash; // 8 bits
          nBitsInHash+=8;
          ourHash |= a2Hash<<nBitsInHash; // 8 bits
          bondHashes.insert(std::lower_bound(bondHashes.begin(),bondHashes.end(),ourHash),ourHash);
        }

        // finally, we will add the number of distinct atoms in the path at the end
        // of the vect. This allows us to distinguish C1CC1 from CC(C)C
        bondHashes.push_back(atomsInPath.size());

        // hash the path to generate a seed:
        boost::hash<std::vector<unsigned int> > vectHasher;
	unsigned long seed = vectHasher(bondHashes);

#ifdef VERBOSE_FINGERPRINTING
        std::cerr<<" hash: "<<seed<<std::endl;
#endif
        // originally it seemed like a good idea to track hashes we've already
        // seen in order to avoid resetting them. In some benchmarking I did, that
        // seemed to actually result in a longer runtime (at least when using
        // an std::set to store the hashes)
        generator.seed(static_cast<rng_type::result_type>(seed));
        for(unsigned int i=0;i<nBitsPerHash;i++){
          unsigned int bit = randomSource();
          bit %= fpSize;
          res->SetBit(bit);
        }
      }
    }

    // EFF: this could be faster by folding by more than a factor
    // of 2 each time, but we're not going to be spending much
    // time here anyway
    if(tgtDensity>0.0){
      while( static_cast<double>(res->GetNumOnBits())/res->GetNumBits() < tgtDensity &&
             res->GetNumBits() >= 2*minSize ){
        ExplicitBitVect *tmpV=FoldFingerprint(*res,2);
        delete res;
        res = tmpV;
      }
    }

    return res;
  }

}
<|endoftext|>


<commit_before>#include <fstream>
#include <iostream>
#include <omp.h>
#include <stdio.h>
#include <time.h>

#include "../Neural_Networks.h"

void Read_MNIST(string training_set_images, string training_set_labels, string test_set_images, string test_set_labels, int number_training, int number_test, float **input, float **target_output) {
	ifstream file(training_set_images, ifstream::binary);

	if (file.is_open()) {
		for (int h = 0, value; h < 4; h++) {
			file.read((char*)(&value), sizeof(int));
		}
		for (int h = 0; h < number_training; h++) {
			unsigned char pixel;

			for (int j = 0; j < 28 * 28; j++) {
				file.read((char*)(&pixel), 1);
				input[h][j] = pixel / 255.0;
			}
		}
		file.close();
	}
	else {
		cerr << "[Read_MNIST], " + training_set_images + " not found" << endl;
	}

	file.open(training_set_labels, ifstream::binary);

	if (file.is_open()) {
		for (int h = 0, value; h < 2; h++) {
			file.read((char*)(&value), sizeof(int));
		}
		for (int h = 0; h < number_training; h++) {
			unsigned char label;

			file.read((char*)(&label), 1);

			for (int j = 0; j < 10; j++) {
				target_output[h][j] = (j == label);
			}
		}
		file.close();
	}
	else {
		cerr << "[Read_MNIST], " + training_set_labels + " not found" << endl;
	}

	file.open(test_set_images, ifstream::binary);

	if (file.is_open()) {
		for (int h = 0, value; h < 4; h++) {
			file.read((char*)(&value), sizeof(int));
		}
		for (int h = number_training; h < number_training + number_test; h++) {
			unsigned char pixel;

			for (int j = 0; j < 28 * 28; j++) {
				file.read((char*)(&pixel), 1);
				input[h][j] = pixel / 255.0;
			}
		}
		file.close();
	}
	else {
		cerr << "[Read_MNIST], " + test_set_images + " not found" << endl;
	}

	file.open(test_set_labels, ifstream::binary);

	if (file.is_open()) {
		for (int h = 0, value; h < 2; h++) {
			file.read((char*)(&value), sizeof(int));
		}
		for (int h = number_training; h < number_training + number_test; h++) {
			unsigned char label;

			file.read((char*)(&label), 1);

			for (int j = 0; j < 10; j++) {
				target_output[h][j] = (j == label);
			}
		}
		file.close();
	}
	else {
		cerr << "[Read_MNIST], " + test_set_labels + " not found" << endl;
	}
}

int main() {
	int batch_size		= 60;
	int number_iterations = 50;
	int number_threads;
	int number_training = 60000;
	int number_test		= 10000;

	float **input = new float*[number_training + number_test];
	float **target_output = new float*[number_training + number_test];

	double learning_rate = 0.005;
	double decay_rate	 = 0.977;

	string path;

	vector<int> number_nodes = { 784, 10 };

	vector<Layer*> layer;

	// train from scratch *****************
	Neural_Networks NN = Neural_Networks();

	layer.push_back(NN.Add(new Layer("MNIST", 784)));
	layer.push_back(NN.Add(new Layer("BN,ReLU", 400)));		// batch normalization, ReLU activation
	layer.push_back(NN.Add(new Layer("BN,ReLU", 400)));		// batch normalization, ReLU activation
	layer.push_back(NN.Add(new Layer("CE,softmax", 10)));	// cross-entropy loss, softmax activation

	layer[1]->Connect(layer[0], "W"); // fully connected
	layer[2]->Connect(layer[1], "W"); // fully connected
	layer[3]->Connect(layer[2], "W"); // fully connected

	srand(0); NN.Initialize(0.01);
	// ************************************

	// or load pretrained model
	// Neural_Networks NN = Neural_Networks("MNIST_MLP.txt");

	cout << "The number of threads : ";
	cin >> number_threads;
	cin.ignore();

	cout << "path where MNIST handwritten digits dataset is : ";
	getline(cin, path);

	for (int h = 0; h < number_training + number_test; h++) {
		input[h] = new float[number_nodes.front()];
		target_output[h] = new float[number_nodes.back()];
	}
	Read_MNIST(path + "train-images.idx3-ubyte", path + "train-labels.idx1-ubyte", path + "t10k-images.idx3-ubyte", path + "t10k-labels.idx1-ubyte", number_training, number_test, input, target_output);

	omp_set_num_threads(number_threads);

	for (int g = 0, time = clock(); g < number_iterations; g++) {
		int score[2] = { 0, };

		float **output = new float*[batch_size];

		double loss = NN.Train(batch_size, number_training, input, target_output, learning_rate);

		for (int h = 0; h < batch_size; h++) {
			output[h] = new float[number_nodes.back()];
		}
		for (int i = 0, h = 0; i < number_training + number_test; i++) {
			if (++h == batch_size || i == number_training + number_test - 1) {
				NN.Test(h, &input[i - h + 1], output);

				for (int g = 0, argmax; g < h; g++) {
					double max = 0;

					for (int j = 0; j < number_nodes.back(); j++) {
						if (max < output[g][j]) {
							max = output[g][argmax = j];
						}
					}
					score[(i - h + g + 1 < number_training) ? (0) : (1)] += (int)target_output[i - h + g + 1][argmax];
				}
				h = 0;
			}
		}
		printf("."); NN.Save("NN.txt");

		printf("score: %d / %d, %d / %d  loss: %lf  step %d  %.2lf sec\n", score[0], number_training, score[1], number_test, loss, g + 1, (double)(clock() - time) / CLOCKS_PER_SEC);
		learning_rate *= decay_rate;

		for (int h = 0; h < batch_size; h++) {
			delete[] output[h];
		}
		delete[] output;
	}

	for (int h = 0; h < number_training + number_test; h++) {
		delete[] input[h];
		delete[] target_output[h];
	}
	delete[] input;
	delete[] target_output;

	return 0;
}
<commit_msg>Update MNIST_MLP.cpp<commit_after>#include <fstream>
#include <iostream>
#include <omp.h>
#include <stdio.h>
#include <time.h>

#include "../Neural_Networks.h"

void Read_MNIST(string training_set_images, string training_set_labels, string test_set_images, string test_set_labels, int number_training, int number_test, float **input, float **target_output) {
	ifstream file(training_set_images, ifstream::binary);

	if (file.is_open()) {
		for (int h = 0, value; h < 4; h++) {
			file.read((char*)(&value), sizeof(int));
		}
		for (int h = 0; h < number_training; h++) {
			unsigned char pixel;

			for (int j = 0; j < 28 * 28; j++) {
				file.read((char*)(&pixel), 1);
				input[h][j] = pixel / 255.0;
			}
		}
		file.close();
	}
	else {
		cerr << "[Read_MNIST], " + training_set_images + " not found" << endl;
	}

	file.open(training_set_labels, ifstream::binary);

	if (file.is_open()) {
		for (int h = 0, value; h < 2; h++) {
			file.read((char*)(&value), sizeof(int));
		}
		for (int h = 0; h < number_training; h++) {
			unsigned char label;

			file.read((char*)(&label), 1);

			for (int j = 0; j < 10; j++) {
				target_output[h][j] = (j == label);
			}
		}
		file.close();
	}
	else {
		cerr << "[Read_MNIST], " + training_set_labels + " not found" << endl;
	}

	file.open(test_set_images, ifstream::binary);

	if (file.is_open()) {
		for (int h = 0, value; h < 4; h++) {
			file.read((char*)(&value), sizeof(int));
		}
		for (int h = number_training; h < number_training + number_test; h++) {
			unsigned char pixel;

			for (int j = 0; j < 28 * 28; j++) {
				file.read((char*)(&pixel), 1);
				input[h][j] = pixel / 255.0;
			}
		}
		file.close();
	}
	else {
		cerr << "[Read_MNIST], " + test_set_images + " not found" << endl;
	}

	file.open(test_set_labels, ifstream::binary);

	if (file.is_open()) {
		for (int h = 0, value; h < 2; h++) {
			file.read((char*)(&value), sizeof(int));
		}
		for (int h = number_training; h < number_training + number_test; h++) {
			unsigned char label;

			file.read((char*)(&label), 1);

			for (int j = 0; j < 10; j++) {
				target_output[h][j] = (j == label);
			}
		}
		file.close();
	}
	else {
		cerr << "[Read_MNIST], " + test_set_labels + " not found" << endl;
	}
}

int main() {
	int batch_size		= 60;
	int number_iterations = 50;
	int number_threads;
	int number_training = 60000;
	int number_test		= 10000;

	float **input = new float*[number_training + number_test];
	float **target_output = new float*[number_training + number_test];

	double epsilon		 = 0.001;
	double learning_rate = 0.005;
	double decay_rate	 = 0.977;

	string path;

	vector<int> number_nodes = { 784, 10 };

	vector<Layer*> layer;

	// train from scratch *****************
	Neural_Networks NN = Neural_Networks();

	layer.push_back(NN.Add(new Layer("MNIST", 784)));
	layer.push_back(NN.Add(new Layer("BN,ReLU", 400)));		// batch normalization, ReLU activation
	layer.push_back(NN.Add(new Layer("BN,ReLU", 400)));		// batch normalization, ReLU activation
	layer.push_back(NN.Add(new Layer("CE,softmax", 10)));	// cross-entropy loss, softmax activation

	layer[1]->Connect(layer[0], "W"); // fully connected
	layer[2]->Connect(layer[1], "W"); // fully connected
	layer[3]->Connect(layer[2], "W"); // fully connected

	srand(0); NN.Initialize(0.01);
	// ************************************

	// or load pretrained model
	// Neural_Networks NN = Neural_Networks("MNIST_MLP.txt");

	cout << "The number of threads : ";
	cin >> number_threads;
	cin.ignore();

	cout << "path where MNIST handwritten digits dataset is : ";
	getline(cin, path);

	for (int h = 0; h < number_training + number_test; h++) {
		input[h] = new float[number_nodes.front()];
		target_output[h] = new float[number_nodes.back()];
	}
	Read_MNIST(path + "train-images.idx3-ubyte", path + "train-labels.idx1-ubyte", path + "t10k-images.idx3-ubyte", path + "t10k-labels.idx1-ubyte", number_training, number_test, input, target_output);

	omp_set_num_threads(number_threads);

	for (int g = 0, time = clock(); g < number_iterations; g++) {
		int score[2] = { 0, };

		float **output = new float*[batch_size];

		double loss = NN.Train(batch_size, number_training, input, target_output, learning_rate, epsilon);

		for (int h = 0; h < batch_size; h++) {
			output[h] = new float[number_nodes.back()];
		}
		for (int i = 0, h = 0; i < number_training + number_test; i++) {
			if (++h == batch_size || i == number_training + number_test - 1) {
				NN.Test(h, &input[i - h + 1], output);

				for (int g = 0, argmax; g < h; g++) {
					double max = 0;

					for (int j = 0; j < number_nodes.back(); j++) {
						if (max < output[g][j]) {
							max = output[g][argmax = j];
						}
					}
					score[(i - h + g + 1 < number_training) ? (0) : (1)] += (int)target_output[i - h + g + 1][argmax];
				}
				h = 0;
			}
		}
		printf("."); NN.Save("NN.txt");

		printf("score: %d / %d, %d / %d  loss: %lf  step %d  %.2lf sec\n", score[0], number_training, score[1], number_test, loss, g + 1, (double)(clock() - time) / CLOCKS_PER_SEC);
		learning_rate *= decay_rate;

		for (int h = 0; h < batch_size; h++) {
			delete[] output[h];
		}
		delete[] output;
	}

	for (int h = 0; h < number_training + number_test; h++) {
		delete[] input[h];
		delete[] target_output[h];
	}
	delete[] input;
	delete[] target_output;

	return 0;
}
<|endoftext|>


<commit_before>/**
 * This file is part of the CernVM File System.
 */

#include "cvmfs_config.h"
#include "malloc_heap.h"

#include <cassert>
#include <cstring>
#include <new>

#include "smalloc.h"

using namespace std;  // NOLINT

void *MallocHeap::Allocate(
  uint64_t size,
  void *header,
  unsigned header_size)
{
  assert(size > 0);
  assert(header_size <= size);
  uint64_t rounded_size = RoundUp8(size);
  int64_t real_size = rounded_size + sizeof(Tag);
  if (gauge_ + real_size > capacity_)
    return NULL;

  unsigned char *new_block = heap_ + gauge_;
  new (new_block) Tag(rounded_size);
  new_block += sizeof(Tag);
  memcpy(new_block, header, header_size);
  gauge_ += real_size;
  stored_ += rounded_size;
  num_blocks_++;
  return new_block;
}

void MallocHeap::Compact() {
  if (gauge_ == 0)
    return;

  // Not really a tag, just the top memory address
  Tag *heap_top = reinterpret_cast<Tag *>(heap_ + gauge_);
  Tag *current_tag = reinterpret_cast<Tag *>(heap_);
  Tag *next_tag = current_tag->JumpToNext();
  // Move a sliding window of two blocks over the heap and compact where
  // possible
  while (next_tag < heap_top) {
    if (current_tag->IsFree()) {
      if (next_tag->IsFree()) {
        // Adjacent free blocks, merge and try again
        current_tag->size -= sizeof(Tag) + next_tag->GetSize();
        next_tag = next_tag->JumpToNext();
      } else {
        // Free block followed by a reserved block, move memory and create a
        // new free tag at the end of the moved block
        int64_t free_space = current_tag->size;
        current_tag->size = next_tag->size;
        memmove(current_tag->GetBlock(),
                next_tag->GetBlock(), next_tag->GetSize());
        (*callback_ptr_)(BlockPtr(current_tag->GetBlock()));
        next_tag = current_tag->JumpToNext();
        next_tag->size = free_space;
      }
    } else {
      // Current block allocated, move on
      current_tag = next_tag;
      next_tag = next_tag->JumpToNext();
    }
  }

  gauge_ = (reinterpret_cast<unsigned char *>(current_tag) - heap_);
  if (!current_tag->IsFree())
    gauge_ += sizeof(Tag) + current_tag->GetSize();
}

void MallocHeap::MarkFree(void *block) {
  Tag *tag = reinterpret_cast<Tag *>(block) - 1;
  assert(tag->size > 0);
  tag->size = -(tag->size);
  stored_ -= tag->GetSize();
  num_blocks_--;
  // TODO(jblomer): if MarkFree() takes place at the top of the heap, one could
  // move back the gauge_ pointer.  If this is an optimiziation or unnecessary
  // extra work depends on how the MallocHeap is used.
}

uint64_t MallocHeap::GetSize(void *block) {
  Tag *tag = reinterpret_cast<Tag *>(block) - 1;
  assert(tag->size > 0);
  return tag->size;
}

MallocHeap::MallocHeap(uint64_t capacity, CallbackPtr callback_ptr)
  : callback_ptr_(callback_ptr)
  , capacity_(capacity)
  , gauge_(0)
  , stored_(0)
  , num_blocks_(0)
{
  assert(capacity_ > kMinCapacity);
  // Ensure 8-byte alignment
  assert((capacity_ % 8) == 0);
  heap_ = reinterpret_cast<unsigned char *>(sxmmap(capacity + 7));
  uintptr_t head = uintptr_t(heap_) % 8;
  if (head > 0)
    sxunmap(heap_, head);
  heap_ += head;
  uintptr_t tail = 7 - head;
  if (tail > 0)
    sxunmap(heap_ + capacity, tail);
}

MallocHeap::~MallocHeap() {
  sxunmap(heap_, capacity_);
}
<commit_msg>Remove unaligned munmap<commit_after>/**
 * This file is part of the CernVM File System.
 */

#include "cvmfs_config.h"
#include "malloc_heap.h"

#include <cassert>
#include <cstring>
#include <new>

#include "smalloc.h"

using namespace std;  // NOLINT

void *MallocHeap::Allocate(
  uint64_t size,
  void *header,
  unsigned header_size)
{
  assert(size > 0);
  assert(header_size <= size);
  uint64_t rounded_size = RoundUp8(size);
  int64_t real_size = rounded_size + sizeof(Tag);
  if (gauge_ + real_size > capacity_)
    return NULL;

  unsigned char *new_block = heap_ + gauge_;
  new (new_block) Tag(rounded_size);
  new_block += sizeof(Tag);
  memcpy(new_block, header, header_size);
  gauge_ += real_size;
  stored_ += rounded_size;
  num_blocks_++;
  return new_block;
}

void MallocHeap::Compact() {
  if (gauge_ == 0)
    return;

  // Not really a tag, just the top memory address
  Tag *heap_top = reinterpret_cast<Tag *>(heap_ + gauge_);
  Tag *current_tag = reinterpret_cast<Tag *>(heap_);
  Tag *next_tag = current_tag->JumpToNext();
  // Move a sliding window of two blocks over the heap and compact where
  // possible
  while (next_tag < heap_top) {
    if (current_tag->IsFree()) {
      if (next_tag->IsFree()) {
        // Adjacent free blocks, merge and try again
        current_tag->size -= sizeof(Tag) + next_tag->GetSize();
        next_tag = next_tag->JumpToNext();
      } else {
        // Free block followed by a reserved block, move memory and create a
        // new free tag at the end of the moved block
        int64_t free_space = current_tag->size;
        current_tag->size = next_tag->size;
        memmove(current_tag->GetBlock(),
                next_tag->GetBlock(), next_tag->GetSize());
        (*callback_ptr_)(BlockPtr(current_tag->GetBlock()));
        next_tag = current_tag->JumpToNext();
        next_tag->size = free_space;
      }
    } else {
      // Current block allocated, move on
      current_tag = next_tag;
      next_tag = next_tag->JumpToNext();
    }
  }

  gauge_ = (reinterpret_cast<unsigned char *>(current_tag) - heap_);
  if (!current_tag->IsFree())
    gauge_ += sizeof(Tag) + current_tag->GetSize();
}

void MallocHeap::MarkFree(void *block) {
  Tag *tag = reinterpret_cast<Tag *>(block) - 1;
  assert(tag->size > 0);
  tag->size = -(tag->size);
  stored_ -= tag->GetSize();
  num_blocks_--;
  // TODO(jblomer): if MarkFree() takes place at the top of the heap, one could
  // move back the gauge_ pointer.  If this is an optimiziation or unnecessary
  // extra work depends on how the MallocHeap is used.
}

uint64_t MallocHeap::GetSize(void *block) {
  Tag *tag = reinterpret_cast<Tag *>(block) - 1;
  assert(tag->size > 0);
  return tag->size;
}

MallocHeap::MallocHeap(uint64_t capacity, CallbackPtr callback_ptr)
  : callback_ptr_(callback_ptr)
  , capacity_(capacity)
  , gauge_(0)
  , stored_(0)
  , num_blocks_(0)
{
  assert(capacity_ > kMinCapacity);
  // Ensure 8-byte alignment
  assert((capacity_ % 8) == 0);
  heap_ = reinterpret_cast<unsigned char *>(sxmmap(capacity + 7));
  uintptr_t head = uintptr_t(heap_) % 8;
  heap_ += head;
}

MallocHeap::~MallocHeap() {
  sxunmap(heap_, capacity_);
}
<|endoftext|>