<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

 /*
  * $Log$
  * Revision 1.1  2003/09/16 14:33:36  neilg
  * PSVI/schema component model classes, with Makefile/configuration changes necessary to build them
  *
  */

#if !defined(PSVIHANDLER_HPP)
#define PSVIHANDLER_HPP

#include <xercesc/framework/psvi/PSVIElement.hpp>
#include <xercesc/framework/psvi/PSVIAttribute.hpp>

XERCES_CPP_NAMESPACE_BEGIN

/**
  * This abstract class provides the interface for the scanner to return
  * PSVI information to the application.
  *
  */
class XMLPARSER_EXPORT PSVIHandler
{
public:
    // -----------------------------------------------------------------------
    //  Constructors are hidden, just the virtual destructor is exposed
    // -----------------------------------------------------------------------
    /** @name Destructor */
    //@{
    virtual ~PSVIHandler()
    {
    }
    //@}

    /** @name The PSVI handler interface */
    //@{
    /** Receive notification of the PSVI properties of an element.
      * The scanner will issue this call after the XMLDocumentHandler
      * endElement call.  Since the scanner will issue the psviAttributes
      * call immediately after reading the start tag of an element, all element
      * content will be effectively bracketed by these two calls.
      * @param  localName The name of the element whose end tag was just
      *                     parsed.
      * @param  uri       The namespace to which the element is bound
      * @param  prefix  The string representing the prefix name
      * @param  elementInfo    Object containing the element's PSVI properties
      */
    virtual void handleElementPSVI
    (
        const   XMLElementDecl *        localName
        , const XMLCh* const            uri
        , const XMLCh* const            prefix
        , const PSVIElement *           elementInfo
    ) = 0;

    /**
      * Enables PSVI information about attributes to be passed back to the
      * application.  This callback will be made on *all*
      * elements; on elements with no attributes, the final parameter will
      * be null.
      * @param  localName The name of the element upon which start tag
      *          these attributes were encountered.
      * @param  uri       The namespace to which the element is bound
      * @param  prefix  The string representing the prefix name
      * @param  psviAttributes   Object containing the attributes' PSVI properties
      *          with information to identify them.
      */
    virtual void handleAttributesPSVI
    (
        const   XMLElementDecl *        localName
        , const XMLCh* const            uri
        , const XMLCh* const            prefix
        , const PSVIAttributeList *     psviAttributes
    ) = 0;

    //@}

protected :
    // -----------------------------------------------------------------------
    //  Hidden Constructors
    // -----------------------------------------------------------------------
    PSVIHandler()
    {
    }

private:
    // -----------------------------------------------------------------------
    //  Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    PSVIHandler(const PSVIHandler&);
    PSVIHandler& operator=(const PSVIHandler&);
};

XERCES_CPP_NAMESPACE_END

#endif
<commit_msg>clearly the local name of an element should be a string, not an XMLElementDecl...<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

 /*
  * $Log$
  * Revision 1.2  2003/09/22 15:03:06  neilg
  * clearly the local name of an element should be a string, not an XMLElementDecl...
  *
  * Revision 1.1  2003/09/16 14:33:36  neilg
  * PSVI/schema component model classes, with Makefile/configuration changes necessary to build them
  *
  */

#if !defined(PSVIHANDLER_HPP)
#define PSVIHANDLER_HPP

#include <xercesc/framework/psvi/PSVIElement.hpp>
#include <xercesc/framework/psvi/PSVIAttribute.hpp>

XERCES_CPP_NAMESPACE_BEGIN

/**
  * This abstract class provides the interface for the scanner to return
  * PSVI information to the application.
  *
  */
class XMLPARSER_EXPORT PSVIHandler
{
public:
    // -----------------------------------------------------------------------
    //  Constructors are hidden, just the virtual destructor is exposed
    // -----------------------------------------------------------------------
    /** @name Destructor */
    //@{
    virtual ~PSVIHandler()
    {
    }
    //@}

    /** @name The PSVI handler interface */
    //@{
    /** Receive notification of the PSVI properties of an element.
      * The scanner will issue this call after the XMLDocumentHandler
      * endElement call.  Since the scanner will issue the psviAttributes
      * call immediately after reading the start tag of an element, all element
      * content will be effectively bracketed by these two calls.
      * @param  localName The name of the element whose end tag was just
      *                     parsed.
      * @param  uri       The namespace to which the element is bound
      * @param  prefix  The string representing the prefix name
      * @param  elementInfo    Object containing the element's PSVI properties
      */
    virtual void handleElementPSVI
    (
        const   XMLCh *                 localName
        , const XMLCh* const            uri
        , const XMLCh* const            prefix
        , const PSVIElement *           elementInfo
    ) = 0;

    /**
      * Enables PSVI information about attributes to be passed back to the
      * application.  This callback will be made on *all*
      * elements; on elements with no attributes, the final parameter will
      * be null.
      * @param  localName The name of the element upon which start tag
      *          these attributes were encountered.
      * @param  uri       The namespace to which the element is bound
      * @param  prefix  The string representing the prefix name
      * @param  psviAttributes   Object containing the attributes' PSVI properties
      *          with information to identify them.
      */
    virtual void handleAttributesPSVI
    (
        const   XMLCh *                 localName
        , const XMLCh* const            uri
        , const XMLCh* const            prefix
        , const PSVIAttributeList *     psviAttributes
    ) = 0;

    //@}

protected :
    // -----------------------------------------------------------------------
    //  Hidden Constructors
    // -----------------------------------------------------------------------
    PSVIHandler()
    {
    }

private:
    // -----------------------------------------------------------------------
    //  Unimplemented constructors and operators
    // -----------------------------------------------------------------------
    PSVIHandler(const PSVIHandler&);
    PSVIHandler& operator=(const PSVIHandler&);
};

XERCES_CPP_NAMESPACE_END

#endif
<|endoftext|>


<commit_before>/*
 *
 * Copyright 2015, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

// Generates Objective C gRPC service interface out of Protobuf IDL.

#include <memory>

#include "src/compiler/config.h"
#include "src/compiler/objective_c_generator.h"
#include "src/compiler/objective_c_generator_helpers.h"

#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>

using ::google::protobuf::compiler::objectivec::ProtobufLibraryFrameworkName;
using ::google::protobuf::compiler::objectivec::
    IsProtobufLibraryBundledProtoFile;

class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
 public:
  ObjectiveCGrpcGenerator() {}
  virtual ~ObjectiveCGrpcGenerator() {}

  virtual bool Generate(const grpc::protobuf::FileDescriptor *file,
                        const ::grpc::string &parameter,
                        grpc::protobuf::compiler::GeneratorContext *context,
                        ::grpc::string *error) const {
    if (file->service_count() == 0) {
      // No services.  Do nothing.
      return true;
    }

    ::grpc::string file_name = google::protobuf::compiler::objectivec::FilePath(file);
    ::grpc::string prefix = file->options().objc_class_prefix();

    {
      // Generate .pbrpc.h

      ::grpc::string imports = ::grpc::string("#import \"") + file_name +
                               ".pbobjc.h\"\n\n"
                               "#import <ProtoRPC/ProtoService.h>\n"
                               "#import <ProtoRPC/ProtoRPC.h>\n"
                               "#import <RxLibrary/GRXWriteable.h>\n"
                               "#import <RxLibrary/GRXWriter.h>\n";

      // TODO(jcanizales): Instead forward-declare the input and output types
      // and import the files in the .pbrpc.m
      ::grpc::string proto_imports;
      for (int i = 0; i < file->dependency_count(); i++) {
        ::grpc::string header =
            grpc_objective_c_generator::MessageHeaderName(file->dependency(i));
        const grpc::protobuf::FileDescriptor *dependency = file->dependency(i);
        if (IsProtobufLibraryBundledProtoFile(dependency)) {
          ::grpc::string base_name = header;
          grpc_generator::StripPrefix(&base_name, "google/protobuf/");
          // create the import code snippet
          proto_imports +=
              "#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS\n"
              "  #import <" +
              ::grpc::string(ProtobufLibraryFrameworkName) + "/" + base_name +
              ">\n"
              "#else\n"
              "  #import \"" +
              header +
              "\"\n"
              "#endif\n";
        } else {
          proto_imports += ::grpc::string("#import \"") + header + "\"\n";
        }
      }

      ::grpc::string declarations;
      for (int i = 0; i < file->service_count(); i++) {
        const grpc::protobuf::ServiceDescriptor *service = file->service(i);
        declarations += grpc_objective_c_generator::GetHeader(service);
      }

      static const ::grpc::string kNonNullBegin =
          "\nNS_ASSUME_NONNULL_BEGIN\n\n";
      static const ::grpc::string kNonNullEnd = "\nNS_ASSUME_NONNULL_END\n";

      Write(context, file_name + ".pbrpc.h", imports + '\n' + proto_imports +
                                                 '\n' + kNonNullBegin +
                                                 declarations + kNonNullEnd);
    }

    {
      // Generate .pbrpc.m

      ::grpc::string imports = ::grpc::string("#import \"") + file_name +
                               ".pbrpc.h\"\n\n"
                               "#import <ProtoRPC/ProtoRPC.h>\n"
                               "#import <RxLibrary/GRXWriter+Immediate.h>\n";

      ::grpc::string definitions;
      for (int i = 0; i < file->service_count(); i++) {
        const grpc::protobuf::ServiceDescriptor *service = file->service(i);
        definitions += grpc_objective_c_generator::GetSource(service);
      }

      Write(context, file_name + ".pbrpc.m", imports + '\n' + definitions);
    }

    return true;
  }

 private:
  // Write the given code into the given file.
  void Write(grpc::protobuf::compiler::GeneratorContext *context,
             const ::grpc::string &filename, const ::grpc::string &code) const {
    std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> output(
        context->Open(filename));
    grpc::protobuf::io::CodedOutputStream coded_out(output.get());
    coded_out.WriteRaw(code.data(), code.size());
  }
};

int main(int argc, char *argv[]) {
  ObjectiveCGrpcGenerator generator;
  return grpc::protobuf::compiler::PluginMain(argc, argv, &generator);
}
<commit_msg>clang-format<commit_after>/*
 *
 * Copyright 2015, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

// Generates Objective C gRPC service interface out of Protobuf IDL.

#include <memory>

#include "src/compiler/config.h"
#include "src/compiler/objective_c_generator.h"
#include "src/compiler/objective_c_generator_helpers.h"

#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>

using ::google::protobuf::compiler::objectivec::ProtobufLibraryFrameworkName;
using ::google::protobuf::compiler::objectivec::
    IsProtobufLibraryBundledProtoFile;

class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
 public:
  ObjectiveCGrpcGenerator() {}
  virtual ~ObjectiveCGrpcGenerator() {}

  virtual bool Generate(const grpc::protobuf::FileDescriptor *file,
                        const ::grpc::string &parameter,
                        grpc::protobuf::compiler::GeneratorContext *context,
                        ::grpc::string *error) const {
    if (file->service_count() == 0) {
      // No services.  Do nothing.
      return true;
    }

    ::grpc::string file_name =
        google::protobuf::compiler::objectivec::FilePath(file);
    ::grpc::string prefix = file->options().objc_class_prefix();

    {
      // Generate .pbrpc.h

      ::grpc::string imports = ::grpc::string("#import \"") + file_name +
                               ".pbobjc.h\"\n\n"
                               "#import <ProtoRPC/ProtoService.h>\n"
                               "#import <ProtoRPC/ProtoRPC.h>\n"
                               "#import <RxLibrary/GRXWriteable.h>\n"
                               "#import <RxLibrary/GRXWriter.h>\n";

      // TODO(jcanizales): Instead forward-declare the input and output types
      // and import the files in the .pbrpc.m
      ::grpc::string proto_imports;
      for (int i = 0; i < file->dependency_count(); i++) {
        ::grpc::string header =
            grpc_objective_c_generator::MessageHeaderName(file->dependency(i));
        const grpc::protobuf::FileDescriptor *dependency = file->dependency(i);
        if (IsProtobufLibraryBundledProtoFile(dependency)) {
          ::grpc::string base_name = header;
          grpc_generator::StripPrefix(&base_name, "google/protobuf/");
          // create the import code snippet
          proto_imports +=
              "#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS\n"
              "  #import <" +
              ::grpc::string(ProtobufLibraryFrameworkName) + "/" + base_name +
              ">\n"
              "#else\n"
              "  #import \"" +
              header +
              "\"\n"
              "#endif\n";
        } else {
          proto_imports += ::grpc::string("#import \"") + header + "\"\n";
        }
      }

      ::grpc::string declarations;
      for (int i = 0; i < file->service_count(); i++) {
        const grpc::protobuf::ServiceDescriptor *service = file->service(i);
        declarations += grpc_objective_c_generator::GetHeader(service);
      }

      static const ::grpc::string kNonNullBegin =
          "\nNS_ASSUME_NONNULL_BEGIN\n\n";
      static const ::grpc::string kNonNullEnd = "\nNS_ASSUME_NONNULL_END\n";

      Write(context, file_name + ".pbrpc.h", imports + '\n' + proto_imports +
                                                 '\n' + kNonNullBegin +
                                                 declarations + kNonNullEnd);
    }

    {
      // Generate .pbrpc.m

      ::grpc::string imports = ::grpc::string("#import \"") + file_name +
                               ".pbrpc.h\"\n\n"
                               "#import <ProtoRPC/ProtoRPC.h>\n"
                               "#import <RxLibrary/GRXWriter+Immediate.h>\n";

      ::grpc::string definitions;
      for (int i = 0; i < file->service_count(); i++) {
        const grpc::protobuf::ServiceDescriptor *service = file->service(i);
        definitions += grpc_objective_c_generator::GetSource(service);
      }

      Write(context, file_name + ".pbrpc.m", imports + '\n' + definitions);
    }

    return true;
  }

 private:
  // Write the given code into the given file.
  void Write(grpc::protobuf::compiler::GeneratorContext *context,
             const ::grpc::string &filename, const ::grpc::string &code) const {
    std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> output(
        context->Open(filename));
    grpc::protobuf::io::CodedOutputStream coded_out(output.get());
    coded_out.WriteRaw(code.data(), code.size());
  }
};

int main(int argc, char *argv[]) {
  ObjectiveCGrpcGenerator generator;
  return grpc::protobuf::compiler::PluginMain(argc, argv, &generator);
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "compiler_llvm.h"

#include "base/stl_util.h"
#include "backend_options.h"
#include "class_linker.h"
#include "compiled_method.h"
#include "compiler.h"
#include "ir_builder.h"
#include "jni_compiler.h"
#include "llvm_compilation_unit.h"
#include "method_compiler.h"
#include "oat_compilation_unit.h"
#include "oat_file.h"
#include "stub_compiler.h"
#include "utils_llvm.h"
#include "verifier/method_verifier.h"

#include <llvm/LinkAllPasses.h>
#include <llvm/LinkAllVMCore.h>
#include <llvm/Support/ManagedStatic.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/Threading.h>

#if defined(ART_USE_PORTABLE_COMPILER)
namespace art {
void CompileOneMethod(Compiler& compiler,
                      const CompilerBackend compilerBackend,
                      const DexFile::CodeItem* code_item,
                      uint32_t access_flags, InvokeType invoke_type,
                      uint32_t class_def_idx, uint32_t method_idx, jobject class_loader,
                      const DexFile& dex_file,
                      LLVMInfo* llvm_info);
}
#endif

namespace llvm {
  extern bool TimePassesIsEnabled;
}

namespace {

pthread_once_t llvm_initialized = PTHREAD_ONCE_INIT;

void InitializeLLVM() {
  // Initialize LLVM internal data structure for multithreading
  llvm::llvm_start_multithreaded();

  // NOTE: Uncomment following line to show the time consumption of LLVM passes
  //llvm::TimePassesIsEnabled = true;

  // Initialize LLVM target-specific options.
  art::compiler_llvm::InitialBackendOptions();

  // Initialize LLVM target, MC subsystem, asm printer, and asm parser.
#if defined(ART_TARGET)
  // Don't initialize all targets on device. Just initialize the device's native target
  llvm::InitializeNativeTarget();
  llvm::InitializeNativeTargetAsmPrinter();
  llvm::InitializeNativeTargetAsmParser();
#else
  llvm::InitializeAllTargets();
  llvm::InitializeAllTargetMCs();
  llvm::InitializeAllAsmPrinters();
  llvm::InitializeAllAsmParsers();
#endif

  // Initialize LLVM optimization passes
  llvm::PassRegistry &registry = *llvm::PassRegistry::getPassRegistry();

  llvm::initializeCore(registry);
  llvm::initializeScalarOpts(registry);
  llvm::initializeIPO(registry);
  llvm::initializeAnalysis(registry);
  llvm::initializeIPA(registry);
  llvm::initializeTransformUtils(registry);
  llvm::initializeInstCombine(registry);
  llvm::initializeInstrumentation(registry);
  llvm::initializeTarget(registry);
}

// The Guard to Shutdown LLVM
// llvm::llvm_shutdown_obj llvm_guard;
// TODO: We are commenting out this line because this will cause SEGV from
// time to time.
// Two reasons: (1) the order of the destruction of static objects, or
//              (2) dlopen/dlclose side-effect on static objects.

} // anonymous namespace

namespace art {
namespace compiler_llvm {

llvm::Module* makeLLVMModuleContents(llvm::Module* module);

CompilerLLVM::CompilerLLVM(Compiler* compiler, InstructionSet insn_set)
    : compiler_(compiler), insn_set_(insn_set),
      num_cunits_lock_("compilation unit counter lock"), num_cunits_(0),
      plt_(insn_set) {

  // Initialize LLVM libraries
  pthread_once(&llvm_initialized, InitializeLLVM);
}

CompilerLLVM::~CompilerLLVM() {
}

LlvmCompilationUnit* CompilerLLVM::AllocateCompilationUnit() {
  MutexLock GUARD(Thread::Current(), num_cunits_lock_);
  LlvmCompilationUnit* cunit = new LlvmCompilationUnit(this, num_cunits_++);
  if (!bitcode_filename_.empty()) {
    cunit->SetBitcodeFileName(StringPrintf("%s-%zu", bitcode_filename_.c_str(), cunit->GetIndex()));
  }
  return cunit;
}

CompiledMethod* CompilerLLVM::
CompileDexMethod(OatCompilationUnit* oat_compilation_unit, InvokeType invoke_type) {
  UniquePtr<LlvmCompilationUnit> cunit(AllocateCompilationUnit());

#if defined(ART_USE_PORTABLE_COMPILER)
  std::string methodName(PrettyMethod(oat_compilation_unit->GetDexMethodIndex(),
                                      *oat_compilation_unit->GetDexFile()));
  if (insn_set_ == kX86) {
    // Use iceland
    UniquePtr<MethodCompiler> method_compiler(
        new MethodCompiler(cunit.get(), compiler_, oat_compilation_unit));

    return method_compiler->Compile();
  } else {

    // TODO: consolidate ArtCompileMethods
    CompileOneMethod(*compiler_,
                     kPortable,
                     oat_compilation_unit->GetCodeItem(),
                     oat_compilation_unit->access_flags_,
                     invoke_type,
                     oat_compilation_unit->GetClassDefIndex(),
                     oat_compilation_unit->GetDexMethodIndex(),
                     oat_compilation_unit->GetClassLoader(),
                     *oat_compilation_unit->GetDexFile(),
                     cunit->GetQuickContext()
                     );

    cunit->SetCompiler(compiler_);
    cunit->SetOatCompilationUnit(oat_compilation_unit);

    cunit->Materialize();

    Compiler::MethodReference mref(oat_compilation_unit->GetDexFile(),
                                   oat_compilation_unit->GetDexMethodIndex());
    return new CompiledMethod(compiler_->GetInstructionSet(),
                              cunit->GetCompiledCode(),
                              *verifier::MethodVerifier::GetDexGcMap(mref));
  }
#else
  UniquePtr<MethodCompiler> method_compiler(
      new MethodCompiler(cunit.get(), compiler_, oat_compilation_unit));

  return method_compiler->Compile();
#endif
}

CompiledMethod* CompilerLLVM::
CompileNativeMethod(OatCompilationUnit* oat_compilation_unit) {
  UniquePtr<LlvmCompilationUnit> cunit(AllocateCompilationUnit());

  UniquePtr<JniCompiler> jni_compiler(
      new JniCompiler(cunit.get(), *compiler_, oat_compilation_unit));

  return jni_compiler->Compile();
}

CompiledInvokeStub* CompilerLLVM::CreateInvokeStub(bool is_static,
                                                   char const *shorty) {
  UniquePtr<LlvmCompilationUnit> cunit(AllocateCompilationUnit());

  UniquePtr<StubCompiler> stub_compiler(
    new StubCompiler(cunit.get(), *compiler_));

  return stub_compiler->CreateInvokeStub(is_static, shorty);
}

CompiledInvokeStub* CompilerLLVM::CreateProxyStub(char const *shorty) {
  UniquePtr<LlvmCompilationUnit> cunit(AllocateCompilationUnit());

  UniquePtr<StubCompiler> stub_compiler(
    new StubCompiler(cunit.get(), *compiler_));

  return stub_compiler->CreateProxyStub(shorty);
}

} // namespace compiler_llvm
} // namespace art

inline static art::compiler_llvm::CompilerLLVM* ContextOf(art::Compiler& compiler) {
  void *compiler_context = compiler.GetCompilerContext();
  CHECK(compiler_context != NULL);
  return reinterpret_cast<art::compiler_llvm::CompilerLLVM*>(compiler_context);
}

inline static const art::compiler_llvm::CompilerLLVM* ContextOf(const art::Compiler& compiler) {
  void *compiler_context = compiler.GetCompilerContext();
  CHECK(compiler_context != NULL);
  return reinterpret_cast<const art::compiler_llvm::CompilerLLVM*>(compiler_context);
}

extern "C" void ArtInitCompilerContext(art::Compiler& compiler) {
  CHECK(compiler.GetCompilerContext() == NULL);

  art::compiler_llvm::CompilerLLVM* compiler_llvm =
      new art::compiler_llvm::CompilerLLVM(&compiler,
                                           compiler.GetInstructionSet());

  compiler.SetCompilerContext(compiler_llvm);
}

extern "C" void ArtUnInitCompilerContext(art::Compiler& compiler) {
  delete ContextOf(compiler);
  compiler.SetCompilerContext(NULL);
}
extern "C" art::CompiledMethod* ArtCompileMethod(art::Compiler& compiler,
                                                 const art::DexFile::CodeItem* code_item,
                                                 uint32_t access_flags,
                                                 art::InvokeType invoke_type,
                                                 uint32_t class_def_idx,
                                                 uint32_t method_idx,
                                                 jobject class_loader,
                                                 const art::DexFile& dex_file) {
  UNUSED(class_def_idx);  // TODO: this is used with Compiler::RequiresConstructorBarrier.
  art::ClassLinker *class_linker = art::Runtime::Current()->GetClassLinker();

  art::OatCompilationUnit oat_compilation_unit(
    class_loader, class_linker, dex_file, code_item,
    class_def_idx, method_idx, access_flags);
  art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
  art::CompiledMethod* result = compiler_llvm->CompileDexMethod(&oat_compilation_unit, invoke_type);
  return result;
}

extern "C" art::CompiledMethod* ArtLLVMJniCompileMethod(art::Compiler& compiler,
                                                        uint32_t access_flags, uint32_t method_idx,
                                                        const art::DexFile& dex_file) {
  art::ClassLinker *class_linker = art::Runtime::Current()->GetClassLinker();

  art::OatCompilationUnit oat_compilation_unit(
    NULL, class_linker, dex_file, NULL,
    0, method_idx, access_flags);

  art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
  art::CompiledMethod* result = compiler_llvm->CompileNativeMethod(&oat_compilation_unit);
  return result;
}

extern "C" art::CompiledInvokeStub* ArtCreateLLVMInvokeStub(art::Compiler& compiler,
                                                            bool is_static,
                                                            const char* shorty,
                                                            uint32_t shorty_len) {
  art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
  art::CompiledInvokeStub* result = compiler_llvm->CreateInvokeStub(is_static, shorty);
  return result;
}

extern "C" art::CompiledInvokeStub* ArtCreateProxyStub(art::Compiler& compiler,
                                                       const char* shorty,
                                                       uint32_t shorty_len) {
  art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
  art::CompiledInvokeStub* result = compiler_llvm->CreateProxyStub(shorty);
  return result;
}

extern "C" void compilerLLVMSetBitcodeFileName(art::Compiler& compiler,
                                               std::string const& filename) {
  ContextOf(compiler)->SetBitcodeFileName(filename);
}
<commit_msg>Start the ELF function index from 1 instead of 0.<commit_after>/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "compiler_llvm.h"

#include "base/stl_util.h"
#include "backend_options.h"
#include "class_linker.h"
#include "compiled_method.h"
#include "compiler.h"
#include "ir_builder.h"
#include "jni_compiler.h"
#include "llvm_compilation_unit.h"
#include "method_compiler.h"
#include "oat_compilation_unit.h"
#include "oat_file.h"
#include "stub_compiler.h"
#include "utils_llvm.h"
#include "verifier/method_verifier.h"

#include <llvm/LinkAllPasses.h>
#include <llvm/LinkAllVMCore.h>
#include <llvm/Support/ManagedStatic.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/Threading.h>

#if defined(ART_USE_PORTABLE_COMPILER)
namespace art {
void CompileOneMethod(Compiler& compiler,
                      const CompilerBackend compilerBackend,
                      const DexFile::CodeItem* code_item,
                      uint32_t access_flags, InvokeType invoke_type,
                      uint32_t class_def_idx, uint32_t method_idx, jobject class_loader,
                      const DexFile& dex_file,
                      LLVMInfo* llvm_info);
}
#endif

namespace llvm {
  extern bool TimePassesIsEnabled;
}

namespace {

pthread_once_t llvm_initialized = PTHREAD_ONCE_INIT;

void InitializeLLVM() {
  // Initialize LLVM internal data structure for multithreading
  llvm::llvm_start_multithreaded();

  // NOTE: Uncomment following line to show the time consumption of LLVM passes
  //llvm::TimePassesIsEnabled = true;

  // Initialize LLVM target-specific options.
  art::compiler_llvm::InitialBackendOptions();

  // Initialize LLVM target, MC subsystem, asm printer, and asm parser.
#if defined(ART_TARGET)
  // Don't initialize all targets on device. Just initialize the device's native target
  llvm::InitializeNativeTarget();
  llvm::InitializeNativeTargetAsmPrinter();
  llvm::InitializeNativeTargetAsmParser();
#else
  llvm::InitializeAllTargets();
  llvm::InitializeAllTargetMCs();
  llvm::InitializeAllAsmPrinters();
  llvm::InitializeAllAsmParsers();
#endif

  // Initialize LLVM optimization passes
  llvm::PassRegistry &registry = *llvm::PassRegistry::getPassRegistry();

  llvm::initializeCore(registry);
  llvm::initializeScalarOpts(registry);
  llvm::initializeIPO(registry);
  llvm::initializeAnalysis(registry);
  llvm::initializeIPA(registry);
  llvm::initializeTransformUtils(registry);
  llvm::initializeInstCombine(registry);
  llvm::initializeInstrumentation(registry);
  llvm::initializeTarget(registry);
}

// The Guard to Shutdown LLVM
// llvm::llvm_shutdown_obj llvm_guard;
// TODO: We are commenting out this line because this will cause SEGV from
// time to time.
// Two reasons: (1) the order of the destruction of static objects, or
//              (2) dlopen/dlclose side-effect on static objects.

} // anonymous namespace

namespace art {
namespace compiler_llvm {

llvm::Module* makeLLVMModuleContents(llvm::Module* module);

CompilerLLVM::CompilerLLVM(Compiler* compiler, InstructionSet insn_set)
    : compiler_(compiler), insn_set_(insn_set),
      num_cunits_lock_("compilation unit counter lock"), num_cunits_(0),
      plt_(insn_set) {

  // Initialize LLVM libraries
  pthread_once(&llvm_initialized, InitializeLLVM);
}

CompilerLLVM::~CompilerLLVM() {
}

LlvmCompilationUnit* CompilerLLVM::AllocateCompilationUnit() {
  MutexLock GUARD(Thread::Current(), num_cunits_lock_);
  LlvmCompilationUnit* cunit = new LlvmCompilationUnit(this, ++num_cunits_);
  if (!bitcode_filename_.empty()) {
    cunit->SetBitcodeFileName(StringPrintf("%s-%zu", bitcode_filename_.c_str(), cunit->GetIndex()));
  }
  return cunit;
}

CompiledMethod* CompilerLLVM::
CompileDexMethod(OatCompilationUnit* oat_compilation_unit, InvokeType invoke_type) {
  UniquePtr<LlvmCompilationUnit> cunit(AllocateCompilationUnit());

#if defined(ART_USE_PORTABLE_COMPILER)
  std::string methodName(PrettyMethod(oat_compilation_unit->GetDexMethodIndex(),
                                      *oat_compilation_unit->GetDexFile()));
  if (insn_set_ == kX86) {
    // Use iceland
    UniquePtr<MethodCompiler> method_compiler(
        new MethodCompiler(cunit.get(), compiler_, oat_compilation_unit));

    return method_compiler->Compile();
  } else {

    // TODO: consolidate ArtCompileMethods
    CompileOneMethod(*compiler_,
                     kPortable,
                     oat_compilation_unit->GetCodeItem(),
                     oat_compilation_unit->access_flags_,
                     invoke_type,
                     oat_compilation_unit->GetClassDefIndex(),
                     oat_compilation_unit->GetDexMethodIndex(),
                     oat_compilation_unit->GetClassLoader(),
                     *oat_compilation_unit->GetDexFile(),
                     cunit->GetQuickContext()
                     );

    cunit->SetCompiler(compiler_);
    cunit->SetOatCompilationUnit(oat_compilation_unit);

    cunit->Materialize();

    Compiler::MethodReference mref(oat_compilation_unit->GetDexFile(),
                                   oat_compilation_unit->GetDexMethodIndex());
    return new CompiledMethod(compiler_->GetInstructionSet(),
                              cunit->GetCompiledCode(),
                              *verifier::MethodVerifier::GetDexGcMap(mref));
  }
#else
  UniquePtr<MethodCompiler> method_compiler(
      new MethodCompiler(cunit.get(), compiler_, oat_compilation_unit));

  return method_compiler->Compile();
#endif
}

CompiledMethod* CompilerLLVM::
CompileNativeMethod(OatCompilationUnit* oat_compilation_unit) {
  UniquePtr<LlvmCompilationUnit> cunit(AllocateCompilationUnit());

  UniquePtr<JniCompiler> jni_compiler(
      new JniCompiler(cunit.get(), *compiler_, oat_compilation_unit));

  return jni_compiler->Compile();
}

CompiledInvokeStub* CompilerLLVM::CreateInvokeStub(bool is_static,
                                                   char const *shorty) {
  UniquePtr<LlvmCompilationUnit> cunit(AllocateCompilationUnit());

  UniquePtr<StubCompiler> stub_compiler(
    new StubCompiler(cunit.get(), *compiler_));

  return stub_compiler->CreateInvokeStub(is_static, shorty);
}

CompiledInvokeStub* CompilerLLVM::CreateProxyStub(char const *shorty) {
  UniquePtr<LlvmCompilationUnit> cunit(AllocateCompilationUnit());

  UniquePtr<StubCompiler> stub_compiler(
    new StubCompiler(cunit.get(), *compiler_));

  return stub_compiler->CreateProxyStub(shorty);
}

} // namespace compiler_llvm
} // namespace art

inline static art::compiler_llvm::CompilerLLVM* ContextOf(art::Compiler& compiler) {
  void *compiler_context = compiler.GetCompilerContext();
  CHECK(compiler_context != NULL);
  return reinterpret_cast<art::compiler_llvm::CompilerLLVM*>(compiler_context);
}

inline static const art::compiler_llvm::CompilerLLVM* ContextOf(const art::Compiler& compiler) {
  void *compiler_context = compiler.GetCompilerContext();
  CHECK(compiler_context != NULL);
  return reinterpret_cast<const art::compiler_llvm::CompilerLLVM*>(compiler_context);
}

extern "C" void ArtInitCompilerContext(art::Compiler& compiler) {
  CHECK(compiler.GetCompilerContext() == NULL);

  art::compiler_llvm::CompilerLLVM* compiler_llvm =
      new art::compiler_llvm::CompilerLLVM(&compiler,
                                           compiler.GetInstructionSet());

  compiler.SetCompilerContext(compiler_llvm);
}

extern "C" void ArtUnInitCompilerContext(art::Compiler& compiler) {
  delete ContextOf(compiler);
  compiler.SetCompilerContext(NULL);
}
extern "C" art::CompiledMethod* ArtCompileMethod(art::Compiler& compiler,
                                                 const art::DexFile::CodeItem* code_item,
                                                 uint32_t access_flags,
                                                 art::InvokeType invoke_type,
                                                 uint32_t class_def_idx,
                                                 uint32_t method_idx,
                                                 jobject class_loader,
                                                 const art::DexFile& dex_file) {
  UNUSED(class_def_idx);  // TODO: this is used with Compiler::RequiresConstructorBarrier.
  art::ClassLinker *class_linker = art::Runtime::Current()->GetClassLinker();

  art::OatCompilationUnit oat_compilation_unit(
    class_loader, class_linker, dex_file, code_item,
    class_def_idx, method_idx, access_flags);
  art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
  art::CompiledMethod* result = compiler_llvm->CompileDexMethod(&oat_compilation_unit, invoke_type);
  return result;
}

extern "C" art::CompiledMethod* ArtLLVMJniCompileMethod(art::Compiler& compiler,
                                                        uint32_t access_flags, uint32_t method_idx,
                                                        const art::DexFile& dex_file) {
  art::ClassLinker *class_linker = art::Runtime::Current()->GetClassLinker();

  art::OatCompilationUnit oat_compilation_unit(
    NULL, class_linker, dex_file, NULL,
    0, method_idx, access_flags);

  art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
  art::CompiledMethod* result = compiler_llvm->CompileNativeMethod(&oat_compilation_unit);
  return result;
}

extern "C" art::CompiledInvokeStub* ArtCreateLLVMInvokeStub(art::Compiler& compiler,
                                                            bool is_static,
                                                            const char* shorty,
                                                            uint32_t shorty_len) {
  art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
  art::CompiledInvokeStub* result = compiler_llvm->CreateInvokeStub(is_static, shorty);
  return result;
}

extern "C" art::CompiledInvokeStub* ArtCreateProxyStub(art::Compiler& compiler,
                                                       const char* shorty,
                                                       uint32_t shorty_len) {
  art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
  art::CompiledInvokeStub* result = compiler_llvm->CreateProxyStub(shorty);
  return result;
}

extern "C" void compilerLLVMSetBitcodeFileName(art::Compiler& compiler,
                                               std::string const& filename) {
  ContextOf(compiler)->SetBitcodeFileName(filename);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
const ll infty = 1000000000000000000;

typedef tuple<ll, ll, ll> state;

int main () {
  int N;
  cin >> N;
  ll a[200010];
  for (auto i = 0; i < N; ++i) {
    cin >> a[i];
  }
  priority_queue<state, vector<state>, greater<state> > Q;
  ll ans[200010];
  fill(ans, ans+200010, infty);
  for (auto i = 0; i < N; ++i) {
    Q.push(state(a[i], i, 0));
  }
  while(!Q.empty()) {
    ll num = get<0>(Q.top());
    ll place = get<1>(Q.top());
    ll dist = get<2>(Q.top());
    cerr << num << " " << place << " " << dist << endl;
    Q.pop();
    if (ans[place] == infty) {
      ans[place] = num;
      cerr << "ans[" << place << "] = " << num << endl;
      ll nplace[2] = {place + 1, place - 1};
      ll ndist = dist+1;
      ll nnum = num - dist * dist + ndist * ndist;
      for (auto j = 0; j < 2; ++j) {
        if (0 <= nplace[j] && nplace[j] < N) {
          Q.push(state(nnum, nplace[j], ndist));
        }
      }
    }
  }
  for (auto i = 0; i < N; ++i) {
    cout << ans[i] << endl;
  }
}
<commit_msg>submit C.cpp to 'C - スペースエクスプローラー高橋君' (colopl2018-final-open) [C++14 (GCC 5.4.1)]<commit_after>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
const ll infty = 1000000000000000000;

typedef tuple<ll, ll, ll> state;

int main () {
  int N;
  cin >> N;
  ll a[200010];
  for (auto i = 0; i < N; ++i) {
    cin >> a[i];
  }
  priority_queue<state, vector<state>, greater<state> > Q;
  ll ans[200010];
  fill(ans, ans+200010, infty);
  for (auto i = 0; i < N; ++i) {
    Q.push(state(a[i], i, 0));
  }
  while(!Q.empty()) {
    ll num = get<0>(Q.top());
    ll place = get<1>(Q.top());
    ll dist = get<2>(Q.top());
    cerr << num << " " << place << " " << dist << endl;
    Q.pop();
    if (ans[place] == infty) {
      ans[place] = num;
      cerr << "ans[" << place << "] = " << num << endl;
    }
    ll nplace[2] = {place + 1, place - 1};
    ll ndist = dist+1;
    ll nnum = num - dist * dist + ndist * ndist;
    for (auto j = 0; j < 2; ++j) {
      if (0 <= nplace[j] && nplace[j] < N && ans[nplace[j]] == infty) {
        Q.push(state(nnum, nplace[j], ndist));
      }
    }
  }
  for (auto i = 0; i < N; ++i) {
    cout << ans[i] << endl;
  }
}
<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 1 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

const ll infty = 10000000000000007;

struct edge {
  int to;
  ll cap;
  int rev;
};

vector<edge> G[100010];
bool used[100010];

void add_edge(int from, int to, ll cap) {
  G[from].push_back((edge){to, cap, (int)G[to].size()});
  G[to].push_back((edge){from, 0, (int)G[from].size()-1});
}

ll dfs(int v, int t, ll f) {
  if (v == t) return f;
  used[v] = true;
  for (auto& e : G[v]) {
    if (!used[e.to] && e.cap > 0) {
      ll d = dfs(e.to, t, min(f, e.cap));
      if (d > 0) {
        e.cap -= d;
        G[e.to][e.rev].cap += d;
        return d;
      }
    }
  }
  return 0;
}

ll max_flow(int s, int t) {
  ll flow = 0;
  while (true) {
    fill(used, used+100010, false);
    ll f = dfs(s, t, infty);
    if (f == 0) return flow;
    flow += f;
  }
}

typedef tuple<ll, int> state; // kachi, bit

int N;
ll x[20];
ll c[20];
ll v[20];
vector<state> V[20];

int main () {
  cin >> N;
  for (auto i = 0; i < N; ++i) {
    cin >> x[i];
  }
  for (auto i = 0; i < N-1; ++i) {
    x[i+1] += x[i];
  }
  for (auto i = 0; i < N; ++i) {
    cin >> c[i];
  }
  for (auto i = 0; i < N; ++i) {
    cin >> v[i];
  }
  for (auto i = 0; i < (1 << N); ++i) {
    ll kakaku = 0;
    ll kachi = 0;
    for (auto j = 0; j < N; ++j) {
      if ((i >> j) & 1) {
        kakaku += c[j];
        kachi += v[j];
      }
    }
    for (auto j = 0; j < N; ++j) {
      if (kakaku <= x[j]) {
        V[j].push_back(make_tuple(kachi, i));
        break;
      }
    }
  }
  ll ans = 0;
  for (auto i = 0; i < N; ++i) {
#if DEBUG == 1
    cerr << "ban item i+1 = " << i+1 << endl;
#endif
    sort(V[i].begin(), V[i].end());
    reverse(V[i].begin(), V[i].end());
    for (auto now = 1; now <= (int)V[i].size(); ++now) {
      // 0 start, 1 goal, 2...N+2 choten, N+2+i i
      for (auto j = 0; j <= N+2+now; ++j) {
        G[j].clear();
      }
      for (auto j = 0; j < N; ++j) {
        add_edge(0, j+2, 1);
      }
      for (auto j = 0; j < now; ++j) {
        int bit = get<1>(V[i][j]);
        for (auto k = 0; k < N; ++k) {
          if ((bit >> k) & 0) {
            add_edge(k+2, N+2+j, infty);
          }
        }
        add_edge(N+2+j, 1, 1);
      }
      ll f = N - max_flow(0, 1);
#if DEBUG == 1
      cerr << "now = " << now << ", f = " << f
           << ", bit = " << get<1>(V[i][now-1]) << endl;
#endif
      if (f <= i+1) {
        //
      } else {
#if DEBUG == 1
        cerr << "value = " << get<0>(V[i][now-1]) << endl;
#endif
        ans = max(ans, get<0>(V[i][now-1]));
        break;
      }
    }
  }
  cout << ans << endl;
}
<commit_msg>tried C.cpp to 'C'<commit_after>#include <iostream>
#include <iomanip> // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple> // get<n>(xxx)
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set> // S.insert(M);
// if (S.find(key) != S.end()) { }
// for (auto it=S.begin(); it != S.end(); it++) { }
// auto it = S.lower_bound(M);
#include <random> // random_device rd; mt19937 mt(rd());
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib> // atoi(xxx)
using namespace std;

#define DEBUG 1 // change 0 -> 1 if we need debug.
// insert #if<tab> by my emacs. #if DEBUG == 1 ... #end

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
// const ll M = 1000000007;

const ll infty = 10000000000000007;

struct edge {
  int to;
  ll cap;
  int rev;
};

vector<edge> G[100010];
bool used[100010];

void add_edge(int from, int to, ll cap) {
  G[from].push_back((edge){to, cap, (int)G[to].size()});
  G[to].push_back((edge){from, 0, (int)G[from].size()-1});
}

ll dfs(int v, int t, ll f) {
  if (v == t) return f;
  used[v] = true;
  for (auto& e : G[v]) {
    if (!used[e.to] && e.cap > 0) {
      ll d = dfs(e.to, t, min(f, e.cap));
      if (d > 0) {
        e.cap -= d;
        G[e.to][e.rev].cap += d;
        return d;
      }
    }
  }
  return 0;
}

ll max_flow(int s, int t) {
  ll flow = 0;
  while (true) {
    fill(used, used+100010, false);
    ll f = dfs(s, t, infty);
    if (f == 0) return flow;
    flow += f;
  }
}

typedef tuple<ll, int> state; // kachi, bit

int N;
ll x[20];
ll c[20];
ll v[20];
vector<state> V[20];

int main () {
  cin >> N;
  for (auto i = 0; i < N; ++i) {
    cin >> x[i];
  }
  for (auto i = 0; i < N-1; ++i) {
    x[i+1] += x[i];
  }
  for (auto i = 0; i < N; ++i) {
    cin >> c[i];
  }
  for (auto i = 0; i < N; ++i) {
    cin >> v[i];
  }
  for (auto i = 0; i < (1 << N); ++i) {
    ll kakaku = 0;
    ll kachi = 0;
    for (auto j = 0; j < N; ++j) {
      if ((i >> j) & 1) {
        kakaku += c[j];
        kachi += v[j];
      }
    }
    for (auto j = 0; j < N; ++j) {
      if (kakaku <= x[j]) {
        V[j].push_back(make_tuple(kachi, i));
        break;
      }
    }
  }
  ll ans = 0;
  for (auto i = 0; i < N; ++i) {
#if DEBUG == 1
    cerr << "ban item i+1 = " << i+1 << endl;
#endif
    sort(V[i].begin(), V[i].end());
    reverse(V[i].begin(), V[i].end());
    for (auto now = 1; now <= (int)V[i].size(); ++now) {
      // 0 start, 1 goal, 2...N+2 choten, N+2+i i
      for (auto j = 0; j <= N+2+now; ++j) {
        G[j].clear();
      }
      for (auto j = 0; j < N; ++j) {
        add_edge(0, j+2, 1);
      }
      for (auto j = 0; j < now; ++j) {
        int bit = get<1>(V[i][j]);
        for (auto k = 0; k < N; ++k) {
          if (((bit >> k) & 1) == 0) {
            add_edge(k+2, N+2+j, infty);
          }
        }
        add_edge(N+2+j, 1, 1);
      }
      ll f = N - max_flow(0, 1);
#if DEBUG == 1
      cerr << "now = " << now << ", f = " << f
           << ", bit = " << get<1>(V[i][now-1]) << endl;
#endif
      if (f <= i+1) {
        //
      } else {
#if DEBUG == 1
        cerr << "value = " << get<0>(V[i][now-1]) << endl;
#endif
        ans = max(ans, get<0>(V[i][now-1]));
        break;
      }
    }
  }
  cout << ans << endl;
}
<|endoftext|>


<commit_before>#ifndef STAN_MATH_PRIM_META_FORWARD_AS_HPP
#define STAN_MATH_PRIM_META_FORWARD_AS_HPP

#include <stan/math/prim/meta.hpp>
#include <type_traits>

namespace stan {
namespace math {

/** \ingroup type_trait
 * Assume which type we get. If actual type is convertible to assumed type or in
 * case of eigen types compile time rows and columns also match this is a no-op.
 * Otherwise it throws std::runtime_error, which should never happen if used as
 * intended.
 *
 * This is intended to be used in compile time branches that would otherwise
 * trigger compile error even though they are never executed.
 *
 * @tparam T_desired type of output we need to avoid compile time errors
 * @tparam T_actual actual type of the argument
 * @param a input value
 * @return the input value a
 */
template <typename T_desired, typename T_actual,
          typename
          = std::enable_if_t<std::is_convertible<T_actual, T_desired>::value
                             && !is_eigen<T_desired>::value>>
inline T_actual&& forward_as(T_actual&& a) {  // NOLINT
  return std::forward<T_actual>(a);
}

/** \ingroup type_trait
 * Assume which type we get. If actual type is not convertible to assumed type
 * or in case of eigen types compile time rows and columns are not the same this
 * has return type of \c T_desired, but it only throws. This version should only
 * be used where it is optimized away so the throw should never happen.
 *
 * This is intended to be used in compile time branches that would otherwise
 * trigger compile error even though they are never executed.
 *
 * @tparam T_desired type of output we need to avoid compile time errors
 * @tparam T_actual actual type of the argument
 * @param a input value
 * @return nothing, this always throws
 * @throw always throws std::runtime_error
 */
template <typename T_desired, typename T_actual,
          typename
          = std::enable_if_t<!std::is_convertible<T_actual, T_desired>::value>>
inline T_desired forward_as(const T_actual& a) {
  throw std::runtime_error("Wrong type assumed! Please file a bug report.");
}

/** \ingroup type_trait
 * Assume which type we get. If actual type is convertible to assumed type or in
 * case of eigen types compile time rows and columns also match this is a no-op.
 * Otherwise it throws std::runtime_error, which should never happen if used as
 * intended.
 *
 * This is intended to be used in compile time branches that would otherwise
 * trigger compile error even though they are never executed.
 *
 * @tparam T_desired type of output we need to avoid compile time errors
 * @tparam T_actual actual type of the argument
 * @param a input value
 * @return the input value a
 */
// clang-format off
template <typename T_desired, typename T_actual,
          typename = std::enable_if_t<
              std::is_convertible<T_actual, T_desired>::value && static_cast<
                  int>(T_desired::RowsAtCompileTime)
                  == static_cast<int>(std::decay_t<T_actual>::RowsAtCompileTime)
              && static_cast<int>(T_desired::ColsAtCompileTime)
                     == static_cast<int>(std::decay_t<T_actual>::ColsAtCompileTime)>,
          typename = void>
// clang-format on
inline T_actual&& forward_as(T_actual&& a) {  // NOLINT
  return std::forward<T_actual>(a);
}

/**
 * Assume which type we get. If actual type is not convertible to assumed type
 * or in case of eigen types compile time rows and columns are not the same this
 * has return type of \c T_desired, but it only throws. This version should only
 * be used where it is optimized away so the throw should never happen.
 *
 * This is intended to be used in compile time branches that would otherwise
 * trigger compile error even though they are never executed.
 *
 * @tparam T_desired type of output we need to avoid compile time errors
 * @tparam T_actual actual type of the argument
 * @param a input value
 * @return nothing, this always throws
 * @throw always throws std::runtime_error
 */
template <typename T_desired, typename T_actual,
          typename = std::enable_if_t<
              !std::is_convertible<T_actual, T_desired>::value
              || static_cast<int>(T_desired::RowsAtCompileTime)
                     != static_cast<int>(T_actual::RowsAtCompileTime)
              || static_cast<int>(T_desired::ColsAtCompileTime)
                     != static_cast<int>(T_actual::ColsAtCompileTime)>,
          typename = void>
inline T_desired forward_as(const T_actual& a) {
  throw std::runtime_error("Wrong type assumed! Please file a bug report.");
}

}  // namespace math
}  // namespace stan
#endif
<commit_msg>fixed cpplint<commit_after>#ifndef STAN_MATH_PRIM_META_FORWARD_AS_HPP
#define STAN_MATH_PRIM_META_FORWARD_AS_HPP

#include <stan/math/prim/meta.hpp>
#include <type_traits>

namespace stan {
namespace math {

/** \ingroup type_trait
 * Assume which type we get. If actual type is convertible to assumed type or in
 * case of eigen types compile time rows and columns also match this is a no-op.
 * Otherwise it throws std::runtime_error, which should never happen if used as
 * intended.
 *
 * This is intended to be used in compile time branches that would otherwise
 * trigger compile error even though they are never executed.
 *
 * @tparam T_desired type of output we need to avoid compile time errors
 * @tparam T_actual actual type of the argument
 * @param a input value
 * @return the input value a
 */
template <typename T_desired, typename T_actual,
          typename
          = std::enable_if_t<std::is_convertible<T_actual, T_desired>::value
                             && !is_eigen<T_desired>::value>>
inline T_actual&& forward_as(T_actual&& a) {  // NOLINT
  return std::forward<T_actual>(a);
}

/** \ingroup type_trait
 * Assume which type we get. If actual type is not convertible to assumed type
 * or in case of eigen types compile time rows and columns are not the same this
 * has return type of \c T_desired, but it only throws. This version should only
 * be used where it is optimized away so the throw should never happen.
 *
 * This is intended to be used in compile time branches that would otherwise
 * trigger compile error even though they are never executed.
 *
 * @tparam T_desired type of output we need to avoid compile time errors
 * @tparam T_actual actual type of the argument
 * @param a input value
 * @return nothing, this always throws
 * @throw always throws std::runtime_error
 */
template <typename T_desired, typename T_actual,
          typename
          = std::enable_if_t<!std::is_convertible<T_actual, T_desired>::value>>
inline T_desired forward_as(const T_actual& a) {
  throw std::runtime_error("Wrong type assumed! Please file a bug report.");
}

/** \ingroup type_trait
 * Assume which type we get. If actual type is convertible to assumed type or in
 * case of eigen types compile time rows and columns also match this is a no-op.
 * Otherwise it throws std::runtime_error, which should never happen if used as
 * intended.
 *
 * This is intended to be used in compile time branches that would otherwise
 * trigger compile error even though they are never executed.
 *
 * @tparam T_desired type of output we need to avoid compile time errors
 * @tparam T_actual actual type of the argument
 * @param a input value
 * @return the input value a
 */
template <
    typename T_desired, typename T_actual,
    typename = std::enable_if_t<
        std::is_convertible<T_actual, T_desired>::value&& static_cast<int>(
            T_desired::RowsAtCompileTime)
            == static_cast<int>(std::decay_t<T_actual>::RowsAtCompileTime)
        && static_cast<int>(T_desired::ColsAtCompileTime)
               == static_cast<int>(std::decay_t<T_actual>::ColsAtCompileTime)>,
    typename = void>
inline T_actual&& forward_as(T_actual&& a) {  // NOLINT
  return std::forward<T_actual>(a);
}

/**
 * Assume which type we get. If actual type is not convertible to assumed type
 * or in case of eigen types compile time rows and columns are not the same this
 * has return type of \c T_desired, but it only throws. This version should only
 * be used where it is optimized away so the throw should never happen.
 *
 * This is intended to be used in compile time branches that would otherwise
 * trigger compile error even though they are never executed.
 *
 * @tparam T_desired type of output we need to avoid compile time errors
 * @tparam T_actual actual type of the argument
 * @param a input value
 * @return nothing, this always throws
 * @throw always throws std::runtime_error
 */
template <typename T_desired, typename T_actual,
          typename = std::enable_if_t<
              !std::is_convertible<T_actual, T_desired>::value
              || static_cast<int>(T_desired::RowsAtCompileTime)
                     != static_cast<int>(T_actual::RowsAtCompileTime)
              || static_cast<int>(T_desired::ColsAtCompileTime)
                     != static_cast<int>(T_actual::ColsAtCompileTime)>,
          typename = void>
inline T_desired forward_as(const T_actual& a) {
  throw std::runtime_error("Wrong type assumed! Please file a bug report.");
}

}  // namespace math
}  // namespace stan
#endif
<|endoftext|>


<commit_before>#ifndef STAN_MATH_REV_SCAL_FUN_LOG_MIX_HPP
#define STAN_MATH_REV_SCAL_FUN_LOG_MIX_HPP

#include <stan/math/rev/meta.hpp>
#include <stan/math/prim/scal/fun/value_of.hpp>
#include <stan/math/prim/scal/fun/log_mix.hpp>
#include <stan/math/rev/scal/fun/value_of.hpp>
#include <cmath>

namespace stan {
namespace math {

/* Computes shared terms in log_mix partial derivative calculations
 *
 * @param[in] theta_val value of mixing proportion theta.
 * @param[in] lambda1_val value of log density multiplied by theta.
 * @param[in] lambda2_val value of log density multiplied by 1 - theta.
 * @param[out] one_m_exp_lam2_m_lam1 shared term in deriv calculation.
 * @param[out] one_m_t_prod_exp_lam2_m_lam1 shared term in deriv calculation.
 * @param[out] one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1 shared term in deriv
 * calculation.
 */
inline void log_mix_partial_helper(
    double theta_val, double lambda1_val, double lambda2_val,
    double& one_m_exp_lam2_m_lam1, double& one_m_t_prod_exp_lam2_m_lam1,
    double& one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1) {
  using std::exp;
  double lam2_m_lam1 = lambda2_val - lambda1_val;
  double exp_lam2_m_lam1 = exp(lam2_m_lam1);
  one_m_exp_lam2_m_lam1 = 1 - exp_lam2_m_lam1;
  double one_m_t = 1 - theta_val;
  one_m_t_prod_exp_lam2_m_lam1 = one_m_t * exp_lam2_m_lam1;
  one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1
      = 1 / (theta_val + one_m_t_prod_exp_lam2_m_lam1);
}

/**
 * Return the log mixture density with specified mixing proportion
 * and log densities and its derivative at each.
 *
 * \f[
 * \mbox{log\_mix}(\theta, \lambda_1, \lambda_2)
 * = \log \left( \theta \exp(\lambda_1) + (1 - \theta) \exp(\lambda_2) \right).
 * \f]
 *
 * \f[
 * \frac{\partial}{\partial \theta}
 * \mbox{log\_mix}(\theta, \lambda_1, \lambda_2)
 * = \dfrac{\exp(\lambda_1) - \exp(\lambda_2)}
 * {\left( \theta \exp(\lambda_1) + (1 - \theta) \exp(\lambda_2) \right)}
 * \f]
 *
 * \f[
 * \frac{\partial}{\partial \lambda_1}
 * \mbox{log\_mix}(\theta, \lambda_1, \lambda_2)
 * = \dfrac{\theta \exp(\lambda_1)}
 * {\left( \theta \exp(\lambda_1) + (1 - \theta) \exp(\lambda_2) \right)}
 * \f]
 *
 * \f[
 * \frac{\partial}{\partial \lambda_2}
 * \mbox{log\_mix}(\theta, \lambda_1, \lambda_2)
 * = \dfrac{\theta \exp(\lambda_2)}
 * {\left( \theta \exp(\lambda_1) + (1 - \theta) \exp(\lambda_2) \right)}
 * \f]
 *
 * @tparam T_theta theta scalar type.
 * @tparam T_lambda1 lambda1 scalar type.
 * @tparam T_lambda2 lambda2 scalar type.
 *
 * @param[in] theta mixing proportion in [0, 1].
 * @param[in] lambda1 first log density.
 * @param[in] lambda2 second log density.
 * @return log mixture of densities in specified proportion
 */
template <typename T_theta, typename T_lambda1, typename T_lambda2>
inline typename return_type<T_theta, T_lambda1, T_lambda2>::type log_mix(
    const T_theta& theta, const T_lambda1& lambda1, const T_lambda2& lambda2) {
  using std::log;

  operands_and_partials<T_theta, T_lambda1, T_lambda2> ops_partials(
      theta, lambda1, lambda2);

  double theta_double = value_of(theta);
  const double lambda1_double = value_of(lambda1);
  const double lambda2_double = value_of(lambda2);

  double log_mix_function_value
      = log_mix(theta_double, lambda1_double, lambda2_double);

  double one_m_exp_lam2_m_lam1(0.0);
  double one_m_t_prod_exp_lam2_m_lam1(0.0);
  double one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1(0.0);

  if (lambda1 > lambda2) {
    log_mix_partial_helper(theta_double, lambda1_double, lambda2_double,
                           one_m_exp_lam2_m_lam1, one_m_t_prod_exp_lam2_m_lam1,
                           one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1);
  } else {
    log_mix_partial_helper(1.0 - theta_double, lambda2_double, lambda1_double,
                           one_m_exp_lam2_m_lam1, one_m_t_prod_exp_lam2_m_lam1,
                           one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1);
    one_m_exp_lam2_m_lam1 = -one_m_exp_lam2_m_lam1;
    theta_double = one_m_t_prod_exp_lam2_m_lam1;
    one_m_t_prod_exp_lam2_m_lam1 = 1.0 - value_of(theta);
  }

  if (!is_constant_all<T_theta>::value)
    ops_partials.edge1_.partials_[0]
        = one_m_exp_lam2_m_lam1 * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;
  if (!is_constant_all<T_lambda1>::value)
    ops_partials.edge2_.partials_[0]
        = theta_double * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;
  if (!is_constant_all<T_lambda2>::value)
    ops_partials.edge3_.partials_[0]
        = one_m_t_prod_exp_lam2_m_lam1
          * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;

  return ops_partials.build(log_mix_function_value);
}

}  // namespace math
}  // namespace stan
#endif
<commit_msg>clean up another raw return type statement<commit_after>#ifndef STAN_MATH_REV_SCAL_FUN_LOG_MIX_HPP
#define STAN_MATH_REV_SCAL_FUN_LOG_MIX_HPP

#include <stan/math/rev/meta.hpp>
#include <stan/math/prim/scal/fun/value_of.hpp>
#include <stan/math/prim/scal/fun/log_mix.hpp>
#include <stan/math/rev/scal/fun/value_of.hpp>
#include <cmath>

namespace stan {
namespace math {

/* Computes shared terms in log_mix partial derivative calculations
 *
 * @param[in] theta_val value of mixing proportion theta.
 * @param[in] lambda1_val value of log density multiplied by theta.
 * @param[in] lambda2_val value of log density multiplied by 1 - theta.
 * @param[out] one_m_exp_lam2_m_lam1 shared term in deriv calculation.
 * @param[out] one_m_t_prod_exp_lam2_m_lam1 shared term in deriv calculation.
 * @param[out] one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1 shared term in deriv
 * calculation.
 */
inline void log_mix_partial_helper(
    double theta_val, double lambda1_val, double lambda2_val,
    double& one_m_exp_lam2_m_lam1, double& one_m_t_prod_exp_lam2_m_lam1,
    double& one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1) {
  using std::exp;
  double lam2_m_lam1 = lambda2_val - lambda1_val;
  double exp_lam2_m_lam1 = exp(lam2_m_lam1);
  one_m_exp_lam2_m_lam1 = 1 - exp_lam2_m_lam1;
  double one_m_t = 1 - theta_val;
  one_m_t_prod_exp_lam2_m_lam1 = one_m_t * exp_lam2_m_lam1;
  one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1
      = 1 / (theta_val + one_m_t_prod_exp_lam2_m_lam1);
}

/**
 * Return the log mixture density with specified mixing proportion
 * and log densities and its derivative at each.
 *
 * \f[
 * \mbox{log\_mix}(\theta, \lambda_1, \lambda_2)
 * = \log \left( \theta \exp(\lambda_1) + (1 - \theta) \exp(\lambda_2) \right).
 * \f]
 *
 * \f[
 * \frac{\partial}{\partial \theta}
 * \mbox{log\_mix}(\theta, \lambda_1, \lambda_2)
 * = \dfrac{\exp(\lambda_1) - \exp(\lambda_2)}
 * {\left( \theta \exp(\lambda_1) + (1 - \theta) \exp(\lambda_2) \right)}
 * \f]
 *
 * \f[
 * \frac{\partial}{\partial \lambda_1}
 * \mbox{log\_mix}(\theta, \lambda_1, \lambda_2)
 * = \dfrac{\theta \exp(\lambda_1)}
 * {\left( \theta \exp(\lambda_1) + (1 - \theta) \exp(\lambda_2) \right)}
 * \f]
 *
 * \f[
 * \frac{\partial}{\partial \lambda_2}
 * \mbox{log\_mix}(\theta, \lambda_1, \lambda_2)
 * = \dfrac{\theta \exp(\lambda_2)}
 * {\left( \theta \exp(\lambda_1) + (1 - \theta) \exp(\lambda_2) \right)}
 * \f]
 *
 * @tparam T_theta theta scalar type.
 * @tparam T_lambda1 lambda1 scalar type.
 * @tparam T_lambda2 lambda2 scalar type.
 *
 * @param[in] theta mixing proportion in [0, 1].
 * @param[in] lambda1 first log density.
 * @param[in] lambda2 second log density.
 * @return log mixture of densities in specified proportion
 */
template <typename T_theta, typename T_lambda1, typename T_lambda2>
inline return_type_t<T_theta, T_lambda1, T_lambda2> log_mix(
    const T_theta& theta, const T_lambda1& lambda1, const T_lambda2& lambda2) {
  using std::log;

  operands_and_partials<T_theta, T_lambda1, T_lambda2> ops_partials(
      theta, lambda1, lambda2);

  double theta_double = value_of(theta);
  const double lambda1_double = value_of(lambda1);
  const double lambda2_double = value_of(lambda2);

  double log_mix_function_value
      = log_mix(theta_double, lambda1_double, lambda2_double);

  double one_m_exp_lam2_m_lam1(0.0);
  double one_m_t_prod_exp_lam2_m_lam1(0.0);
  double one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1(0.0);

  if (lambda1 > lambda2) {
    log_mix_partial_helper(theta_double, lambda1_double, lambda2_double,
                           one_m_exp_lam2_m_lam1, one_m_t_prod_exp_lam2_m_lam1,
                           one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1);
  } else {
    log_mix_partial_helper(1.0 - theta_double, lambda2_double, lambda1_double,
                           one_m_exp_lam2_m_lam1, one_m_t_prod_exp_lam2_m_lam1,
                           one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1);
    one_m_exp_lam2_m_lam1 = -one_m_exp_lam2_m_lam1;
    theta_double = one_m_t_prod_exp_lam2_m_lam1;
    one_m_t_prod_exp_lam2_m_lam1 = 1.0 - value_of(theta);
  }

  if (!is_constant_all<T_theta>::value)
    ops_partials.edge1_.partials_[0]
        = one_m_exp_lam2_m_lam1 * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;
  if (!is_constant_all<T_lambda1>::value)
    ops_partials.edge2_.partials_[0]
        = theta_double * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;
  if (!is_constant_all<T_lambda2>::value)
    ops_partials.edge3_.partials_[0]
        = one_m_t_prod_exp_lam2_m_lam1
          * one_d_t_plus_one_m_t_prod_exp_lam2_m_lam1;

  return ops_partials.build(log_mix_function_value);
}

}  // namespace math
}  // namespace stan
#endif
<|endoftext|>


<commit_before>// $Id$
// Category: geometry
//
// See the class description in the header file.

#include "AliDetConstruction.h"
#include "AliSingleModuleConstruction.h"
#include "AliDetSwitch.h"
#include "AliGlobals.h"
#include "AliRun.h"
#include "AliModule.h"

AliDetConstruction::AliDetConstruction()
  : fTopVolumeName("ALIC")
{
  // initialize det switch vector:
  // moduleName nofVersions defaultVersion PPRVersion [type isStandalone]
        // det switch objects are deleted in
	// tbe base class (AliModulesCompositions) destructor

  AliDetSwitch* detSwitch;
  detSwitch = new AliDetSwitch("ABSO",   1, 0, 0, kStructure);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("DIPO",   3, 2, 2, kStructure, false);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("FRAME",  2, 1, 1, kStructure, false);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("HALL",   1, 0, 0, kStructure);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("MAG",    1, 0, 0, kStructure);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("PIPE",   5, 0, 0, kStructure);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("SHIL",   1, 0, 0, kStructure);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("CASTOR", 2, 1, 1);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("FMD",    2, 0, 0);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("ITS",   10, 7, 7);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("MUON",   2, 1, 1);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("PHOS",   5, 1, 1);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("PMD",    3, 1, 1);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("RICH",   3, 1, 1);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("START",  2, 1, 1);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("TOF",    5, 2, 2, kDetector, false);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("TPC",    4, 2, 2);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("TRD",    2, 1, 1, kDetector, false);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("ZDC",    2, 1, 1, kDetector, false);
  AddDetSwitch(detSwitch);
}

AliDetConstruction::AliDetConstruction(const AliDetConstruction& right)
  : AliModulesComposition(right)
{
  // AliModuleComposition is protected from copying
}

AliDetConstruction::~AliDetConstruction() {
//
}

// operators

AliDetConstruction&
AliDetConstruction::operator=(const AliDetConstruction& right)
{
  // check assignement to self
  if (this == &right) return *this;

  // base class assignement
  // AliModuleComposition is protected from assigning
  AliModulesComposition::operator=(right);

  return *this;
}

// private methods

void AliDetConstruction::BuildDetectors()
{
// Create module constructions for AliModules
// that have been created and registered by gAlice
// ---

  TObjArray* pDetectors = gAlice->Detectors();
  TIter next(pDetectors);

  // the first AliModule is expected to be the top volume
  AliModule *module = (AliModule*)next();
  if (G4String(module->GetName()) != "BODY") {
    G4String text = "AliDetConstruction::BuildDetectors():\n";
    text = text + "    Instead of BODY - the first module ";
    text = text + module->GetName() + " has been found.";
    AliGlobals::Exception(text);
  }
  AddSingleModuleConstruction("BODY", 0, kStructure);

  G4bool first = true;
  while ((module = (AliModule*)next())) {
    // register moduleConstruction in fDetSwitchVector
    // in order to keep availability of /AlDet/list command
    G4String modName = module->GetName();
    G4int modVersion = module->IsVersion();
    if (first)
      // skip registering of the top volume
      first = false;
    else
      SwitchDetOn(modName, modVersion);

    // all modules will be processed alltogether
    AddMoreModuleConstruction(modName, modVersion);

    G4cout << "Created module construction for "
           << modName << "v" << modVersion << "." << G4endl;
  }

  // do not process Config.C
  // (it was processed when creating modules by gAlice)
  SetProcessConfigToModules(false);
}

void AliDetConstruction::CreateDetectors()
{
// Creates AliModules and their module constructions
// according to the fDetSwitchVector
// ---

  // add top volume (AliBODY) construction first
  AddSingleModuleConstruction("BODY", 0, kStructure);

  // add modules constructions
  for (G4int id=0; id<fDetSwitchVector.entries(); id++)
  {
    G4String detName = fDetSwitchVector[id]->GetDetName();
    G4int version = fDetSwitchVector[id]->GetSwitchedVersion();
    G4bool isStandalone = fDetSwitchVector[id]->IsStandalone();
    AliModuleType type = fDetSwitchVector[id]->GetType();

    if (version > -1)
      if (isStandalone)
        AddSingleModuleConstruction(detName, version, type);
      else
        AddMoreModuleConstruction(detName, version, type);
  }
}

void AliDetConstruction::CheckDetDependencies()
{
// Checks modules dependencies.
// Dependent modules FRAME, TOF, TRD
// TOF always requires FRAMEv1
// TRD can be built with both (??)
// ZDC requires DIPO
// ---

  // get switched versions of dependent modules
  G4int verTOF = GetDetSwitch("TOF")->GetSwitchedVersion();
  G4int verTRD = GetDetSwitch("TRD")->GetSwitchedVersion();
  G4int verZDC = GetDetSwitch("ZDC")->GetSwitchedVersion();
  G4int verFRAME = GetDetSwitch("FRAME")->GetSwitchedVersion();

  // check dependencies
  if (verTOF > -1) {
    // TOF requires FRAMEv1
    if (verFRAME != 1) {
      GetDetSwitch("FRAME")->SwitchOn(1);
      G4String text = "AliDetConstruction::CheckDetDependencies: \n";
      text = text + "    Switched TOF requires FRAME v1.\n";
      text = text + "    The det switch for FRAME has been changed.";
      AliGlobals::Warning(text);
    }
  }
  if (verTRD > -1) {
    // TRD requires FRAME
    verFRAME = GetDetSwitch("FRAME")->GetSwitchedVersion();
    if (verFRAME < 0) {
      GetDetSwitch("FRAME")->SwitchOnDefault();
      G4String text = "AliDetConstruction::CheckDetDependencies: \n";
      text = text + "    Switched TRD requires FRAME.\n";
      text = text + "    The det switch for FRAME has been changed.";
      AliGlobals::Warning(text);
    }
  }
  if (verZDC > 0) {
    // ZDC requires PIPE, ABSO, DIPO, SHIL
    G4int verPIPE = GetDetSwitch("PIPE")->GetSwitchedVersion();
    G4int verABSO = GetDetSwitch("ABSO")->GetSwitchedVersion();
    G4int verDIPO = GetDetSwitch("DIPO")->GetSwitchedVersion();
    G4int verSHIL = GetDetSwitch("SHIL")->GetSwitchedVersion();
    if ( verPIPE != 1 || verABSO !=0 || verDIPO == -1 || verSHIL == -1) {
      G4String text = "AliDetConstruction::CheckDetDependencies: \n";
      text = text + "    Switched ZDC requires PIPE, ABSO, DIPO and SHIL.\n";
      if (verPIPE == -1) {
        GetDetSwitch("PIPE")->SwitchOnDefault();
        text = text + "    The det switch for PIPE has been changed.\n";
      }
      if (verABSO == -1) {
        GetDetSwitch("ABSO")->SwitchOnDefault();
        text = text + "    The det switch for ABSO has been changed.\n";
      }
      if (verDIPO == -1) {
        GetDetSwitch("DIPO")->SwitchOnDefault();
        text = text + "    The det switch for DIPO has been changed.\n";
      }
      if (verSHIL == -1) {
        GetDetSwitch("SHIL")->SwitchOnDefault();
        text = text + "    The det switch for SHIL has been changed.";
      }
      AliGlobals::Warning(text);
    }
  }
}

// public methods

G4VPhysicalVolume* AliDetConstruction::Construct()
{
// Constructs geometry.
// This method is called by G4RunManager in initialization.
// ---

  if (gAlice->Modules()->GetLast() < 0) {
    // create geometry (including AliModules) according to
    // the fDetSwitchVector
    CheckDetDependencies();
    CreateDetectors();
  }
  else {
    // create geometry for AliModules
    // that have been created and registered by gAlice
    BuildDetectors();
  }
  // construct modules geometry
  ConstructModules();

  return AliSingleModuleConstruction::GetWorld();
}

<commit_msg>updated default versions of FRAME, ITS<commit_after>// $Id$
// Category: geometry
//
// See the class description in the header file.

#include "AliDetConstruction.h"
#include "AliSingleModuleConstruction.h"
#include "AliDetSwitch.h"
#include "AliGlobals.h"
#include "AliRun.h"
#include "AliModule.h"

AliDetConstruction::AliDetConstruction()
  : fTopVolumeName("ALIC")
{
  // initialize det switch vector:
  // moduleName nofVersions defaultVersion PPRVersion [type isStandalone]
        // det switch objects are deleted in
	// tbe base class (AliModulesCompositions) destructor

  AliDetSwitch* detSwitch;
  detSwitch = new AliDetSwitch("ABSO",   1, 0, 0, kStructure);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("DIPO",   3, 2, 2, kStructure, false);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("FRAME",  3, 2, 2, kStructure, false);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("HALL",   1, 0, 0, kStructure);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("MAG",    1, 0, 0, kStructure);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("PIPE",   5, 0, 0, kStructure);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("SHIL",   1, 0, 0, kStructure);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("CASTOR", 2, 1, 1);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("FMD",    2, 0, 0);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("ITS",    7, 5, 5);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("MUON",   2, 1, 1);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("PHOS",   5, 1, 1);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("PMD",    3, 1, 1);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("RICH",   3, 1, 1);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("START",  2, 1, 1);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("TOF",    5, 2, 2, kDetector, false);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("TPC",    4, 2, 2);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("TRD",    2, 1, 1, kDetector, false);
  AddDetSwitch(detSwitch);
  detSwitch = new AliDetSwitch("ZDC",    2, 1, 1, kDetector, false);
  AddDetSwitch(detSwitch);
}

AliDetConstruction::AliDetConstruction(const AliDetConstruction& right)
  : AliModulesComposition(right)
{
  // AliModuleComposition is protected from copying
}

AliDetConstruction::~AliDetConstruction() {
//
}

// operators

AliDetConstruction&
AliDetConstruction::operator=(const AliDetConstruction& right)
{
  // check assignement to self
  if (this == &right) return *this;

  // base class assignement
  // AliModuleComposition is protected from assigning
  AliModulesComposition::operator=(right);

  return *this;
}

// private methods

void AliDetConstruction::BuildDetectors()
{
// Create module constructions for AliModules
// that have been created and registered by gAlice
// ---

  TObjArray* pDetectors = gAlice->Detectors();
  TIter next(pDetectors);

  // the first AliModule is expected to be the top volume
  AliModule *module = (AliModule*)next();
  if (G4String(module->GetName()) != "BODY") {
    G4String text = "AliDetConstruction::BuildDetectors():\n";
    text = text + "    Instead of BODY - the first module ";
    text = text + module->GetName() + " has been found.";
    AliGlobals::Exception(text);
  }
  AddSingleModuleConstruction("BODY", 0, kStructure);

  G4bool first = true;
  while ((module = (AliModule*)next())) {
    // register moduleConstruction in fDetSwitchVector
    // in order to keep availability of /AlDet/list command
    G4String modName = module->GetName();
    G4int modVersion = module->IsVersion();
    if (first)
      // skip registering of the top volume
      first = false;
    else
      SwitchDetOn(modName, modVersion);

    // all modules will be processed alltogether
    AddMoreModuleConstruction(modName, modVersion);

    G4cout << "Created module construction for "
           << modName << "v" << modVersion << "." << G4endl;
  }

  // do not process Config.C
  // (it was processed when creating modules by gAlice)
  SetProcessConfigToModules(false);
}

void AliDetConstruction::CreateDetectors()
{
// Creates AliModules and their module constructions
// according to the fDetSwitchVector
// ---

  // add top volume (AliBODY) construction first
  AddSingleModuleConstruction("BODY", 0, kStructure);

  // add modules constructions
  for (G4int id=0; id<fDetSwitchVector.entries(); id++)
  {
    G4String detName = fDetSwitchVector[id]->GetDetName();
    G4int version = fDetSwitchVector[id]->GetSwitchedVersion();
    G4bool isStandalone = fDetSwitchVector[id]->IsStandalone();
    AliModuleType type = fDetSwitchVector[id]->GetType();

    if (version > -1)
      if (isStandalone)
        AddSingleModuleConstruction(detName, version, type);
      else
        AddMoreModuleConstruction(detName, version, type);
  }
}

void AliDetConstruction::CheckDetDependencies()
{
// Checks modules dependencies.
// Dependent modules FRAME, TOF, TRD
// TOF always requires FRAMEv1
// TRD can be built with both (??)
// ZDC requires DIPO
// ---

  // get switched versions of dependent modules
  G4int verTOF = GetDetSwitch("TOF")->GetSwitchedVersion();
  G4int verTRD = GetDetSwitch("TRD")->GetSwitchedVersion();
  G4int verZDC = GetDetSwitch("ZDC")->GetSwitchedVersion();
  G4int verFRAME = GetDetSwitch("FRAME")->GetSwitchedVersion();

  // check dependencies
  if (verTOF > -1) {
    // TOF requires FRAMEv1 - obsolete?
    if (verFRAME != 2) {
      GetDetSwitch("FRAME")->SwitchOn(2);
      G4String text = "AliDetConstruction::CheckDetDependencies: \n";
      text = text + "    Switched TOF requires FRAME v1.\n";
      text = text + "    The det switch for FRAME has been changed.";
      AliGlobals::Warning(text);
    }
  }
  if (verTRD > -1) {
    // TRD requires FRAME
    verFRAME = GetDetSwitch("FRAME")->GetSwitchedVersion();
    if (verFRAME < 0) {
      GetDetSwitch("FRAME")->SwitchOnDefault();
      G4String text = "AliDetConstruction::CheckDetDependencies: \n";
      text = text + "    Switched TRD requires FRAME.\n";
      text = text + "    The det switch for FRAME has been changed.";
      AliGlobals::Warning(text);
    }
  }
  if (verZDC > 0) {
    // ZDC requires PIPE, ABSO, DIPO, SHIL
    G4int verPIPE = GetDetSwitch("PIPE")->GetSwitchedVersion();
    G4int verABSO = GetDetSwitch("ABSO")->GetSwitchedVersion();
    G4int verDIPO = GetDetSwitch("DIPO")->GetSwitchedVersion();
    G4int verSHIL = GetDetSwitch("SHIL")->GetSwitchedVersion();
    if ( verPIPE != 1 || verABSO !=0 || verDIPO == -1 || verSHIL == -1) {
      G4String text = "AliDetConstruction::CheckDetDependencies: \n";
      text = text + "    Switched ZDC requires PIPE, ABSO, DIPO and SHIL.\n";
      if (verPIPE == -1) {
        GetDetSwitch("PIPE")->SwitchOnDefault();
        text = text + "    The det switch for PIPE has been changed.\n";
      }
      if (verABSO == -1) {
        GetDetSwitch("ABSO")->SwitchOnDefault();
        text = text + "    The det switch for ABSO has been changed.\n";
      }
      if (verDIPO == -1) {
        GetDetSwitch("DIPO")->SwitchOnDefault();
        text = text + "    The det switch for DIPO has been changed.\n";
      }
      if (verSHIL == -1) {
        GetDetSwitch("SHIL")->SwitchOnDefault();
        text = text + "    The det switch for SHIL has been changed.";
      }
      AliGlobals::Warning(text);
    }
  }
}

// public methods

G4VPhysicalVolume* AliDetConstruction::Construct()
{
// Constructs geometry.
// This method is called by G4RunManager in initialization.
// ---

  if (gAlice->Modules()->GetLast() < 0) {
    // create geometry (including AliModules) according to
    // the fDetSwitchVector
    CheckDetDependencies();
    CreateDetectors();
  }
  else {
    // create geometry for AliModules
    // that have been created and registered by gAlice
    BuildDetectors();
  }
  // construct modules geometry
  ConstructModules();

  return AliSingleModuleConstruction::GetWorld();
}

<|endoftext|>


<commit_before>// Copyright (c) 2015 kamyu. All rights reserved.

#include <iostream>
#include <queue>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>

using std::cout;
using std::endl;
using std::queue;
using std::string;
using std::thread;
using std::mutex;
using std::unique_lock;
using std::lock_guard;
using std::condition_variable;
using std::chrono::milliseconds;
using std::this_thread::sleep_for;

template<typename T>
class SyncQueue {
 public:
    void put(const T& val) {
        unique_lock<mutex> lock{mtx};
        // If the condition is not met,
        // wait until the thread is notified,
        // the mutex is acquirable, and the condition is met.
        cond.wait(lock, [this]() { return q.size() != q_size; });
        q.emplace(val);
        cond.notify_one();  // Notify one of the waiting thread.
    }  // Unlock the mutex.

    void get(T *val) {
        unique_lock<mutex> lock{mtx};
        // If the condition is not met,
        // wait until the thread is notified,
        // the mutex is acquirable, and the condition is met.
        cond.wait(lock, [this]() { return !q.empty(); });
        *val = q.front();
        q.pop();
        cond.notify_one();  // Notify one of the waiting thread.
    }  // Unlock the mutex.

 private:
    mutex mtx;
    condition_variable cond;
    queue<T> q;
    const unsigned int q_size = 5;
};

class Printer {
 public:
    static void print(const string& s, const int& i) {
        static mutex mtx;
        unique_lock<mutex> lock(mtx);
        cout << s << i <<endl;
    }
};

class Producer {
 public:
    explicit Producer(SyncQueue<int> *q) : q_(*q) {}

    void run() {
        for (int i = 0; i < 100; ++i) {
            const int num = i;
            q_.put(num);
            Printer::print("Produced: ", num);
            sleep_for(milliseconds(50));
        }
    }

 private:
    SyncQueue<int>& q_;
};

class Consumer {
 public:
    explicit Consumer(SyncQueue<int> *q) : q_(*q) {}

    void run() {
        for (int i = 0; i < 100; ++i) {
            int num;
            q_.get(&num);
            Printer::print("Consumed: ", num);
            sleep_for(milliseconds(500));
        }
    }

 private:
    SyncQueue<int>& q_;
};

int main() {
    SyncQueue<int> q;
    Producer p{&q};
    Consumer c{&q};

    thread producer_thread{&Producer::run, &p};
    thread consumer_thread{&Consumer::run, &c};

    producer_thread.join();
    consumer_thread.join();

    return 0;
}
<commit_msg>Update producer-consumer.cpp<commit_after>// Copyright (c) 2015 kamyu. All rights reserved.

#include <iostream>
#include <queue>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>

using std::cout;
using std::endl;
using std::queue;
using std::string;
using std::thread;
using std::mutex;
using std::unique_lock;
using std::lock_guard;
using std::condition_variable;
using std::chrono::milliseconds;
using std::this_thread::sleep_for;

template<typename T>
class SyncQueue {
 public:
    void put(const T& val) {
        unique_lock<mutex> lock{mtx};
        // If the condition is not met,
        // wait until the thread is notified,
        // the mutex is acquirable, and the condition is met.
        cond.wait(lock, [this]() { return q.size() != q_size; });
        q.emplace(val);
        cond.notify_one();  // Notify one of the waiting thread.
    }  // Unlock the mutex.

    void get(T *val) {
        unique_lock<mutex> lock{mtx};
        // If the condition is not met,
        // wait until the thread is notified,
        // the mutex is acquirable, and the condition is met.
        cond.wait(lock, [this]() { return !q.empty(); });
        *val = q.front();
        q.pop();
        cond.notify_one();  // Notify one of the waiting thread.
    }  // Unlock the mutex.

 private:
    mutex mtx;
    condition_variable cond;
    queue<T> q;
    const unsigned int q_size = 5;
};

class Printer {
 public:
    static void print(const string& s, const int& i) {
        static mutex mtx;
        unique_lock<mutex> lock(mtx);
        cout << s << i << endl;
    }
};

class Producer {
 public:
    explicit Producer(SyncQueue<int> *q) : q_(*q) {}

    void run() {
        for (int i = 0; i < 100; ++i) {
            const int num = i;
            q_.put(num);
            Printer::print("Produced: ", num);
            sleep_for(milliseconds(50));
        }
    }

 private:
    SyncQueue<int>& q_;
};

class Consumer {
 public:
    explicit Consumer(SyncQueue<int> *q) : q_(*q) {}

    void run() {
        for (int i = 0; i < 100; ++i) {
            int num;
            q_.get(&num);
            Printer::print("Consumed: ", num);
            sleep_for(milliseconds(500));
        }
    }

 private:
    SyncQueue<int>& q_;
};

int main() {
    SyncQueue<int> q;
    Producer p{&q};
    Consumer c{&q};

    thread producer_thread{&Producer::run, &p};
    thread consumer_thread{&Consumer::run, &c};

    producer_thread.join();
    consumer_thread.join();

    return 0;
}
<|endoftext|>