text:
//===--- FunctionSignatureOpts.cpp - Optimizes function signatures --------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
///
/// \file
///
/// This pass defines function signature related optimizations.
/// When a function signature optimization is performed, changes are made to
/// the original function and after all function signature optimizations are
/// finished, a new function is created and the old function is turned into
/// a thunk.
///
/// Another possibility is to implement these optimizations as separate passes,
/// but then we would send slightly different functions to the pass pipeline
/// multiple times through notifyPassManagerOfFunction.
///
/// TODO: Optimize function with generic parameters.
///
/// TODO: Improve epilogue release matcher, i.e. do a data flow instead of
/// only finding releases in the return block.
///
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "sil-function-signature-opt"
#include "swift/SILOptimizer/Analysis/ARCAnalysis.h"
#include "swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h"
#include "swift/SILOptimizer/Analysis/CallerAnalysis.h"
#include "swift/SILOptimizer/Analysis/EpilogueARCAnalysis.h"
#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h"
#include "swift/SILOptimizer/PassManager/Passes.h"
#include "swift/SILOptimizer/PassManager/Transforms.h"
#include "swift/SILOptimizer/Utils/FunctionSignatureOptUtils.h"
#include "swift/SILOptimizer/Utils/Local.h"
#include "swift/SILOptimizer/Utils/SILInliner.h"
#include "swift/SILOptimizer/Utils/SpecializationMangler.h"
#include "swift/SIL/DebugUtils.h"
#include "swift/SIL/Mangle.h"
#include "swift/SIL/SILFunction.h"
#include "swift/SIL/SILCloner.h"
#include "swift/SIL/SILValue.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Debug.h"

using namespace swift;

STATISTIC(NumFunctionSignaturesOptimized, "Total func sig optimized");
STATISTIC(NumDeadArgsEliminated, "Total dead args eliminated");
STATISTIC(NumOwnedConvertedToGuaranteed, "Total owned args -> guaranteed args");
STATISTIC(NumOwnedConvertedToNotOwnedResult, "Total owned result -> not owned result");
STATISTIC(NumSROAArguments, "Total SROA arguments optimized");

using SILParameterInfoList = llvm::SmallVector<SILParameterInfo, 8>;
using ArgumentIndexMap = llvm::SmallDenseMap<int, int>;

//===----------------------------------------------------------------------===//
//                           Utilities
//===----------------------------------------------------------------------===//

/// Return the single return value of the function.
static SILValue findReturnValue(SILFunction *F) {
  auto RBB = F->findReturnBB();
  if (RBB == F->end())
    return SILValue();
  auto Term = dyn_cast<ReturnInst>(RBB->getTerminator());
  return Term->getOperand();
}

/// Return the single apply found in this function.
static SILInstruction *findOnlyApply(SILFunction *F) {
  SILInstruction *OnlyApply = nullptr;
  for (auto &B : *F) {
    for (auto &X : B) {
      if (!isa<ApplyInst>(X) && !isa<TryApplyInst>(X))
        continue;
      assert(!OnlyApply && "There are more than 1 function calls");
      OnlyApply = &X;
    }
  }
  assert(OnlyApply && "There is no function calls");
  return OnlyApply;
}

/// Return a unique name in the current module. We should not be blocked
/// from being able to FSO a function just because we have a name conflict.
///
/// TODO: we should teach the demangler to understand this suffix.
static std::string getUniqueName(std::string Name, SILModule &M) {
  if (!M.lookUpFunction(Name))
    return Name;
  return getUniqueName(Name + "_unique_suffix", M);
}

//===----------------------------------------------------------------------===//
//                     Function Signature Transformation
//===----------------------------------------------------------------------===//
class FunctionSignatureTransform {
  /// The actual function to analyze and transform.
  SILFunction *F;

  /// The newly created function.
  SILFunction *NewF;

  /// The RC identity analysis we are using.
  RCIdentityAnalysis *RCIA;

  /// Post order analysis we are using.
  EpilogueARCAnalysis *EA;

  // The function signature mangler we are using.
  FunctionSignatureSpecializationMangler &OldFM;
  NewMangling::FunctionSignatureSpecializationMangler &NewFM;

  // Keep tracks to argument mapping.
  ArgumentIndexMap &AIM;

  // Self argument is modified.
  bool shouldModifySelfArgument;

  /// Keep a "view" of precompiled information on arguments that we use
  /// during our optimization.
  llvm::SmallVector<ArgumentDescriptor, 4> &ArgumentDescList;

  /// Keep a "view" of precompiled information on the direct results that we
  /// will use during our optimization.
  llvm::SmallVector<ResultDescriptor, 4> &ResultDescList;

  /// Return a function name based on ArgumentDescList and ResultDescList.
  std::string createOptimizedSILFunctionName();

  /// Return a function type based on ArgumentDescList and ResultDescList.
  CanSILFunctionType createOptimizedSILFunctionType();

private:
  /// ----------------------------------------------------------///
  /// Dead argument transformation.                             ///
  /// ----------------------------------------------------------///
  /// Find any dead argument opportunities.
  bool DeadArgumentAnalyzeParameters();
  /// Modify the current function so that later function signature analysis
  /// are more effective.
  void DeadArgumentTransformFunction();
  /// Remove the dead argument once the new function is created.
  void DeadArgumentFinalizeOptimizedFunction();

  /// ----------------------------------------------------------///
  /// Owned to guaranteed transformation.                       ///
  /// ----------------------------------------------------------///
  bool OwnedToGuaranteedAnalyzeResults();
  bool OwnedToGuaranteedAnalyzeParameters();

  /// Modify the current function so that later function signature analysis
  /// are more effective.
  void OwnedToGuaranteedTransformFunctionResults();
  void OwnedToGuaranteedTransformFunctionParameters();

  /// Find any owned to guaranteed opportunities.
  bool OwnedToGuaranteedAnalyze() {
    bool Result = OwnedToGuaranteedAnalyzeResults();
    bool Params = OwnedToGuaranteedAnalyzeParameters();
    return Params || Result;
  }

  /// Do the actual owned to guaranteed transformations.
  void OwnedToGuaranteedTransform() {
    OwnedToGuaranteedTransformFunctionResults();
    OwnedToGuaranteedTransformFunctionParameters();
  }

  /// Set up epilogue work for the thunk result based in the given argument.
  void OwnedToGuaranteedAddResultRelease(ResultDescriptor &RD,
                                         SILBuilder &Builder,
                                         SILFunction *F);

  /// Set up epilogue work for the thunk argument based in the given argument.
  void OwnedToGuaranteedAddArgumentRelease(ArgumentDescriptor &AD,
                                           SILBuilder &Builder,
                                           SILFunction *F);

  /// Add the release for converted arguments and result.
  void OwnedToGuaranteedFinalizeThunkFunction(SILBuilder &B, SILFunction *F);

  /// ----------------------------------------------------------///
  /// Argument explosion transformation.                        ///
  /// ----------------------------------------------------------///
  /// Find any argument explosion opportunities.
  bool ArgumentExplosionAnalyzeParameters();
  /// Explode the argument in the optimized function and replace the uses of
  /// the original argument.
  void ArgumentExplosionFinalizeOptimizedFunction();

  /// Setup the thunk arguments based on the given argument descriptor info.
  /// Every transformation must defines this interface. Default implementation
  /// simply passes it through.
  void addThunkArgument(ArgumentDescriptor &AD, SILBuilder &Builder,
                        SILBasicBlock *BB,
                        llvm::SmallVectorImpl<SILValue> &NewArgs) {
    // Dead argument.
    if (AD.IsEntirelyDead) {
      return;
    }

    // Explode the argument.
    if (AD.Explode) {
      llvm::SmallVector<SILValue, 4> LeafValues;
      AD.ProjTree.createTreeFromValue(Builder, BB->getParent()->getLocation(),
                                      BB->getArgument(AD.Index), LeafValues);
      NewArgs.append(LeafValues.begin(), LeafValues.end());
      return;
    }

    // All other arguments get pushed as what they are.
    NewArgs.push_back(BB->getArgument(AD.Index));
  }

  /// Take ArgumentDescList and ResultDescList and create an optimized function
  /// based on the current function we are analyzing. This also has the side effect
  /// of turning the current function into a thunk.
  void createFunctionSignatureOptimizedFunction();

  /// Compute the optimized function type based on the given argument descriptor.
  void computeOptimizedArgInterface(ArgumentDescriptor &A, SILParameterInfoList &O);

public:
  /// Constructor.
  FunctionSignatureTransform(SILFunction *F,
                             RCIdentityAnalysis *RCIA, EpilogueARCAnalysis *EA,
                             FunctionSignatureSpecializationMangler &OldFM,
                    NewMangling::FunctionSignatureSpecializationMangler &NewFM,
                             ArgumentIndexMap &AIM,
                             llvm::SmallVector<ArgumentDescriptor, 4> &ADL,
                             llvm::SmallVector<ResultDescriptor, 4> &RDL)
    : F(F), NewF(nullptr), RCIA(RCIA), EA(EA), OldFM(OldFM), NewFM(NewFM),
      AIM(AIM), shouldModifySelfArgument(false), ArgumentDescList(ADL),
      ResultDescList(RDL) {}

  /// Return the optimized function.
  SILFunction *getOptimizedFunction() { return NewF; }

  /// Run the optimization.
  bool run(bool hasCaller) {
    bool Changed = false;

    if (!hasCaller && canBeCalledIndirectly(F->getRepresentation())) {
      DEBUG(llvm::dbgs() << "  function has no caller -> abort\n");
      return false;
    }

    // Run OwnedToGuaranteed optimization.
    if (OwnedToGuaranteedAnalyze()) {
      Changed = true;
      DEBUG(llvm::dbgs() << "  transform owned-to-guaranteed\n");
      OwnedToGuaranteedTransform();
    }

    // Run DeadArgument elimination transformation. We only specialize
    // if this function has a caller inside the current module or we have
    // already created a thunk.
    if ((hasCaller || Changed) && DeadArgumentAnalyzeParameters()) {
      Changed = true;
      DEBUG(llvm::dbgs() << "  remove dead arguments\n");
      DeadArgumentTransformFunction();
    }

    // Run ArgumentExplosion transformation. We only specialize
    // if this function has a caller inside the current module or we have
    // already created a thunk.
    //
    // NOTE: we run argument explosion last because we've already initialized
    // the ArgumentDescList to have unexploded number of arguments. Exploding
    // it without changing the argument count is not going to help with
    // owned-to-guaranteed transformation.
    //
    // In order to not miss any opportunity, we send the optimized function
    // to the passmanager to optimize any opportunities exposed by argument
    // explosion.
    if ((hasCaller || Changed) && ArgumentExplosionAnalyzeParameters()) {
      Changed = true;
    }

    // Create the specialized function and invalidate the old function.
    if (Changed) {
      createFunctionSignatureOptimizedFunction();
    }
    return Changed;
  }

  /// Run dead argument elimination of partially applied functions.
  /// After this optimization CapturePropagation can replace the partial_apply
  /// by a direct reference to the specialized function.
  bool removeDeadArgs(int minPartialAppliedArgs) {
    if (minPartialAppliedArgs < 1)
      return false;

    if (!DeadArgumentAnalyzeParameters())
      return false;

    // Check if at least the minimum number of partially applied arguments
    // are dead. Otherwise no partial_apply can be removed anyway.
    for (unsigned Idx = 0, Num = ArgumentDescList.size(); Idx < Num; ++Idx) {
      if (Idx < Num - minPartialAppliedArgs) {
        // Don't remove arguments other than the partial applied ones, even if
        // they are dead.
        ArgumentDescList[Idx].IsEntirelyDead = false;
      } else {
        // Is the partially applied argument dead?
        if (!ArgumentDescList[Idx].IsEntirelyDead)
          return false;

        // Currently we require that all dead parameters have trivial types.
        // The reason is that it's very hard to find places where we can release
        // those parameters (as a replacement for the removed partial_apply).
        // TODO: maybe we can skip this restriction when we have semantic ARC.
        if (!ArgumentDescList[Idx].Arg->getType().isTrivial(F->getModule()))
          return false;
      }
    }

    DEBUG(llvm::dbgs() << "  remove dead arguments for partial_apply\n");
    DeadArgumentTransformFunction();
    createFunctionSignatureOptimizedFunction();
    return true;
  }
};

std::string FunctionSignatureTransform::createOptimizedSILFunctionName() {
  // Handle arguments' changes.
  for (unsigned i : indices(ArgumentDescList)) {
    const ArgumentDescriptor &Arg = ArgumentDescList[i];
    if (Arg.IsEntirelyDead) {
      OldFM.setArgumentDead(i);
      NewFM.setArgumentDead(i);
      // No point setting other attribute if argument is dead.
      continue;
    }

    // If we have an @owned argument and found a callee release for it,
    // convert the argument to guaranteed.
    if (Arg.OwnedToGuaranteed) {
      OldFM.setArgumentOwnedToGuaranteed(i);
      NewFM.setArgumentOwnedToGuaranteed(i);
    }

    // If this argument is not dead and we can explode it, add 's' to the
    // mangling.
    if (Arg.Explode) {
      OldFM.setArgumentSROA(i);
      NewFM.setArgumentSROA(i);
    }
  }

  // Handle return value's change.
  // FIXME: handle multiple direct results here
  if (ResultDescList.size() == 1 && !ResultDescList[0].CalleeRetain.empty()) {
    OldFM.setReturnValueOwnedToUnowned();
    NewFM.setReturnValueOwnedToUnowned();
  }

  OldFM.mangle();
  SILModule &M = F->getModule();
  std::string Old = getUniqueName(OldFM.getMangler().finalize(), M);

  int UniqueID = 0;
  std::string New;
  do {
    New = NewFM.mangle(UniqueID);
    ++UniqueID;
  } while (M.lookUpFunction(New));

  return NewMangling::selectMangling(Old, New);
}

/// Compute what the function interface will look like based on the
/// optimization we are doing on the given argument descriptor. Default
/// implementation simply passes it through.
void
FunctionSignatureTransform::
computeOptimizedArgInterface(ArgumentDescriptor &AD, SILParameterInfoList &Out) {
  // If this argument is live, but we cannot optimize it.
  if (!AD.canOptimizeLiveArg()) {
    Out.push_back(AD.PInfo);
    return;
  }

  // If we have a dead argument, bail.
  if (AD.IsEntirelyDead) {
    ++NumDeadArgsEliminated;
    return;
  }

  // Explode the argument or not ?
  if (AD.Explode) {
    ++NumSROAArguments;
    llvm::SmallVector<const ProjectionTreeNode*, 8> LeafNodes;
    AD.ProjTree.getLeafNodes(LeafNodes);
    for (auto Node : LeafNodes) {
      SILType Ty = Node->getType();
      DEBUG(llvm::dbgs() << "                " << Ty << "\n");
      // If Ty is trivial, just pass it directly.
      if (Ty.isTrivial(AD.Arg->getModule())) {
        SILParameterInfo NewInfo(Ty.getSwiftRValueType(),
                                 ParameterConvention::Direct_Unowned);
        Out.push_back(NewInfo);
        continue;
      }

      // Ty is not trivial, pass it through as the original calling convention.
      SILParameterInfo NewInfo(Ty.getSwiftRValueType(), AD.OwnedToGuaranteed ?
                               ParameterConvention::Direct_Guaranteed :
                               AD.PInfo.getConvention());
      Out.push_back(NewInfo);
    }
    return;
  }

  // If we cannot explode this value, handle callee release and return.
  // If we found releases in the callee in the last BB on an @owned
  // parameter, change the parameter to @guaranteed and continue...
  if (AD.OwnedToGuaranteed) {
    ++NumOwnedConvertedToGuaranteed;
    SILParameterInfo NewInfo(AD.PInfo.getType(),
                             ParameterConvention::Direct_Guaranteed);
    Out.push_back(NewInfo);
    return;
  }

  // Otherwise just propagate through the parameter info.
  Out.push_back(AD.PInfo);
}

CanSILFunctionType FunctionSignatureTransform::createOptimizedSILFunctionType() {
  CanSILFunctionType FTy = F->getLoweredFunctionType();
  // The only way that we modify the arity of function parameters is here for
  // dead arguments. Doing anything else is unsafe since by definition non-dead
  // arguments will have SSA uses in the function. We would need to be smarter
  // in our moving to handle such cases.
  llvm::SmallVector<SILParameterInfo, 8> InterfaceParams;
  for (auto &ArgDesc : ArgumentDescList) {
    computeOptimizedArgInterface(ArgDesc, InterfaceParams);
  }

  // ResultDescs only covers the direct results; we currently can't ever
  // change an indirect result.  Piece the modified direct result information
  // back into the all-results list.
  llvm::SmallVector<SILResultInfo, 8> InterfaceResults;
  auto &ResultDescs = ResultDescList;
  for (SILResultInfo InterfaceResult : FTy->getResults()) {
    if (InterfaceResult.isFormalDirect()) {
      auto &RV = ResultDescs[0];
      if (!RV.CalleeRetain.empty()) {
        ++NumOwnedConvertedToNotOwnedResult;
        InterfaceResults.push_back(SILResultInfo(InterfaceResult.getType(),
                                                 ResultConvention::Unowned));
        continue;
      }
    }

    InterfaceResults.push_back(InterfaceResult);
  }

  // Don't use a method representation if we modified self.
  auto ExtInfo = FTy->getExtInfo();
  if (shouldModifySelfArgument) {
    ExtInfo = ExtInfo.withRepresentation(SILFunctionTypeRepresentation::Thin);
  }

  return SILFunctionType::get(FTy->getGenericSignature(), ExtInfo,
                              FTy->getCalleeConvention(), InterfaceParams,
                              InterfaceResults, FTy->getOptionalErrorResult(),
                              F->getModule().getASTContext());
}

void FunctionSignatureTransform::createFunctionSignatureOptimizedFunction() {
  // Create the optimized function !
  SILModule &M = F->getModule();
  std::string Name = createOptimizedSILFunctionName();
  SILLinkage linkage = F->getLinkage();
  if (isAvailableExternally(linkage))
    linkage = SILLinkage::Shared;

  DEBUG(llvm::dbgs() << "  -> create specialized function " << Name << "\n");

  NewF = M.createFunction(
      linkage, Name, createOptimizedSILFunctionType(), nullptr,
      F->getLocation(), F->isBare(), F->isTransparent(), F->isFragile(),
      F->isThunk(), F->getClassVisibility(), F->getInlineStrategy(),
      F->getEffectsKind(), nullptr, F->getDebugScope(), F->getDeclContext());
  if (F->hasUnqualifiedOwnership()) {
    NewF->setUnqualifiedOwnership();
  }

  // Then we transfer the body of F to NewF.
  NewF->spliceBody(F);
  NewF->setDeclCtx(F->getDeclContext());

  // Array semantic clients rely on the signature being as in the original
  // version.
  for (auto &Attr : F->getSemanticsAttrs()) {
    if (!StringRef(Attr).startswith("array."))
      NewF->addSemanticsAttr(Attr);
  }

  // Do the last bit of work to the newly created optimized function.
  ArgumentExplosionFinalizeOptimizedFunction();
  DeadArgumentFinalizeOptimizedFunction();

  // Create the thunk body !
  F->setThunk(IsThunk);
  // The thunk now carries the information on how the signature is
  // optimized. If we inline the thunk, we will get the benefit of calling
  // the signature optimized function without additional setup on the
  // caller side.
  F->setInlineStrategy(AlwaysInline);
  SILBasicBlock *ThunkBody = F->createBasicBlock();
  for (auto &ArgDesc : ArgumentDescList) {
    ThunkBody->createFunctionArgument(ArgDesc.Arg->getType(), ArgDesc.Decl);
  }

  SILLocation Loc = ThunkBody->getParent()->getLocation();
  SILBuilder Builder(ThunkBody);
  Builder.setCurrentDebugScope(ThunkBody->getParent()->getDebugScope());

  FunctionRefInst *FRI = Builder.createFunctionRef(Loc, NewF);

  // Create the args for the thunk's apply, ignoring any dead arguments.
  llvm::SmallVector<SILValue, 8> ThunkArgs;
  for (auto &ArgDesc : ArgumentDescList) {
    addThunkArgument(ArgDesc, Builder, ThunkBody, ThunkArgs);
  }

  // We are ignoring generic functions and functions with out parameters for
  // now.
  SILValue ReturnValue;
  SILType LoweredType = NewF->getLoweredType();
  SILType ResultType = NewF->getConventions().getSILResultType();
  auto FunctionTy = LoweredType.castTo<SILFunctionType>();
  if (FunctionTy->hasErrorResult()) {
    // We need a try_apply to call a function with an error result.
    SILFunction *Thunk = ThunkBody->getParent();
    SILBasicBlock *NormalBlock = Thunk->createBasicBlock();
    ReturnValue =
        NormalBlock->createPHIArgument(ResultType, ValueOwnershipKind::Owned);
    SILBasicBlock *ErrorBlock = Thunk->createBasicBlock();
    SILType Error =
        SILType::getPrimitiveObjectType(FunctionTy->getErrorResult().getType());
    auto *ErrorArg =
        ErrorBlock->createPHIArgument(Error, ValueOwnershipKind::Owned);
    Builder.createTryApply(Loc, FRI, LoweredType, ArrayRef<Substitution>(),
                           ThunkArgs, NormalBlock, ErrorBlock);

    Builder.setInsertionPoint(ErrorBlock);
    Builder.createThrow(Loc, ErrorArg);
    Builder.setInsertionPoint(NormalBlock);
  } else {
    ReturnValue = Builder.createApply(Loc, FRI, LoweredType, ResultType,
                                      ArrayRef<Substitution>(), ThunkArgs,
                                      false);
  }

  // Set up the return results.
  if (NewF->isNoReturnFunction()) {
    Builder.createUnreachable(Loc);
  } else {
    Builder.createReturn(Loc, ReturnValue);
  }

  // Do the last bit work to finalize the thunk.
  OwnedToGuaranteedFinalizeThunkFunction(Builder, F);
  assert(F->getDebugScope()->Parent != NewF->getDebugScope()->Parent);
}

/// ----------------------------------------------------------///
/// Dead argument transformation.                             ///
/// ----------------------------------------------------------///
bool FunctionSignatureTransform::DeadArgumentAnalyzeParameters() {
  // Did we decide we should optimize any parameter?
  bool SignatureOptimize = false;
  auto Args = F->begin()->getFunctionArguments();

  // Analyze the argument information.
  for (unsigned i = 0, e = Args.size(); i != e; ++i) {
    ArgumentDescriptor &A = ArgumentDescList[i];
    if (!A.canOptimizeLiveArg()) {
      continue;
    }

    // Check whether argument is dead.
    if (!hasNonTrivialNonDebugUse(Args[i])) {
      A.IsEntirelyDead = true;
      SignatureOptimize = true;
      if (Args[i]->isSelf())
        shouldModifySelfArgument = true;
    }
  }
  return SignatureOptimize;
}

void FunctionSignatureTransform::DeadArgumentTransformFunction() {
  SILBasicBlock *BB = &*F->begin();
  for (const ArgumentDescriptor &AD : ArgumentDescList) {
    if (!AD.IsEntirelyDead)
      continue;
    eraseUsesOfValue(BB->getArgument(AD.Index));
  }
}

void FunctionSignatureTransform::DeadArgumentFinalizeOptimizedFunction() {
  auto *BB = &*NewF->begin();
  // Remove any dead argument starting from the last argument to the first.
  for (const ArgumentDescriptor &AD : reverse(ArgumentDescList)) {
    if (!AD.IsEntirelyDead)
      continue;
    BB->eraseArgument(AD.Arg->getIndex());
  }
}

/// ----------------------------------------------------------///
/// Owned to Guaranteed transformation.                       ///
/// ----------------------------------------------------------///
bool FunctionSignatureTransform::OwnedToGuaranteedAnalyzeParameters() {
  auto Args = F->begin()->getFunctionArguments();
  // A map from consumed SILArguments to the release associated with an
  // argument.
  //
  // TODO: The return block and throw block should really be abstracted away.
  ConsumedArgToEpilogueReleaseMatcher ArgToReturnReleaseMap(RCIA->get(F), F);
  ConsumedArgToEpilogueReleaseMatcher ArgToThrowReleaseMap(
      RCIA->get(F), F, ConsumedArgToEpilogueReleaseMatcher::ExitKind::Throw);

  // Did we decide we should optimize any parameter?
  bool SignatureOptimize = false;

  // Analyze the argument information.
  for (unsigned i = 0, e = Args.size(); i != e; ++i) {
    ArgumentDescriptor &A = ArgumentDescList[i];
    if (!A.canOptimizeLiveArg()) {
      continue;
    }

    // See if we can find a ref count equivalent strong_release or release_value
    // at the end of this function if our argument is an @owned parameter.
    if (A.hasConvention(SILArgumentConvention::Direct_Owned)) {
      auto Releases = ArgToReturnReleaseMap.getReleasesForArgument(A.Arg);
      if (!Releases.empty()) {
        // If the function has a throw block we must also find a matching
        // release in the throw block.
        auto ReleasesInThrow = ArgToThrowReleaseMap.getReleasesForArgument(A.Arg);
        if (!ArgToThrowReleaseMap.hasBlock() || !ReleasesInThrow.empty()) {
          A.CalleeRelease = Releases;
          A.CalleeReleaseInThrowBlock = ReleasesInThrow;
          // We can convert this parameter to a @guaranteed.
          A.OwnedToGuaranteed = true;
          SignatureOptimize = true;
        }
      }
    }

    // Modified self argument.
    if (A.OwnedToGuaranteed && Args[i]->isSelf()) {
      shouldModifySelfArgument = true;
    }
  }
  return SignatureOptimize;
}

bool FunctionSignatureTransform::OwnedToGuaranteedAnalyzeResults() {
  auto fnConv = F->getConventions();
  // For now, only do anything if there's a single direct result.
  if (fnConv.getNumDirectSILResults() != 1)
    return false;

  bool SignatureOptimize = false;
  if (ResultDescList[0].hasConvention(ResultConvention::Owned)) {
    auto RV = findReturnValue(F);
    if (!RV)
      return false;
    auto &RI = ResultDescList[0];
    // We have an @owned return value, find the epilogue retains now.
    auto Retains = EA->get(F)->computeEpilogueARCInstructions(EpilogueARCContext::EpilogueARCKind::Retain, RV);
    // We do not need to worry about the throw block, as the return value is only
    // going to be used in the return block/normal block of the try_apply
    // instruction.
    if (!Retains.empty()) {
      RI.CalleeRetain = Retains;
      SignatureOptimize = true;
      RI.OwnedToGuaranteed = true;
    }
  }
  return SignatureOptimize;
}

void FunctionSignatureTransform::OwnedToGuaranteedTransformFunctionParameters() {
  // And remove all Callee releases that we found and made redundant via owned
  // to guaranteed conversion.
  for (const ArgumentDescriptor &AD : ArgumentDescList) {
    if (!AD.OwnedToGuaranteed)
      continue;
    for (auto &X : AD.CalleeRelease) {
      X->eraseFromParent();
    }
    for (auto &X : AD.CalleeReleaseInThrowBlock) {
      X->eraseFromParent();
    }

    // Now we need to replace the FunctionArgument so that we have the correct
    // ValueOwnershipKind.
    AD.Arg->setOwnershipKind(ValueOwnershipKind::Guaranteed);
  }
}

void FunctionSignatureTransform::OwnedToGuaranteedTransformFunctionResults() {
  // And remove all callee retains that we found and made redundant via owned
  // to unowned conversion.
  for (const ResultDescriptor &RD : ResultDescList) {
    if (!RD.OwnedToGuaranteed)
      continue;
    for (auto &X : RD.CalleeRetain) {
      if (isa<StrongRetainInst>(X) || isa<RetainValueInst>(X)) {
        X->eraseFromParent();
        continue;
      }
      // Create a release to balance it out.
      assert(isa<ApplyInst>(X) && "Unknown epilogue retain");
      createDecrementBefore(X, dyn_cast<ApplyInst>(X)->getParent()->getTerminator());
    }
  }
}

void FunctionSignatureTransform::
OwnedToGuaranteedFinalizeThunkFunction(SILBuilder &Builder, SILFunction *F) {
  // Finish the epilogue work for the argument as well as result.
  for (auto &ArgDesc : ArgumentDescList) {
    OwnedToGuaranteedAddArgumentRelease(ArgDesc, Builder, F);
  }
  for (auto &ResDesc : ResultDescList) {
    OwnedToGuaranteedAddResultRelease(ResDesc, Builder, F);
  }
}

/// Set up epilogue work for the thunk arguments based in the given argument.
/// Default implementation simply passes it through.
void
FunctionSignatureTransform::
OwnedToGuaranteedAddArgumentRelease(ArgumentDescriptor &AD, SILBuilder &Builder,
                                    SILFunction *F) {
  // If we have any arguments that were consumed but are now guaranteed,
  // insert a release_value.
  if (!AD.OwnedToGuaranteed) {
    return;
  }

  SILInstruction *Call = findOnlyApply(F);
  if (isa<ApplyInst>(Call)) {
    Builder.setInsertionPoint(&*std::next(SILBasicBlock::iterator(Call)));
    Builder.createReleaseValue(RegularLocation(SourceLoc()),
                               F->getArguments()[AD.Index],
                               Atomicity::Atomic);
  } else {
    SILBasicBlock *NormalBB = dyn_cast<TryApplyInst>(Call)->getNormalBB();
    Builder.setInsertionPoint(&*NormalBB->begin());
    Builder.createReleaseValue(RegularLocation(SourceLoc()),
                               F->getArguments()[AD.Index],
                               Atomicity::Atomic);

    SILBasicBlock *ErrorBB = dyn_cast<TryApplyInst>(Call)->getErrorBB();
    Builder.setInsertionPoint(&*ErrorBB->begin());
    Builder.createReleaseValue(RegularLocation(SourceLoc()),
                               F->getArguments()[AD.Index],
                               Atomicity::Atomic);
  }
}

void
FunctionSignatureTransform::
OwnedToGuaranteedAddResultRelease(ResultDescriptor &RD, SILBuilder &Builder,
                                  SILFunction *F) {
 // If we have any result that were consumed but are now guaranteed,
  // insert a release_value.
  if (!RD.OwnedToGuaranteed) {
    return;
  }

  SILInstruction *Call = findOnlyApply(F);
  if (isa<ApplyInst>(Call)) {
    Builder.setInsertionPoint(&*std::next(SILBasicBlock::iterator(Call)));
    Builder.createRetainValue(RegularLocation(SourceLoc()), Call,
                              Atomicity::Atomic);
  } else {
    SILBasicBlock *NormalBB = dyn_cast<TryApplyInst>(Call)->getNormalBB();
    Builder.setInsertionPoint(&*NormalBB->begin());
    Builder.createRetainValue(RegularLocation(SourceLoc()),
                              NormalBB->getArgument(0), Atomicity::Atomic);
  }
}

/// ----------------------------------------------------------///
/// Argument Explosion transformation.                        ///
/// ----------------------------------------------------------///
bool FunctionSignatureTransform::ArgumentExplosionAnalyzeParameters() {
  // Did we decide we should optimize any parameter?
  bool SignatureOptimize = false;
  auto Args = F->begin()->getFunctionArguments();
  ConsumedArgToEpilogueReleaseMatcher ArgToReturnReleaseMap(RCIA->get(F), F);

  // Analyze the argument information.
  for (unsigned i = 0, e = Args.size(); i != e; ++i) {
    ArgumentDescriptor &A = ArgumentDescList[i];
    // Do not optimize argument.
    if (!A.canOptimizeLiveArg()) {
      continue;
    }

    A.ProjTree.computeUsesAndLiveness(A.Arg);
    A.Explode = A.shouldExplode(ArgToReturnReleaseMap);

    // Modified self argument.
    if (A.Explode && Args[i]->isSelf()) {
      shouldModifySelfArgument = true;
    }

    SignatureOptimize |= A.Explode;
  }
  return SignatureOptimize;
}

void FunctionSignatureTransform::ArgumentExplosionFinalizeOptimizedFunction() {
  SILBasicBlock *BB = &*NewF->begin();
  SILBuilder Builder(BB->begin());
  Builder.setCurrentDebugScope(BB->getParent()->getDebugScope());
  unsigned TotalArgIndex = 0;
  for (ArgumentDescriptor &AD : ArgumentDescList) {
    // Simply continue if do not explode.
    if (!AD.Explode) {
      AIM[TotalArgIndex] = AD.Index;
      TotalArgIndex ++;
      continue;
    }

    // OK, we need to explode this argument.
    unsigned ArgOffset = ++TotalArgIndex;
    unsigned OldArgIndex = ArgOffset - 1;
    llvm::SmallVector<SILValue, 8> LeafValues;

    // We do this in the same order as leaf types since ProjTree expects that the
    // order of leaf values matches the order of leaf types.
    llvm::SmallVector<const ProjectionTreeNode*, 8> LeafNodes;
    AD.ProjTree.getLeafNodes(LeafNodes);

    for (auto *Node : LeafNodes) {
      auto OwnershipKind = *AD.getTransformedOwnershipKind(Node->getType());
      LeafValues.push_back(BB->insertFunctionArgument(
          ArgOffset++, Node->getType(), OwnershipKind,
          BB->getArgument(OldArgIndex)->getDecl()));
      AIM[TotalArgIndex - 1] = AD.Index;
      TotalArgIndex ++;
    }

    // Then go through the projection tree constructing aggregates and replacing
    // uses.
    AD.ProjTree.replaceValueUsesWithLeafUses(Builder, BB->getParent()->getLocation(),
                                             LeafValues);

    // We ignored debugvalue uses when we constructed the new arguments, in order
    // to preserve as much information as possible, we construct a new value for
    // OrigArg from the leaf values and use that in place of the OrigArg.
    SILValue NewOrigArgValue = AD.ProjTree.computeExplodedArgumentValue(Builder,
                                             BB->getParent()->getLocation(),
                                             LeafValues);

    // Replace all uses of the original arg with the new value.
    SILArgument *OrigArg = BB->getArgument(OldArgIndex);
    OrigArg->replaceAllUsesWith(NewOrigArgValue);

    // Now erase the old argument since it does not have any uses. We also
    // decrement ArgOffset since we have one less argument now.
    BB->eraseArgument(OldArgIndex);
    TotalArgIndex --;
  }
}

//===----------------------------------------------------------------------===//
//                           Top Level Entry Point
//===----------------------------------------------------------------------===//
namespace {
class FunctionSignatureOpts : public SILFunctionTransform {

  /// If true, perform a special kind of dead argument elimination to enable
  /// removal of partial_apply instructions where all partially applied
  /// arguments are dead.
  bool OptForPartialApply;

public:

  FunctionSignatureOpts(bool OptForPartialApply) :
     OptForPartialApply(OptForPartialApply) { }

  void run() override {
    auto *F = getFunction();

    // Don't optimize callees that should not be optimized.
    if (!F->shouldOptimize())
      return;

    // This is the function to optimize.
    DEBUG(llvm::dbgs() << "*** FSO on function: " << F->getName() << " ***\n");

    // Check the signature of F to make sure that it is a function that we
    // can specialize. These are conditions independent of the call graph.
    if (!canSpecializeFunction(F)) {
      DEBUG(llvm::dbgs() << "  cannot specialize function -> abort\n");
      return;
    }

    auto *RCIA = getAnalysis<RCIdentityAnalysis>();
    CallerAnalysis *CA = PM->getAnalysis<CallerAnalysis>();
    auto *EA = PM->getAnalysis<EpilogueARCAnalysis>();

    const CallerAnalysis::FunctionInfo &FuncInfo = CA->getCallerInfo(F);

    // Lock BCA so it's not invalidated along with the rest of the call graph.
    AnalysisPreserver BCAP(PM->getAnalysis<BasicCalleeAnalysis>());

    // As we optimize the function more and more, the name of the function is
    // going to change, make sure the mangler is aware of all the changes done
    // to the function.
    Mangle::Mangler M;
    auto P = Demangle::SpecializationPass::FunctionSignatureOpts;
    FunctionSignatureSpecializationMangler OldFM(P, M, F->isFragile(), F);
    NewMangling::FunctionSignatureSpecializationMangler NewFM(P, F->isFragile(),
                                                              F);

    /// Keep a map between the exploded argument index and the original argument
    /// index.
    llvm::SmallDenseMap<int, int> AIM;
    int asize = F->begin()->getArguments().size();
    for (auto i = 0; i < asize; ++i) {
      AIM[i] = i;
    }

    // Allocate the argument and result descriptors.
    llvm::SmallVector<ArgumentDescriptor, 4> ArgumentDescList;
    llvm::SmallVector<ResultDescriptor, 4> ResultDescList;
    auto Args = F->begin()->getFunctionArguments();
    for (unsigned i = 0, e = Args.size(); i != e; ++i) {
      ArgumentDescList.emplace_back(Args[i]);
    }
    for (SILResultInfo IR : F->getLoweredFunctionType()->getResults()) {
      ResultDescList.emplace_back(IR);
    }

    // Owned to guaranteed optimization.
    FunctionSignatureTransform FST(F, RCIA, EA, OldFM, NewFM, AIM,
                                   ArgumentDescList, ResultDescList);

    bool Changed = false;
    if (OptForPartialApply) {
      Changed = FST.removeDeadArgs(FuncInfo.getMinPartialAppliedArgs());
    } else {
      Changed = FST.run(FuncInfo.hasCaller());
    }
    if (Changed) {
      ++ NumFunctionSignaturesOptimized;
      // The old function must be a thunk now.
      assert(F->isThunk() && "Old function should have been turned into a thunk");

      PM->invalidateAnalysis(F, SILAnalysis::InvalidationKind::Everything);

      // Make sure the PM knows about this function. This will also help us
      // with self-recursion.
      notifyPassManagerOfFunction(FST.getOptimizedFunction(), F);

      if (!OptForPartialApply) {
        // We have to restart the pipeline for this thunk in order to run the
        // inliner (and other opts) again. This is important if the new
        // specialized function (which is called from this thunk) is
        // function-signature-optimized again and also becomes an
        // always-inline-thunk.
        restartPassPipeline();
      }
    }
  }

  StringRef getName() override { return "Function Signature Optimization"; }
};

} // end anonymous namespace

SILTransform *swift::createFunctionSignatureOpts() {
  return new FunctionSignatureOpts(/* OptForPartialApply */ false);
}

SILTransform *swift::createDeadArgSignatureOpt() {
  return new FunctionSignatureOpts(/* OptForPartialApply */ true);
}


text:
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<!DOCTYPE cxxClass PUBLIC "-//NOKIA//DTD DITA C++ API Class Reference Type v0.5.0//EN" "dtd/cxxClass.dtd" >
<cxxClass id="class_c_array_var">
	<apiName>CArrayVar</apiName>
	<cxxClassDetail>
		<cxxClassDefinition>
			<cxxClassAccessSpecifier value="public"/>
			<cxxClassDerivations>
				<cxxClassDerivation>
					<cxxClassDerivationAccessSpecifier value="public"/>
					<cxxClassBaseClass href="class_c_array_var_base.xml#class_c_array_var_base">CArrayVarBase</cxxClassBaseClass>
				</cxxClassDerivation>
			</cxxClassDerivations>
			<cxxClassAPIItemLocation>
				<cxxClassDeclarationFile name="filePath" value="K:/epoc32/include/e32base.h"/>
				<cxxClassDeclarationFileLine name="lineNumber" value="774"/>
				<cxxClassDefinitionFile name="filePath" value="K:/epoc32/include/e32base.h"/>
				<cxxClassDefinitionFileLineStart name="lineNumber" value="763"/>
				<cxxClassDefinitionFileLineEnd name="lineNumber" value="790"/>
			</cxxClassAPIItemLocation>
		</cxxClassDefinition>
		<apiDesc>

A thin templated base class for variable length arrays.

The public functions provide standard array behaviour.

The class is always derived from and is never instantiated explicitly.

		</apiDesc>
	</cxxClassDetail>
	<cxxFunction id="class_c_array_var_1a7c6bb7a3ea3d5426f9cc83593e0c7062">
		<apiName>CArrayVar</apiName>
		<cxxFunctionDetail>
			<cxxFunctionDefinition>
				<cxxFunctionAccessSpecifier value="public"/>
				<cxxFunctionInline/>
				<cxxFunctionConstructor/>
				<cxxFunctionDeclaredType/>
				<cxxFunctionScopedName>CArrayVar</cxxFunctionScopedName>
				<cxxFunctionPrototype>inline CArrayVar(TBufRep aRep, TInt aGranularity)</cxxFunctionPrototype>
				<cxxFunctionNameLookup>CArrayVar::CArrayVar(TBufRep,TInt)</cxxFunctionNameLookup>
				<cxxFunctionParameters>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>
							<apiRelation href="e32base_8h.xml#_1a477fbe9a94ebbd833fc678e7551300c1">TBufRep</apiRelation>
						</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>aRep</cxxFunctionParameterDeclarationName>
						<apiDefNote/>
					</cxxFunctionParameter>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>
							<apiRelation href="e32def_8h.xml#_1abb88f5378e8305d934297176fe5fa298">TInt</apiRelation>
						</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>aGranularity</cxxFunctionParameterDeclarationName>
						<apiDefNote/>
					</cxxFunctionParameter>
				</cxxFunctionParameters>
				<cxxFunctionAPIItemLocation>
					<cxxFunctionDeclarationFile name="filePath" value="K:/epoc32/include/e32base.h"/>
					<cxxFunctionDeclarationFileLine name="lineNumber" value="776"/>
					<cxxFunctionDefinitionFile name="filePath" value="K:/sf/os/commsfw/datacommsserver/esockserver/csock/CS_CLI.CPP"/>
					<cxxFunctionDefinitionFileLineStart name="lineNumber" value="1319"/>
					<cxxFunctionDefinitionFileLineEnd name="lineNumber" value="1324"/>
				</cxxFunctionAPIItemLocation>
			</cxxFunctionDefinition>
			<apiDesc/>
		</cxxFunctionDetail>
	</cxxFunction>
	<cxxFunction id="class_c_array_var_1ac20b0fb977feb3df572bec9412a44c78">
		<apiName>operator[]</apiName>
		<cxxFunctionDetail>
			<cxxFunctionDefinition>
				<cxxFunctionAccessSpecifier value="public"/>
				<cxxFunctionConst/>
				<cxxFunctionInline/>
				<cxxFunctionDeclaredType>const T &</cxxFunctionDeclaredType>
				<cxxFunctionScopedName>CArrayVar</cxxFunctionScopedName>
				<cxxFunctionPrototype>inline const T & operator[](TInt anIndex) const </cxxFunctionPrototype>
				<cxxFunctionNameLookup>CArrayVar::operator[](TInt)const</cxxFunctionNameLookup>
				<cxxFunctionParameters>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>
							<apiRelation href="e32def_8h.xml#_1abb88f5378e8305d934297176fe5fa298">TInt</apiRelation>
						</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>anIndex</cxxFunctionParameterDeclarationName>
						<apiDefNote>The position of the element within the array, relative to zero; i.e. zero implies the first element.</apiDefNote>
					</cxxFunctionParameter>
				</cxxFunctionParameters>
				<cxxFunctionAPIItemLocation>
					<cxxFunctionDeclarationFile name="filePath" value="K:/epoc32/include/e32base.h"/>
					<cxxFunctionDeclarationFileLine name="lineNumber" value="777"/>
					<cxxFunctionDefinitionFile name="filePath" value="K:/sf/os/commsfw/datacommsserver/esockserver/csock/CS_CLI.CPP"/>
					<cxxFunctionDefinitionFileLineStart name="lineNumber" value="1330"/>
					<cxxFunctionDefinitionFileLineEnd name="lineNumber" value="1347"/>
				</cxxFunctionAPIItemLocation>
			</cxxFunctionDefinition>
			<apiDesc>

Gets a reference to the const element located at the specified position within the array.

The compiler uses this variant of the function if the returned reference is used in an expression where it cannot be modified.

A const reference to the element located at position anIndex within the array.

					panic

E32USER-CBase 21, if anIndex is negative or greater than or equal to the number of objects currently within the array.

			</apiDesc>
		</cxxFunctionDetail>
	</cxxFunction>
	<cxxFunction id="class_c_array_var_1a0bd9f7e1aee8442b60a0f085b9cd7fc4">
		<apiName>operator[]</apiName>
		<cxxFunctionDetail>
			<cxxFunctionDefinition>
				<cxxFunctionAccessSpecifier value="public"/>
				<cxxFunctionInline/>
				<cxxFunctionDeclaredType>T &</cxxFunctionDeclaredType>
				<cxxFunctionScopedName>CArrayVar</cxxFunctionScopedName>
				<cxxFunctionPrototype>inline T & operator[](TInt anIndex)</cxxFunctionPrototype>
				<cxxFunctionNameLookup>CArrayVar::operator[](TInt)</cxxFunctionNameLookup>
				<cxxFunctionParameters>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>
							<apiRelation href="e32def_8h.xml#_1abb88f5378e8305d934297176fe5fa298">TInt</apiRelation>
						</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>anIndex</cxxFunctionParameterDeclarationName>
						<apiDefNote>The position of the element within the array, relative to zero; i.e. zero implies the first element.</apiDefNote>
					</cxxFunctionParameter>
				</cxxFunctionParameters>
				<cxxFunctionAPIItemLocation>
					<cxxFunctionDeclarationFile name="filePath" value="K:/epoc32/include/e32base.h"/>
					<cxxFunctionDeclarationFileLine name="lineNumber" value="778"/>
					<cxxFunctionDefinitionFile name="filePath" value="K:/sf/os/commsfw/datacommsserver/esockserver/csock/CS_CLI.CPP"/>
					<cxxFunctionDefinitionFileLineStart name="lineNumber" value="1353"/>
					<cxxFunctionDefinitionFileLineEnd name="lineNumber" value="1371"/>
				</cxxFunctionAPIItemLocation>
			</cxxFunctionDefinition>
			<apiDesc>

Gets a reference to the element located at the specified position within the array.

The compiler uses this variant of the function if the returned reference is used in an expression where it can be modified.

A reference to the non-const element located at position anIndex within the array.

					panic

E32USER-CBase 21, if anIndex is negative or greater than or equal to the number of objects currently within the array.

			</apiDesc>
		</cxxFunctionDetail>
	</cxxFunction>
	<cxxFunction id="class_c_array_var_1aa798a8afdb07734a573f9577572bbc1b">
		<apiName>At</apiName>
		<cxxFunctionDetail>
			<cxxFunctionDefinition>
				<cxxFunctionAccessSpecifier value="public"/>
				<cxxFunctionConst/>
				<cxxFunctionInline/>
				<cxxFunctionDeclaredType>const T &</cxxFunctionDeclaredType>
				<cxxFunctionScopedName>CArrayVar</cxxFunctionScopedName>
				<cxxFunctionPrototype>inline const T & At(TInt anIndex) const </cxxFunctionPrototype>
				<cxxFunctionNameLookup>CArrayVar::At(TInt)const</cxxFunctionNameLookup>
				<cxxFunctionReimplemented href="class_c_array_var_base.xml#class_c_array_var_base_1a61015740adaac2867675bab5920fb75d">CArrayVarBase::At(TInt)const</cxxFunctionReimplemented>
				<cxxFunctionParameters>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>
							<apiRelation href="e32def_8h.xml#_1abb88f5378e8305d934297176fe5fa298">TInt</apiRelation>
						</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>anIndex</cxxFunctionParameterDeclarationName>
						<apiDefNote>The position of the element within the array, relative to zero; i.e. zero implies the first element.</apiDefNote>
					</cxxFunctionParameter>
				</cxxFunctionParameters>
				<cxxFunctionAPIItemLocation>
					<cxxFunctionDeclarationFile name="filePath" value="K:/epoc32/include/e32base.h"/>
					<cxxFunctionDeclarationFileLine name="lineNumber" value="779"/>
					<cxxFunctionDefinitionFile name="filePath" value="K:/sf/os/commsfw/datacommsserver/esockserver/csock/CS_CLI.CPP"/>
					<cxxFunctionDefinitionFileLineStart name="lineNumber" value="1377"/>
					<cxxFunctionDefinitionFileLineEnd name="lineNumber" value="1394"/>
				</cxxFunctionAPIItemLocation>
			</cxxFunctionDefinition>
			<apiDesc>

Gets a reference to the const element located at the specified position within the array.

The compiler uses this variant of the function if the returned reference is used in an expression where it cannot be modified.

A const reference to the element located at position anIndex within the array.

					panic

E32USER-CBase 21, if anIndex is negative or greater than or equal to the number of objects currently within the array.

			</apiDesc>
		</cxxFunctionDetail>
	</cxxFunction>
	<cxxFunction id="class_c_array_var_1a33be89682bccb50561cb1ff8399cab8c">
		<apiName>At</apiName>
		<cxxFunctionDetail>
			<cxxFunctionDefinition>
				<cxxFunctionAccessSpecifier value="public"/>
				<cxxFunctionInline/>
				<cxxFunctionDeclaredType>T &</cxxFunctionDeclaredType>
				<cxxFunctionScopedName>CArrayVar</cxxFunctionScopedName>
				<cxxFunctionPrototype>inline T & At(TInt anIndex)</cxxFunctionPrototype>
				<cxxFunctionNameLookup>CArrayVar::At(TInt)</cxxFunctionNameLookup>
				<cxxFunctionParameters>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>
							<apiRelation href="e32def_8h.xml#_1abb88f5378e8305d934297176fe5fa298">TInt</apiRelation>
						</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>anIndex</cxxFunctionParameterDeclarationName>
						<apiDefNote>The position of the element within the array, relative to zero; i.e. zero implies the first element.</apiDefNote>
					</cxxFunctionParameter>
				</cxxFunctionParameters>
				<cxxFunctionAPIItemLocation>
					<cxxFunctionDeclarationFile name="filePath" value="K:/epoc32/include/e32base.h"/>
					<cxxFunctionDeclarationFileLine name="lineNumber" value="780"/>
					<cxxFunctionDefinitionFile name="filePath" value="K:/sf/os/commsfw/datacommsserver/esockserver/csock/CS_CLI.CPP"/>
					<cxxFunctionDefinitionFileLineStart name="lineNumber" value="1399"/>
					<cxxFunctionDefinitionFileLineEnd name="lineNumber" value="1416"/>
				</cxxFunctionAPIItemLocation>
			</cxxFunctionDefinition>
			<apiDesc>

Gets a reference to the element located at the specified position within the array.

The compiler uses this variant of the function if the returned reference is used in an expression where it can be modified.

A reference to the non-const element located at position anIndex within the array.

					panic

E32USER-CBase 21, if anIndex is negative or greater than or equal to the number of objects currently within the array.

			</apiDesc>
		</cxxFunctionDetail>
	</cxxFunction>
	<cxxFunction id="class_c_array_var_1a285b2cbcbe251d08a70f9939a28253f4">
		<apiName>AppendL</apiName>
		<cxxFunctionDetail>
			<cxxFunctionDefinition>
				<cxxFunctionAccessSpecifier value="public"/>
				<cxxFunctionInline/>
				<cxxFunctionDeclaredType>void</cxxFunctionDeclaredType>
				<cxxFunctionScopedName>CArrayVar</cxxFunctionScopedName>
				<cxxFunctionPrototype>inline void AppendL(const T &aRef, TInt aLength)</cxxFunctionPrototype>
				<cxxFunctionNameLookup>CArrayVar::AppendL(const T &,TInt)</cxxFunctionNameLookup>
				<cxxFunctionParameters>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>const T &</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>aRef</cxxFunctionParameterDeclarationName>
						<apiDefNote>A reference to the <class T> element to be appended. </apiDefNote>
					</cxxFunctionParameter>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>
							<apiRelation href="e32def_8h.xml#_1abb88f5378e8305d934297176fe5fa298">TInt</apiRelation>
						</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>aLength</cxxFunctionParameterDeclarationName>
						<apiDefNote>The length of the element to be appended.</apiDefNote>
					</cxxFunctionParameter>
				</cxxFunctionParameters>
				<cxxFunctionAPIItemLocation>
					<cxxFunctionDeclarationFile name="filePath" value="K:/epoc32/include/e32base.h"/>
					<cxxFunctionDeclarationFileLine name="lineNumber" value="781"/>
					<cxxFunctionDefinitionFile name="filePath" value="K:/sf/os/commsfw/datacommsserver/esockserver/csock/CS_CLI.CPP"/>
					<cxxFunctionDefinitionFileLineStart name="lineNumber" value="1422"/>
					<cxxFunctionDefinitionFileLineEnd name="lineNumber" value="1436"/>
				</cxxFunctionAPIItemLocation>
			</cxxFunctionDefinition>
			<apiDesc>

Appends an element of a specified length onto the array.

					leave

KErrNoMemory The function always attempts to allocate a cell to contain the new element and may also attempt to expand the array buffer. If there is insufficient memory available, the function leaves, in which case, the array is left in the state it was in before the call.

					panic

E32USER-CBase 30, if aLength is negative.

			</apiDesc>
		</cxxFunctionDetail>
	</cxxFunction>
	<cxxFunction id="class_c_array_var_1adf141ce15efc824040ab5bfa06ba6716">
		<apiName>ExpandL</apiName>
		<cxxFunctionDetail>
			<cxxFunctionDefinition>
				<cxxFunctionAccessSpecifier value="public"/>
				<cxxFunctionInline/>
				<cxxFunctionDeclaredType>T &</cxxFunctionDeclaredType>
				<cxxFunctionScopedName>CArrayVar</cxxFunctionScopedName>
				<cxxFunctionPrototype>inline T & ExpandL(TInt anIndex, TInt aLength)</cxxFunctionPrototype>
				<cxxFunctionNameLookup>CArrayVar::ExpandL(TInt,TInt)</cxxFunctionNameLookup>
				<cxxFunctionReimplemented href="class_c_array_var_base.xml#class_c_array_var_base_1a7f5aed90e2e28f606df61aee4a916b31">CArrayVarBase::ExpandL(TInt,TInt)</cxxFunctionReimplemented>
				<cxxFunctionParameters>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>
							<apiRelation href="e32def_8h.xml#_1abb88f5378e8305d934297176fe5fa298">TInt</apiRelation>
						</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>anIndex</cxxFunctionParameterDeclarationName>
						<apiDefNote>The position within the array where the array is to be expanded and the new <class T> object is to be constructed.</apiDefNote>
					</cxxFunctionParameter>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>
							<apiRelation href="e32def_8h.xml#_1abb88f5378e8305d934297176fe5fa298">TInt</apiRelation>
						</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>aLength</cxxFunctionParameterDeclarationName>
						<apiDefNote>The length of the new element.</apiDefNote>
					</cxxFunctionParameter>
				</cxxFunctionParameters>
				<cxxFunctionAPIItemLocation>
					<cxxFunctionDeclarationFile name="filePath" value="K:/epoc32/include/e32base.h"/>
					<cxxFunctionDeclarationFileLine name="lineNumber" value="782"/>
					<cxxFunctionDefinitionFile name="filePath" value="K:/sf/os/commsfw/datacommsserver/esockserver/csock/CS_CLI.CPP"/>
					<cxxFunctionDefinitionFileLineStart name="lineNumber" value="1442"/>
					<cxxFunctionDefinitionFileLineEnd name="lineNumber" value="1478"/>
				</cxxFunctionAPIItemLocation>
			</cxxFunctionDefinition>
			<apiDesc>

Expands the array by one element of specified length at the specified position.

It:

1. expands the array by one element position anIndex

2. constructs a new element of specified length at that position

3. returns a reference to the new element.

All existing elements from position anIndex to the end of the array are moved up, so that the element originally at position anIndex is now at position anIndex + 1 etc.

The new element of type <class T> and length aLength is constructed at position anIndex, using the default constructor of that class.

A reference to the newly constructed <class T> object at position anIndex within the array.

					leave

KErrNoMemory The function always attempts to allocate a cell to contain the new element and may also attempt to expand the array buffer. If there is insufficient memory available, the function leaves, in which case, the array is left in the state it was in before the call.

					panic

E32USER-CBase 21, if anIndex is negative or is greater than the number of elements currently in the array.

					panic

E32USER-CBase 30, if aLength is negative.

			</apiDesc>
		</cxxFunctionDetail>
	</cxxFunction>
	<cxxFunction id="class_c_array_var_1ae7bc0885e61422a66059fd7d341db2e0">
		<apiName>ExtendL</apiName>
		<cxxFunctionDetail>
			<cxxFunctionDefinition>
				<cxxFunctionAccessSpecifier value="public"/>
				<cxxFunctionInline/>
				<cxxFunctionDeclaredType>T &</cxxFunctionDeclaredType>
				<cxxFunctionScopedName>CArrayVar</cxxFunctionScopedName>
				<cxxFunctionPrototype>inline T & ExtendL(TInt aLength)</cxxFunctionPrototype>
				<cxxFunctionNameLookup>CArrayVar::ExtendL(TInt)</cxxFunctionNameLookup>
				<cxxFunctionParameters>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>
							<apiRelation href="e32def_8h.xml#_1abb88f5378e8305d934297176fe5fa298">TInt</apiRelation>
						</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>aLength</cxxFunctionParameterDeclarationName>
						<apiDefNote>The length of the new element.</apiDefNote>
					</cxxFunctionParameter>
				</cxxFunctionParameters>
				<cxxFunctionAPIItemLocation>
					<cxxFunctionDeclarationFile name="filePath" value="K:/epoc32/include/e32base.h"/>
					<cxxFunctionDeclarationFileLine name="lineNumber" value="783"/>
					<cxxFunctionDefinitionFile name="filePath" value="K:/sf/os/commsfw/datacommsserver/esockserver/csock/CS_CLI.CPP"/>
					<cxxFunctionDefinitionFileLineStart name="lineNumber" value="1484"/>
					<cxxFunctionDefinitionFileLineEnd name="lineNumber" value="1512"/>
				</cxxFunctionAPIItemLocation>
			</cxxFunctionDefinition>
			<apiDesc>

Expands the array by one element of specified length at the end of the array.

It:

1. expands the array by one element at the end of the array, i.e. at position <xref href="class_c_array_var_base.xml#class_c_array_var_base_1af56230d7653e6784e23c493495ec0a5f">CArrayVarBase::Count()</xref>

2. constructs a new element of specified length at that position.

3. returns a reference to the new element.

The new element of type <class T> is constructed at the end of the array, using the default constructor of that class.

A reference to the newly constructed <class T> object at the end of the array.

					leave

KErrNoMemory The function always attempts to allocate a cell to contain the new element and may also attempt to expand the array buffer. If there is insufficient memory available, the function leaves, in which case, the array is left in the state it was in before the call.

					panic

E32USER-CBase 30, if aLength is negative.

			</apiDesc>
		</cxxFunctionDetail>
	</cxxFunction>
	<cxxFunction id="class_c_array_var_1a584aaceab810485dcfb2d50feb3009e4">
		<apiName>Find</apiName>
		<cxxFunctionDetail>
			<cxxFunctionDefinition>
				<cxxFunctionAccessSpecifier value="public"/>
				<cxxFunctionConst/>
				<cxxFunctionInline/>
				<cxxFunctionDeclaredType>
					<apiRelation href="e32def_8h.xml#_1abb88f5378e8305d934297176fe5fa298">TInt</apiRelation>
				</cxxFunctionDeclaredType>
				<cxxFunctionScopedName>CArrayVar</cxxFunctionScopedName>
				<cxxFunctionPrototype>inline TInt Find(const T &aRef, TKeyArrayVar &aKey, TInt &anIndex) const </cxxFunctionPrototype>
				<cxxFunctionNameLookup>CArrayVar::Find(const T &,TKeyArrayVar &,TInt &)const</cxxFunctionNameLookup>
				<cxxFunctionParameters>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>const T &</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>aRef</cxxFunctionParameterDeclarationName>
						<apiDefNote>A reference to an object of type <class T> whose key is used for comparison. </apiDefNote>
					</cxxFunctionParameter>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>
							<apiRelation href="class_t_key_array_var.xml#class_t_key_array_var">TKeyArrayVar</apiRelation> &</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>aKey</cxxFunctionParameterDeclarationName>
						<apiDefNote>A reference to a key object defining the properties of the key. </apiDefNote>
					</cxxFunctionParameter>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>
							<apiRelation href="e32def_8h.xml#_1abb88f5378e8305d934297176fe5fa298">TInt</apiRelation> &</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>anIndex</cxxFunctionParameterDeclarationName>
						<apiDefNote>A TInt supplied by the caller. On return, if the element is found, this is set to the position of that element within the array. The position is relative to zero, (i.e. the first element in the array is at position 0). If the element is not found or the array is empty, then this is undefined.</apiDefNote>
					</cxxFunctionParameter>
				</cxxFunctionParameters>
				<cxxFunctionAPIItemLocation>
					<cxxFunctionDeclarationFile name="filePath" value="K:/epoc32/include/e32base.h"/>
					<cxxFunctionDeclarationFileLine name="lineNumber" value="784"/>
					<cxxFunctionDefinitionFile name="filePath" value="K:/sf/os/commsfw/datacommsserver/esockserver/csock/CS_CLI.CPP"/>
					<cxxFunctionDefinitionFileLineStart name="lineNumber" value="1518"/>
					<cxxFunctionDefinitionFileLineEnd name="lineNumber" value="1542"/>
				</cxxFunctionAPIItemLocation>
			</cxxFunctionDefinition>
			<apiDesc>

Finds the position of an element within the array, based on the matching of keys, using a sequential search.

The array is searched sequentially for an element whose key matches the key of the supplied object. The search starts with the first element in the array.

Note that where an array has elements with duplicate keys, the function only supplies the position of the first element in the array with that key.

Zero, if the element with the specified key is found. Non-zero, if the element with the specified key is not found.

			</apiDesc>
		</cxxFunctionDetail>
	</cxxFunction>
	<cxxFunction id="class_c_array_var_1a26e98e59d00683e024a396c729e69aee">
		<apiName>FindIsq</apiName>
		<cxxFunctionDetail>
			<cxxFunctionDefinition>
				<cxxFunctionAccessSpecifier value="public"/>
				<cxxFunctionConst/>
				<cxxFunctionInline/>
				<cxxFunctionDeclaredType>
					<apiRelation href="e32def_8h.xml#_1abb88f5378e8305d934297176fe5fa298">TInt</apiRelation>
				</cxxFunctionDeclaredType>
				<cxxFunctionScopedName>CArrayVar</cxxFunctionScopedName>
				<cxxFunctionPrototype>inline TInt FindIsq(const T &aRef, TKeyArrayVar &aKey, TInt &anIndex) const </cxxFunctionPrototype>
				<cxxFunctionNameLookup>CArrayVar::FindIsq(const T &,TKeyArrayVar &,TInt &)const</cxxFunctionNameLookup>
				<cxxFunctionParameters>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>const T &</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>aRef</cxxFunctionParameterDeclarationName>
						<apiDefNote>A reference to an object of type <class T> whose key is used for comparison. </apiDefNote>
					</cxxFunctionParameter>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>
							<apiRelation href="class_t_key_array_var.xml#class_t_key_array_var">TKeyArrayVar</apiRelation> &</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>aKey</cxxFunctionParameterDeclarationName>
						<apiDefNote>A reference to a key object defining the properties of the key. </apiDefNote>
					</cxxFunctionParameter>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>
							<apiRelation href="e32def_8h.xml#_1abb88f5378e8305d934297176fe5fa298">TInt</apiRelation> &</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>anIndex</cxxFunctionParameterDeclarationName>
						<apiDefNote>A TInt supplied by the caller. On return, if the element is found, this is set to the position of that element within the array. The position is relative to zero, (i.e. the first element in the array is at position zero). If the element is not found and the array is not empty, then this is set to the position of the first element in the array with a key which is greater than the key of the object aRef. If the element is not found and the array is empty, then this is undefined.</apiDefNote>
					</cxxFunctionParameter>
				</cxxFunctionParameters>
				<cxxFunctionAPIItemLocation>
					<cxxFunctionDeclarationFile name="filePath" value="K:/epoc32/include/e32base.h"/>
					<cxxFunctionDeclarationFileLine name="lineNumber" value="785"/>
					<cxxFunctionDefinitionFile name="filePath" value="K:/sf/os/commsfw/datacommsserver/esockserver/csock/CS_CLI.CPP"/>
					<cxxFunctionDefinitionFileLineStart name="lineNumber" value="1548"/>
					<cxxFunctionDefinitionFileLineEnd name="lineNumber" value="1578"/>
				</cxxFunctionAPIItemLocation>
			</cxxFunctionDefinition>
			<apiDesc>

Finds the position of an element within the array, based on the matching of keys, using a binary search technique.

The array is searched, using a binary search technique, for an element whose key matches the key of the supplied <class T> object.

The array must be in key order.

Note that where an array has elements with duplicate keys, the function cannot guarantee which element, with the given key value, it will return, except that it will find one of them.

Zero, if the element with the specified key is found or the array is empty. Non-zero, if the element with the specified key is not found.

			</apiDesc>
		</cxxFunctionDetail>
	</cxxFunction>
	<cxxFunction id="class_c_array_var_1a13617c829ab29f8315cc8748687c8c25">
		<apiName>InsertL</apiName>
		<cxxFunctionDetail>
			<cxxFunctionDefinition>
				<cxxFunctionAccessSpecifier value="public"/>
				<cxxFunctionInline/>
				<cxxFunctionDeclaredType>void</cxxFunctionDeclaredType>
				<cxxFunctionScopedName>CArrayVar</cxxFunctionScopedName>
				<cxxFunctionPrototype>inline void InsertL(TInt anIndex, const T &aRef, TInt aLength)</cxxFunctionPrototype>
				<cxxFunctionNameLookup>CArrayVar::InsertL(TInt,const T &,TInt)</cxxFunctionNameLookup>
				<cxxFunctionParameters>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>
							<apiRelation href="e32def_8h.xml#_1abb88f5378e8305d934297176fe5fa298">TInt</apiRelation>
						</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>anIndex</cxxFunctionParameterDeclarationName>
						<apiDefNote>The position within the array where the element is to be inserted. The position is relative to zero, i.e. zero implies that elements are inserted at the beginning of the array. </apiDefNote>
					</cxxFunctionParameter>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>const T &</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>aRef</cxxFunctionParameterDeclarationName>
						<apiDefNote>A reference to the <class T> object to be inserted into the array. </apiDefNote>
					</cxxFunctionParameter>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>
							<apiRelation href="e32def_8h.xml#_1abb88f5378e8305d934297176fe5fa298">TInt</apiRelation>
						</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>aLength</cxxFunctionParameterDeclarationName>
						<apiDefNote>The length of the element to be inserted into the array.</apiDefNote>
					</cxxFunctionParameter>
				</cxxFunctionParameters>
				<cxxFunctionAPIItemLocation>
					<cxxFunctionDeclarationFile name="filePath" value="K:/epoc32/include/e32base.h"/>
					<cxxFunctionDeclarationFileLine name="lineNumber" value="786"/>
					<cxxFunctionDefinitionFile name="filePath" value="K:/sf/os/commsfw/datacommsserver/esockserver/csock/CS_CLI.CPP"/>
					<cxxFunctionDefinitionFileLineStart name="lineNumber" value="1584"/>
					<cxxFunctionDefinitionFileLineEnd name="lineNumber" value="1608"/>
				</cxxFunctionAPIItemLocation>
			</cxxFunctionDefinition>
			<apiDesc>

Inserts an element of a specified length into the array at the specified position.

Note that passing a value of anIndex which is the same as the current number of elements in the array, has the effect of appending that element.

					leave

KErrNoMemory The function always attempts to allocate a cell to contain the new element and may also attempt to expand the array buffer. If there is insufficient memory available, the function leaves, in which case, the array is left in the state it was in before the call.

					panic

E32USER-CBase 21, if anIndex is negative or is greater than the number of objects currently in the array.

					panic

E32USER-CBase 30, if aLength is is negative.

			</apiDesc>
		</cxxFunctionDetail>
	</cxxFunction>
	<cxxFunction id="class_c_array_var_1adc7605d6107c4b41dedec177567c472e">
		<apiName>InsertIsqL</apiName>
		<cxxFunctionDetail>
			<cxxFunctionDefinition>
				<cxxFunctionAccessSpecifier value="public"/>
				<cxxFunctionInline/>
				<cxxFunctionDeclaredType>
					<apiRelation href="e32def_8h.xml#_1abb88f5378e8305d934297176fe5fa298">TInt</apiRelation>
				</cxxFunctionDeclaredType>
				<cxxFunctionScopedName>CArrayVar</cxxFunctionScopedName>
				<cxxFunctionPrototype>inline TInt InsertIsqL(const T &aRef, TInt aLength, TKeyArrayVar &aKey)</cxxFunctionPrototype>
				<cxxFunctionNameLookup>CArrayVar::InsertIsqL(const T &,TInt,TKeyArrayVar &)</cxxFunctionNameLookup>
				<cxxFunctionParameters>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>const T &</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>aRef</cxxFunctionParameterDeclarationName>
						<apiDefNote>A reference to the element of type <class T> to be inserted into the array. </apiDefNote>
					</cxxFunctionParameter>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>
							<apiRelation href="e32def_8h.xml#_1abb88f5378e8305d934297176fe5fa298">TInt</apiRelation>
						</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>aLength</cxxFunctionParameterDeclarationName>
						<apiDefNote>The length of the new element of type <class T> to be inserted into the array. </apiDefNote>
					</cxxFunctionParameter>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>
							<apiRelation href="class_t_key_array_var.xml#class_t_key_array_var">TKeyArrayVar</apiRelation> &</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>aKey</cxxFunctionParameterDeclarationName>
						<apiDefNote>A reference to a key object defining the properties of the key.</apiDefNote>
					</cxxFunctionParameter>
				</cxxFunctionParameters>
				<cxxFunctionAPIItemLocation>
					<cxxFunctionDeclarationFile name="filePath" value="K:/epoc32/include/e32base.h"/>
					<cxxFunctionDeclarationFileLine name="lineNumber" value="787"/>
					<cxxFunctionDefinitionFile name="filePath" value="K:/sf/os/commsfw/datacommsserver/esockserver/csock/CS_CLI.CPP"/>
					<cxxFunctionDefinitionFileLineStart name="lineNumber" value="1614"/>
					<cxxFunctionDefinitionFileLineEnd name="lineNumber" value="1641"/>
				</cxxFunctionAPIItemLocation>
			</cxxFunctionDefinition>
			<apiDesc>

Inserts a single element of a specified length into the array at a position determined by a key.

The array MUST already be in key sequence (as defined by the key), otherwise the position of the new element is unpredictable, or duplicates may occur.

Elements with duplicate keys are not permitted.

The position within the array of the newly inserted element.

					leave

KErrAlreadyExists An element with the same key already exists within the array. NB the array MUST already be in key sequence, otherwise the function may insert a duplicate and fail to leave with this value.

					leave

KErrNoMemory The function always attempts to allocate a cell to contain the new element and may also attempt to expand the array buffer. If there is insufficient memory available, the function leaves, in which case, the array is left in the state it was in before the call.

			</apiDesc>
		</cxxFunctionDetail>
	</cxxFunction>
	<cxxFunction id="class_c_array_var_1a060ad23b933ce579a0ec219f4c1a6552">
		<apiName>InsertIsqAllowDuplicatesL</apiName>
		<cxxFunctionDetail>
			<cxxFunctionDefinition>
				<cxxFunctionAccessSpecifier value="public"/>
				<cxxFunctionInline/>
				<cxxFunctionDeclaredType>
					<apiRelation href="e32def_8h.xml#_1abb88f5378e8305d934297176fe5fa298">TInt</apiRelation>
				</cxxFunctionDeclaredType>
				<cxxFunctionScopedName>CArrayVar</cxxFunctionScopedName>
				<cxxFunctionPrototype>inline TInt InsertIsqAllowDuplicatesL(const T &aRef, TInt aLength, TKeyArrayVar &aKey)</cxxFunctionPrototype>
				<cxxFunctionNameLookup>CArrayVar::InsertIsqAllowDuplicatesL(const T &,TInt,TKeyArrayVar &)</cxxFunctionNameLookup>
				<cxxFunctionParameters>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>const T &</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>aRef</cxxFunctionParameterDeclarationName>
						<apiDefNote>A reference to the element of type <class T> to be inserted into the array. </apiDefNote>
					</cxxFunctionParameter>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>
							<apiRelation href="e32def_8h.xml#_1abb88f5378e8305d934297176fe5fa298">TInt</apiRelation>
						</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>aLength</cxxFunctionParameterDeclarationName>
						<apiDefNote>The length of the new element to be inserted into the array. </apiDefNote>
					</cxxFunctionParameter>
					<cxxFunctionParameter>
						<cxxFunctionParameterDeclaredType>
							<apiRelation href="class_t_key_array_var.xml#class_t_key_array_var">TKeyArrayVar</apiRelation> &</cxxFunctionParameterDeclaredType>
						<cxxFunctionParameterDeclarationName>aKey</cxxFunctionParameterDeclarationName>
						<apiDefNote>A reference to a key object defining the properties of the key.</apiDefNote>
					</cxxFunctionParameter>
				</cxxFunctionParameters>
				<cxxFunctionAPIItemLocation>
					<cxxFunctionDeclarationFile name="filePath" value="K:/epoc32/include/e32base.h"/>
					<cxxFunctionDeclarationFileLine name="lineNumber" value="788"/>
					<cxxFunctionDefinitionFile name="filePath" value="K:/sf/os/commsfw/datacommsserver/esockserver/csock/CS_CLI.CPP"/>
					<cxxFunctionDefinitionFileLineStart name="lineNumber" value="1647"/>
					<cxxFunctionDefinitionFileLineEnd name="lineNumber" value="1671"/>
				</cxxFunctionAPIItemLocation>
			</cxxFunctionDefinition>
			<apiDesc>

Inserts a single element of a specified length into the array at a position determined by a key, allowing duplicates.

The array MUST already be in key sequence, otherwise the position of the new element is unpredictable.

Elements with duplicate keys are permitted. If the new element's key is a duplicate of an existing element's key, then the new element is positioned after the existing element.

The position within the array of the newly inserted element.

					leave

KErrNoMemory The function always attempts to allocate a cell to contain the new element and may also attempt to expand the array buffer. If there is insufficient memory available, the function leaves, in which case, the array is left in the state it was in before the call.

			</apiDesc>
		</cxxFunctionDetail>
	</cxxFunction>
	<cxxFunction id="class_c_array_var_1a0b0c4749feb454162b6b2e1cfa57e1ca">
		<apiName>Array</apiName>
		<cxxFunctionDetail>
			<cxxFunctionDefinition>
				<cxxFunctionAccessSpecifier value="public"/>
				<cxxFunctionConst/>
				<cxxFunctionInline/>
				<cxxFunctionDeclaredType>const <apiRelation href="class_t_array.xml#class_t_array">TArray</apiRelation>< T ></cxxFunctionDeclaredType>
				<cxxFunctionScopedName>CArrayVar</cxxFunctionScopedName>
				<cxxFunctionPrototype>inline const TArray< T > Array() const </cxxFunctionPrototype>
				<cxxFunctionNameLookup>CArrayVar::Array()const</cxxFunctionNameLookup>
				<cxxFunctionParameters/>
				<cxxFunctionAPIItemLocation>
					<cxxFunctionDeclarationFile name="filePath" value="K:/epoc32/include/e32base.h"/>
					<cxxFunctionDeclarationFileLine name="lineNumber" value="789"/>
					<cxxFunctionDefinitionFile name="filePath" value="K:/sf/os/commsfw/datacommsserver/esockserver/csock/CS_CLI.CPP"/>
					<cxxFunctionDefinitionFileLineStart name="lineNumber" value="1677"/>
					<cxxFunctionDefinitionFileLineEnd name="lineNumber" value="1683"/>
				</cxxFunctionAPIItemLocation>
			</cxxFunctionDefinition>
			<apiDesc>

Constructs and returns a TArray<T> object.

A TArray<T> object for this array.

			</apiDesc>
		</cxxFunctionDetail>
	</cxxFunction>
	<cxxClassInherits>
		<cxxClassInheritsDetail>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_array_var_base_1ae07f7130e2b305a9f09e2d3fca2d9654">CArrayVarBase::AtR(const CBase *,TInt)</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_array_var_base_1a52fdb1c89be71fcdd9502080967a3961">CArrayVarBase::CArrayVarBase(TBufRep,TInt)</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_array_var_base_1a78ba5bfdc44112c44c518da23492bfd4">CArrayVarBase::Compress()</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_array_var_base_1af56230d7653e6784e23c493495ec0a5f">CArrayVarBase::Count()const</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_array_var_base_1a9a1b913b29cb096c96878849c377be83">CArrayVarBase::CountR(const CBase *)</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_array_var_base_1a1fffc2ca617bf985a9eb06a65959eee2">CArrayVarBase::Delete(TInt)</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_array_var_base_1a24c19a87adf8a05840d81829a98b0abb">CArrayVarBase::Delete(TInt,TInt)</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_array_var_base_1aea70ba1b25ee0bc6535c26f1a57bf64f">CArrayVarBase::Find(const TAny *,TKeyArrayVar &,TInt &)const</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_array_var_base_1a48205701261c1f396301ace109757480">CArrayVarBase::FindIsq(const TAny *,TKeyArrayVar &,TInt &)const</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_array_var_base_1a1d09e54c3e421854ccbed09d2a700c33">CArrayVarBase::InsertIsqAllowDuplicatesL(const TAny *,TInt,TKeyArrayVar &)</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_array_var_base_1ae17d605a2a8d9878288bba39a67b4e2f">CArrayVarBase::InsertIsqL(const TAny *,TInt,TKeyArrayVar &)</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_array_var_base_1a9f0edefe9154852b1dd8f875084ac2b1">CArrayVarBase::InsertL(TInt,const TAny *,TInt)</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_array_var_base_1a6ac8ff1b1244c8ac931f4075b7b8db31">CArrayVarBase::Length(TInt)const</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_array_var_base_1aa9fecbd5db7a03b57f142d3619691ae1">CArrayVarBase::Reset()</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_array_var_base_1ab66d6e1ed4e79ade948e1bb0ecb40a6d">CArrayVarBase::SetKey(TKeyArrayVar &)const</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_array_var_base_1a72fa537ed6e7985b25218e4c9e3ae1d9">CArrayVarBase::Sort(TKeyArrayVar &)</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_array_var_base_1ae0c9f25f79df144b82ec0ac351a610ff">CArrayVarBase::~CArrayVarBase()</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_base_1a240de7932690a4e987d75690b0b6f82b">CBase::CBase()</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_base_1ac0a06aeab68b3e01be81f9dd79e011c6">CBase::Delete(CBase *)</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_base_1aae681a54d9c9b10c7d42e7e32ff109d5">CBase::Extension_(TUint,TAny *&,TAny *)</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_base_1af4c4965092a763b0856ccbfa3cf99eaf">CBase::operator new(TUint)</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_base_1ab9e5f557dea4db22886189926687ddc1">CBase::operator new(TUint,TAny *)</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_base_1aa464dd21494443ac109084ed03b81f28">CBase::operator new(TUint,TLeave)</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_base_1af8429815362d4df6fecd47179e0c5dfe">CBase::operator new(TUint,TLeave,TUint)</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_base_1a80505bdf8b1b20a2ed102307a78eeeeb">CBase::operator new(TUint,TUint)</cxxClassFunctionInherited>
			<cxxClassFunctionInherited href="class_c_array_var.xml#class_c_base_1a1390361b94424be22bb2b1020eb400ea">CBase::~CBase()</cxxClassFunctionInherited>
		</cxxClassInheritsDetail>
	</cxxClassInherits>
</cxxClass>

redpajama_set_name: RedPajamaGithub


text:
#ifndef _KEYBOARD_H_
#define _KEYBOARD_H_

#define KEYBORAD_CLICK			0x5014
#define ON_KEYBORAD_UPDATE(ctrlId, func)  \
{MSG_TYPE_WND, KEYBORAD_CLICK, (c_cmd_target*)ctrlId, MSG_CALLBACK_VWL, (MsgFuncVV)(static_cast<void (c_cmd_target::*)(unsigned int, long)>(&func))},

typedef enum
{
	STATUS_UPPERCASE,
	STATUS_LOWERCASE
}KEYBOARD_STATUS;

typedef enum
{
	STYLE_ALL_BOARD,
	STYLE_NUM_BOARD
}KEYBOARD_STYLE;

typedef enum
{
	CLICK_CHAR,
	CLICK_ENTER,
	CLICK_ESC
}CLICK_STATUS;

class c_keyboard: public c_wnd
{
public:
	virtual int create(c_wnd *parent, unsigned short resource_id, unsigned short str_id,
		short x, short y, short width, short height, WND_TREE* p_child_tree = NULL);
	KEYBOARD_STATUS get_cap_status(){return m_cap_status;}
	void set_style(KEYBOARD_STYLE style) { m_style = style; }
	char* get_str() { return m_str; }
protected:
	virtual void pre_create_wnd();
	virtual c_wnd* clone(){return new c_keyboard();}

	void on_char_clicked(unsigned int ctrl_id);
	void on_del_clicked(unsigned int ctrl_id);
	void on_caps_clicked(unsigned int ctrl_id);
	void on_enter_clicked(unsigned int ctrl_id);
	void on_esc_clicked(unsigned int ctrl_id);

	GLT_DECLARE_MESSAGE_MAP()
private:
	char m_str[32];
	int	 m_str_len;
	KEYBOARD_STATUS m_cap_status;
	KEYBOARD_STYLE	m_stlyle;
};

class c_keyboard_button : public c_button
{
protected:
	virtual c_wnd* clone(){return new c_keyboard_button();}
	virtual void on_paint();
};

#endif /* KEYBOARD_H_ */


text:
<?php

/**
 * Description of TrackStarActiveRecord
 *
 * @author chenli
 */
abstract class TrackStarActiveRecord extends CActiveRecord {

  /**
   * Prepares create_user_id and update_user_id attributes before saving.
   */
  protected function beforeSave() {

    if (null !== Yii::app()->user)
      $id = Yii::app()->user->id;
    else
      $id = 1;

    if ($this->isNewRecord)
      $this->create_user_id = $id;

    $this->update_user_id = $id;

    return parent::beforeSave();
  }

  /**
   * Attaches the timestamp behavior to update our create and update times
   */
  public function behaviors() {
    return array(
      'CTimestampBehavior' => array(
        'class' => 'zii.behaviors.CTimestampBehavior',
        'createAttribute' => 'create_time',
        'updateAttribute' => 'update_time',
        'setUpdateOnCreate' => true,
      ),
    );
  }

}

?>


text:
<!doctype html>

		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width,initial-scale=1">
		<title>jQuery Mobile Twitter Bootstrap Theme</title>
		<link rel="stylesheet" href="themes/Bootstrap.css">
		<link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.1/jquery.mobile.structure-1.1.1.min.css" />
		<link rel="stylesheet" href="themes/jqm-icon-pack-1.1.1-fa.css">

jQuery Mobile Twitter Bootstrap Theme

						Home
						Buttons
						Lists
						Nav
						Forms

				Get the code

Overview

					The jQuery Mobile Bootstrap theme is meant to duplicate the appearance of Twitter Bootstrap within the context of a jQuery Mobile application. Currently only the colors are mimiced, but eventually some of the components might also work their way into the theme.


text:
package com.spectralogic.ds3client.models.common;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

import java.util.Objects;

public final class Range implements Comparable<Range> {
    @JacksonXmlProperty(localName = "Offset", isAttribute = true)
    private final long start;

    @JsonIgnore
    private final long end;

    @JacksonXmlProperty(localName = "Length", isAttribute = true)
    private final long length;

    public static Range byPosition(final long start, final long end) {
        return new Range(start, end);
    }

    public static Range byLength(final long offset, final long length) {
        return new Range(offset, offset + length - 1);
    }

    public Range(final long start, final long end) {
        this.start = start;
        this.end = end;
        this.length = end - start + 1;
    }

    public long getLength() {
        return length;
    }

    public long getStart() {
         return this.start;
    }

    public long getEnd() {
       return this.end;
    }

    @Override
    public int hashCode() {
        return Objects.hash(start, end, length);
    }

    @Override
    public boolean equals(final Object obj) {
        if (obj instanceof Range) {
            final Range range = (Range) obj;
            if (range.start == this.start && range.end == this.end) {
                return true;
            }
        }
        return false;
    }

    @Override
    public int compareTo(final Range o) {
        return Long.compare(this.getStart(), o.getStart());
    }

    @Override
    public String toString() {
        return "Range{" +
                "start=" + start +
                ", end=" + end +
                ", length=" + length +
                '}';
    }
}


text:
import pytest

from mock import patch, Mock

from plaid import Client, require_access_token

def test_require_access_token_decorator():
    class TestClass(object):
        access_token = 'foo'
        @require_access_token
        def some_func(self):
            return True

    obj = TestClass()
    obj.some_func()

def test_require_access_token_decorator_raises():
    class TestClass(object):
        access_token = None
        @require_access_token
        def some_func(self):
            return True

    obj = TestClass()
    with pytest.raises(Exception):
        obj.some_func()

def test_connect():
    with patch('requests.post') as mock_requests_post:
        mock_response = Mock()
        mock_response.content = '{}'
        mock_requests_post.return_value = mock_response

        client = Client('myclientid', 'mysecret')

        account_type = 'bofa'
        username = 'foo'
        password = 'bar'
        email = 'foo@bar.com'

        response = client.connect(account_type, username, password, email)

        assert mock_response == response

def test_step():
    with patch('requests.post') as mock_requests_post:
        client = Client('myclientid', 'mysecret', 'token')
        client.step('bofa', 'foo')
        assert mock_requests_post.called

def test_step_requires_access_token():
    client = Client('myclientid', 'mysecret')
    with pytest.raises(Exception):
        client.step('bofa', 'foo')

def test_delete_user():
    with patch('requests.delete') as mock_requests_delete:
        client = Client('myclientid', 'mysecret', 'token')
        client.delete_user()
        assert mock_requests_delete.called

def test_delete_user_requires_access_token():
    client = Client('myclientid', 'mysecret')
    with pytest.raises(Exception):
        client.delete_user('bofa', 'foo')

def test_transactions():
    with patch('requests.get') as mock_requests_get:
        client = Client('myclientid', 'mysecret', 'token')
        ret = client.transactions()
        assert mock_requests_get.called
        assert ret is not None

def test_transactions_requires_access_token():
    client = Client('myclientid', 'mysecret')
    with pytest.raises(Exception):
        client.transactions()

def test_balance():
    with patch('requests.get') as mock_requests_get:
        client = Client('myclientid', 'mysecret', 'token')
        ret = client.balance()
        assert mock_requests_get.called
        assert ret is not None

def test_balance_requires_access_token():
    client = Client('myclientid', 'mysecret')
    with pytest.raises(Exception):
        client.balance()

def test_entity():
    with patch('requests.get') as mock_requests_get:
        client = Client('myclientid', 'mysecret')
        client.entity(1)
        assert mock_requests_get.called

def test_categories():
    with patch('requests.get') as mock_requests_get:
        client = Client('myclientid', 'mysecret')
        client.categories()
        assert mock_requests_get.called

def test_category():
    with patch('requests.get') as mock_requests_get:
        client = Client('myclientid', 'mysecret')
        client.category(1)
        assert mock_requests_get.called

def test_categories_by_mapping():
    with patch('requests.get') as mock_requests_get:
        client = Client('myclientid', 'mysecret')
        client.categories_by_mapping('Food > Spanish Restaurant', 'plaid')
        assert mock_requests_get.called


text:
'''OpenGL extension SGIX.sprite

This module customises the behaviour of the
OpenGL.raw.GL.SGIX.sprite to provide a more
Python-friendly API

Overview (from the spec)

	    This extension provides support for viewpoint dependent alignment
	    of geometry, in particular geometry that rotates about a point or
	    a specified axis to face the eye point.  The primary use is for
	    quickly rendering roughly cylindrically or spherically symmetric
	    objects, e.g. trees, smoke, clouds, etc. using geometry textured
	    with a partially transparent texture map.

	    Rendering sprite geometry requires applying a transformation to
	    primitives before the current model view. This matrix includes a
	    rotation which is computed based on the current model view matrix
	    and a translation which is specified explicitly
	    (SPRITE_TRANSLATION_SGIX). The current model view matrix itself
	    is not modified.

	    Primitives are first transformed by a rotation, depending on the
	    sprite mode:

		SPRITE_AXIAL_SGIX: The front of the object is rotated about
		an axis so that it faces the eye as much as the axis
		constraint allows.  This is used for roughly rendering cylindrical
		objects such as trees in visual simulation.

		SPRITE_OBJECT_ALIGNED_SGIX: The front of the object is
		rotated about a point to face the eye with the remaining
		rotational degree of freedom specified by aligning the top
		of the object with a specified axis in object coordinates.
		This is used for spherical objects and special effects such
		as smoke which must maintain an alignment in object
		coordinates for realism.

		SPRITE_EYE_ALIGNED_SGIX: The front of the object is rotated
		about a point to face the eye with the remaining rotational
		degree of freedom specified by aligning the top of the object
		with a specified axis in eye coordinates. This is used for
		rendering sprites which must maintain an alignment on the
		screen, such as 3D annotations.

	    The axis of rotation or alignment, SPRITE_AXIS_SGIX, can be
	    an arbitrary direction to support geocentric coordinate frames
	    in which "up" is not along X, Y or Z.

	    Sprite geometry is modeled in a canonical frame: +Z is the up
	    vector. -Y is the front vector which is rotated to point towards
	    the eye. In the discussion below, the eye vector is the vector to
	    the eye from the origin of the model view frame translated by the
	    sprite position.

The official definition of this extension is available here:
http://www.opengl.org/registry/specs/SGIX/sprite.txt
'''
from OpenGL import platform, constant, arrays
from OpenGL import extensions, wrapper
import ctypes
from OpenGL.raw.GL import _types, _glgets
from OpenGL.raw.GL.SGIX.sprite import *
from OpenGL.raw.GL.SGIX.sprite import _EXTENSION_NAME

def glInitSpriteSGIX():
    '''Return boolean indicating whether this extension is available'''
    from OpenGL import extensions
    return extensions.hasGLExtension( _EXTENSION_NAME )

# INPUT glSpriteParameterfvSGIX.params size not checked against 'pname'
glSpriteParameterfvSGIX=wrapper.wrapper(glSpriteParameterfvSGIX).setInputArraySize(
    'params', None
)
# INPUT glSpriteParameterivSGIX.params size not checked against 'pname'
glSpriteParameterivSGIX=wrapper.wrapper(glSpriteParameterivSGIX).setInputArraySize(
    'params', None
)
### END AUTOGENERATED SECTION


text:
<component name="ProjectDictionaryState">
  <dictionary name="mageia" />
</component>


text:
using System;
using Rhino.DistributedHashTable.Commands;

namespace Rhino.DistributedHashTable.Internal
{
	public interface IExecuter : IDisposable
	{
		void RegisterForExecution(ICommand command);
	}
}


text:
namespace Ui{
	class page_beadm_ui; //this is the name of the main widget/object in the QtDesigner form
};

class beadm_page : public PageWidget{
	Q_OBJECT
public:
	beadm_page(QWidget *parent, sysadm_client *core);
	~beadm_page();

	//Initialize the CORE <-->Page connections
	void setupCore();
	//Page embedded, go ahead and startup any core requests
	void startPage();

	QString pageID(){ return "sysadm/beadm"; } //ID is used to identify which type of page this is
	void ParseReply(QString, QString, QString, QJsonValue);

private:
	Ui::page_beadm_ui *ui;
	void startingRequest(QString notice);

private slots:

	//GUI enable/disable based on selection
	void updateButtons();

	//GUI Buttons
	void create_be();
	void clone_be(bool invalidname = false);
	void delete_be();
	void rename_be();
	void mount_be();
	void unmount_be();
	void activate_be();

	void updateList();

};
#endif


text:
<?php
use Vks\Core\RenderEngine;
use Vks\Core\ST;

ST::deployTemplate('heads/ui_timepicker.inc');
RenderEngine::MenuChanger();?>

Что-то пошло не так

        503

Произошла ошибка

Мы всё знаем, и уже пытаемся починить

        <?php if(isset($error_text)): ?>

Текст ошибки: <?= $error_text ?>

        <?php endif ?>

<a href="<?= ST::route('Index/index') ?>" class="btn btn-warning">Вернуться на главную


text:
{{ site.data.language.new_blog_entries }}

	{% include list-posts entries='7' offset='0' %}


text:
<!DOCTYPE html>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="generator" content="rustdoc">
    <meta name="description" content="API documentation for the Rust `from_utf8` fn in crate `collections`.">
    <meta name="keywords" content="rust, rustlang, rust-lang, from_utf8">

    <title>collections::str::from_utf8 - Rust</title>

    <link rel="stylesheet" type="text/css" href="../../main.css">

    <link rel="shortcut icon" href="http://www.rust-lang.org/favicon.ico">

collections::<wbr>str

        <form class="search-form js-only">

                <input class="search-input" name="search"
                       autocomplete="off"
                       placeholder="Click or press 'S' to search, '?' for more options..."
                       type="search">

        </form>

Function collections::<wbr>str::<wbr>from_utf8<wbr>Stable
            [-] [+]
        [src]

pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error>

Converts a slice of bytes to a string slice without performing any
allocations.

Once the slice has been validated as utf-8, it is transmuted in-place and
returned as a '&str' instead of a '&[u8]'

Failure

Returns Err if the slice is not utf-8 with a description as to why the
provided slice is not utf-8.

Keyboard shortcuts

?

Show this help dialog

S

Focus the search field

⇤

Move up in search results

⇥

Move down in search results

⏎

Go to active search result

Search tricks

                Prefix searches with a type followed by a colon (e.g.
                fn:) to restrict the search to a given type.

                Accepted types are: fn, mod,
                struct, enum,
                trait, typedef (or
                tdef).