// problem 2.1-1 const bool Problem2p1p1() { std::cout << "problem 2.1-1 (page 22):\n"; int v[] = { 31, 41, 59, 26, 41, 58 }; std::cout << "before sorted = " << ArrayString(v) << "\n"; r1::insert_sort_int(v, std::less<int>()); assert(r1::is_sorted(v, std::less<int>())); std::cout << "after sorted = " << ArrayString(v) << "\n" << std::endl; return true; }
// problem 2.1-2 const bool Problem2p1p2() { std::cout << "problem 2.1-2 (page 22):\n"; int v[] = { 5, 2, 4, 6, 1, 3 }; std::cout << "before sorted = " << ArrayString(v) << "\n"; r1::insert_sort_int(v, std::greater<int>()); assert(r1::is_sorted(v, std::greater<int>())); std::cout << "after sorted = " << ArrayString(v) << "\n" << std::endl; return true; }
void UniformHLSL::outputHLSL4_0_FL9_3Sampler(TInfoSinkBase &out, const TType &type, const TName &name, const unsigned int registerIndex) { out << "uniform " << SamplerString(type.getBasicType()) << " sampler_" << DecorateUniform(name, type) << ArrayString(type) << " : register(s" << str(registerIndex) << ");\n"; out << "uniform " << TextureString(type.getBasicType()) << " texture_" << DecorateUniform(name, type) << ArrayString(type) << " : register(t" << str(registerIndex) << ");\n"; }
TString UniformHLSL::interfaceBlockMembersString(const TInterfaceBlock &interfaceBlock, TLayoutBlockStorage blockStorage) { TString hlsl; Std140PaddingHelper padHelper = mStructureHLSL->getPaddingHelper(); for (unsigned int typeIndex = 0; typeIndex < interfaceBlock.fields().size(); typeIndex++) { const TField &field = *interfaceBlock.fields()[typeIndex]; const TType &fieldType = *field.type(); if (blockStorage == EbsStd140) { // 2 and 3 component vector types in some cases need pre-padding hlsl += padHelper.prePaddingString(fieldType); } hlsl += " " + InterfaceBlockFieldTypeString(field, blockStorage) + " " + Decorate(field.name()) + ArrayString(fieldType) + ";\n"; // must pad out after matrices and arrays, where HLSL usually allows itself room to pack stuff if (blockStorage == EbsStd140) { const bool useHLSLRowMajorPacking = (fieldType.getLayoutQualifier().matrixPacking == EmpColumnMajor); hlsl += padHelper.postPaddingString(fieldType, useHLSLRowMajorPacking); } } return hlsl; }
TString UniformHLSL::uniformsHeader(ShShaderOutput outputType, const ReferencedSymbols &referencedUniforms) { TString uniforms; for (ReferencedSymbols::const_iterator uniformIt = referencedUniforms.begin(); uniformIt != referencedUniforms.end(); uniformIt++) { const TIntermSymbol &uniform = *uniformIt->second; const TType &type = uniform.getType(); const TString &name = uniform.getSymbol(); int registerIndex = declareUniformAndAssignRegister(type, name); if (outputType == SH_HLSL11_OUTPUT && IsSampler(type.getBasicType())) // Also declare the texture { uniforms += "uniform " + SamplerString(type) + " sampler_" + DecorateUniform(name, type) + ArrayString(type) + " : register(s" + str(registerIndex) + ");\n"; uniforms += "uniform " + TextureString(type) + " texture_" + DecorateUniform(name, type) + ArrayString(type) + " : register(t" + str(registerIndex) + ");\n"; } else { const TStructure *structure = type.getStruct(); const TString &typeName = (structure ? QualifiedStructNameString(*structure, false, false) : TypeString(type)); const TString ®isterString = TString("register(") + UniformRegisterPrefix(type) + str(registerIndex) + ")"; uniforms += "uniform " + typeName + " " + DecorateUniform(name, type) + ArrayString(type) + " : " + registerString + ";\n"; } } return (uniforms.empty() ? "" : ("// Uniforms\n\n" + uniforms)); }
void UniformHLSL::outputHLSLSamplerUniformGroup(TInfoSinkBase &out, const HLSLTextureSamplerGroup textureGroup, const TVector<const TIntermSymbol *> &group, unsigned int *groupTextureRegisterIndex) { if (group.empty()) { return; } unsigned int groupRegisterCount = 0; for (const TIntermSymbol *uniform : group) { const TType &type = uniform->getType(); const TString &name = uniform->getSymbol(); unsigned int registerCount; unsigned int samplerArrayIndex = declareUniformAndAssignRegister(type, name, ®isterCount); groupRegisterCount += registerCount; if (type.isArray()) { out << "static const uint " << DecorateIfNeeded(uniform->getName()) << ArrayString(type) << " = {"; for (int i = 0; i < type.getArraySize(); ++i) { if (i > 0) out << ", "; out << (samplerArrayIndex + i); } out << "};\n"; } else { out << "static const uint " << DecorateIfNeeded(uniform->getName()) << " = " << samplerArrayIndex << ";\n"; } } TString suffix = TextureGroupSuffix(textureGroup); // Since HLSL_TEXTURE_2D is the first group, it has a fixed offset of zero. if (textureGroup != HLSL_TEXTURE_2D) { out << "static const uint textureIndexOffset" << suffix << " = " << (*groupTextureRegisterIndex) << ";\n"; out << "static const uint samplerIndexOffset" << suffix << " = " << (*groupTextureRegisterIndex) << ";\n"; } out << "uniform " << TextureString(textureGroup) << " textures" << suffix << "[" << groupRegisterCount << "]" << " : register(t" << (*groupTextureRegisterIndex) << ");\n"; out << "uniform " << SamplerString(textureGroup) << " samplers" << suffix << "[" << groupRegisterCount << "]" << " : register(s" << (*groupTextureRegisterIndex) << ");\n"; *groupTextureRegisterIndex += groupRegisterCount; }
void DynamicHLSL::getPixelShaderOutputKey(const gl::Data &data, const gl::Program::Data &programData, const ProgramD3DMetadata &metadata, std::vector<PixelShaderOutputVariable> *outPixelShaderKey) { // Two cases when writing to gl_FragColor and using ESSL 1.0: // - with a 3.0 context, the output color is copied to channel 0 // - with a 2.0 context, the output color is broadcast to all channels bool broadcast = metadata.usesBroadcast(data); const unsigned int numRenderTargets = (broadcast || metadata.usesMultipleFragmentOuts() ? data.caps->maxDrawBuffers : 1); if (metadata.getMajorShaderVersion() < 300) { for (unsigned int renderTargetIndex = 0; renderTargetIndex < numRenderTargets; renderTargetIndex++) { PixelShaderOutputVariable outputKeyVariable; outputKeyVariable.type = GL_FLOAT_VEC4; outputKeyVariable.name = "gl_Color" + Str(renderTargetIndex); outputKeyVariable.source = broadcast ? "gl_Color[0]" : "gl_Color[" + Str(renderTargetIndex) + "]"; outputKeyVariable.outputIndex = renderTargetIndex; outPixelShaderKey->push_back(outputKeyVariable); } } else { const auto &shaderOutputVars = metadata.getFragmentShader()->getData().getActiveOutputVariables(); for (auto outputPair : programData.getOutputVariables()) { const VariableLocation &outputLocation = outputPair.second; const sh::ShaderVariable &outputVariable = shaderOutputVars[outputLocation.index]; const std::string &variableName = "out_" + outputLocation.name; const std::string &elementString = (outputLocation.element == GL_INVALID_INDEX ? "" : Str(outputLocation.element)); ASSERT(outputVariable.staticUse); PixelShaderOutputVariable outputKeyVariable; outputKeyVariable.type = outputVariable.type; outputKeyVariable.name = variableName + elementString; outputKeyVariable.source = variableName + ArrayString(outputLocation.element); outputKeyVariable.outputIndex = outputPair.first; outPixelShaderKey->push_back(outputKeyVariable); } } }
TString UniformHLSL::uniformsHeader(ShShaderOutput outputType, const ReferencedSymbols &referencedUniforms) { TString uniforms; for (ReferencedSymbols::const_iterator uniformIt = referencedUniforms.begin(); uniformIt != referencedUniforms.end(); uniformIt++) { const TIntermSymbol &uniform = *uniformIt->second; const TType &type = uniform.getType(); const TString &name = uniform.getSymbol(); unsigned int registerIndex = declareUniformAndAssignRegister(type, name); if (outputType == SH_HLSL11_OUTPUT && IsSampler(type.getBasicType())) // Also declare the texture { uniforms += "uniform " + SamplerString(type) + " sampler_" + DecorateUniform(name, type) + ArrayString(type) + " : register(s" + str(registerIndex) + ");\n"; uniforms += "uniform " + TextureString(type) + " texture_" + DecorateUniform(name, type) + ArrayString(type) + " : register(t" + str(registerIndex) + ");\n"; } else { const TStructure *structure = type.getStruct(); // If this is a nameless struct, we need to use its full definition, rather than its (empty) name. // TypeString() will invoke defineNameless in this case; qualifier prefixes are unnecessary for // nameless structs in ES, as nameless structs cannot be used anywhere that layout qualifiers are // permitted. const TString &typeName = ((structure && !structure->name().empty()) ? QualifiedStructNameString(*structure, false, false) : TypeString(type)); const TString ®isterString = TString("register(") + UniformRegisterPrefix(type) + str(registerIndex) + ")"; uniforms += "uniform " + typeName + " " + DecorateUniform(name, type) + ArrayString(type) + " : " + registerString + ";\n"; } } return (uniforms.empty() ? "" : ("// Uniforms\n\n" + uniforms)); }
void UniformHLSL::outputUniform(TInfoSinkBase &out, const TType &type, const TName &name, const unsigned int registerIndex) { const TStructure *structure = type.getStruct(); // If this is a nameless struct, we need to use its full definition, rather than its (empty) // name. // TypeString() will invoke defineNameless in this case; qualifier prefixes are unnecessary for // nameless structs in ES, as nameless structs cannot be used anywhere that layout qualifiers // are permitted. const TString &typeName = ((structure && !structure->name().empty()) ? QualifiedStructNameString(*structure, false, false) : TypeString(type)); const TString ®isterString = TString("register(") + UniformRegisterPrefix(type) + str(registerIndex) + ")"; out << "uniform " << typeName << " "; out << DecorateUniform(name, type); out << ArrayString(type) << " : " << registerString << ";\n"; }
void UniformHLSL::outputHLSLSamplerUniformGroup( TInfoSinkBase &out, const HLSLTextureSamplerGroup textureGroup, const TVector<const TIntermSymbol *> &group, const TMap<const TIntermSymbol *, TString> &samplerInStructSymbolsToAPINames, unsigned int *groupTextureRegisterIndex) { if (group.empty()) { return; } unsigned int groupRegisterCount = 0; for (const TIntermSymbol *uniform : group) { const TType &type = uniform->getType(); const TString &name = uniform->getSymbol(); unsigned int registerCount; // The uniform might be just a regular sampler or one extracted from a struct. unsigned int samplerArrayIndex = 0u; const Uniform *uniformByName = findUniformByName(name); if (uniformByName) { samplerArrayIndex = assignUniformRegister(type, name, ®isterCount); } else { ASSERT(samplerInStructSymbolsToAPINames.find(uniform) != samplerInStructSymbolsToAPINames.end()); samplerArrayIndex = assignSamplerInStructUniformRegister( type, samplerInStructSymbolsToAPINames.at(uniform), ®isterCount); } groupRegisterCount += registerCount; if (type.isArray()) { out << "static const uint " << DecorateIfNeeded(uniform->getName()) << ArrayString(type) << " = {"; for (unsigned int i = 0u; i < type.getArraySize(); ++i) { if (i > 0u) out << ", "; out << (samplerArrayIndex + i); } out << "};\n"; } else { out << "static const uint " << DecorateIfNeeded(uniform->getName()) << " = " << samplerArrayIndex << ";\n"; } } TString suffix = TextureGroupSuffix(textureGroup); // Since HLSL_TEXTURE_2D is the first group, it has a fixed offset of zero. if (textureGroup != HLSL_TEXTURE_2D) { out << "static const uint textureIndexOffset" << suffix << " = " << (*groupTextureRegisterIndex) << ";\n"; out << "static const uint samplerIndexOffset" << suffix << " = " << (*groupTextureRegisterIndex) << ";\n"; } out << "uniform " << TextureString(textureGroup) << " textures" << suffix << "[" << groupRegisterCount << "]" << " : register(t" << (*groupTextureRegisterIndex) << ");\n"; out << "uniform " << SamplerString(textureGroup) << " samplers" << suffix << "[" << groupRegisterCount << "]" << " : register(s" << (*groupTextureRegisterIndex) << ");\n"; *groupTextureRegisterIndex += groupRegisterCount; }
void UniformHLSL::uniformsHeader(TInfoSinkBase &out, ShShaderOutput outputType, const ReferencedSymbols &referencedUniforms) { if (!referencedUniforms.empty()) { out << "// Uniforms\n\n"; } // In the case of HLSL 4, sampler uniforms need to be grouped by type before the code is // written. They are grouped based on the combination of the HLSL texture type and // HLSL sampler type, enumerated in HLSLTextureSamplerGroup. TVector<TVector<const TIntermSymbol *>> groupedSamplerUniforms; groupedSamplerUniforms.resize(HLSL_TEXTURE_MAX + 1); for (auto &uniformIt : referencedUniforms) { // Output regular uniforms. Group sampler uniforms by type. const TIntermSymbol &uniform = *uniformIt.second; const TType &type = uniform.getType(); const TString &name = uniform.getSymbol(); if (outputType == SH_HLSL_4_1_OUTPUT && IsSampler(type.getBasicType())) { HLSLTextureSamplerGroup group = TextureGroup(type.getBasicType()); groupedSamplerUniforms[group].push_back(&uniform); } else if (outputType == SH_HLSL_4_0_FL9_3_OUTPUT && IsSampler(type.getBasicType())) { unsigned int registerIndex = declareUniformAndAssignRegister(type, name); out << "uniform " << SamplerString(type.getBasicType()) << " sampler_" << DecorateUniform(name, type) << ArrayString(type) << " : register(s" << str(registerIndex) << ");\n"; out << "uniform " << TextureString(type.getBasicType()) << " texture_" << DecorateUniform(name, type) << ArrayString(type) << " : register(t" << str(registerIndex) << ");\n"; } else { unsigned int registerIndex = declareUniformAndAssignRegister(type, name); const TStructure *structure = type.getStruct(); // If this is a nameless struct, we need to use its full definition, rather than its (empty) name. // TypeString() will invoke defineNameless in this case; qualifier prefixes are unnecessary for // nameless structs in ES, as nameless structs cannot be used anywhere that layout qualifiers are // permitted. const TString &typeName = ((structure && !structure->name().empty()) ? QualifiedStructNameString(*structure, false, false) : TypeString(type)); const TString ®isterString = TString("register(") + UniformRegisterPrefix(type) + str(registerIndex) + ")"; out << "uniform " << typeName << " " << DecorateUniform(name, type) << ArrayString(type) << " : " << registerString << ";\n"; } } if (outputType == SH_HLSL_4_1_OUTPUT) { unsigned int groupTextureRegisterIndex = 0; // TEXTURE_2D is special, index offset is assumed to be 0 and omitted in that case. ASSERT(HLSL_TEXTURE_MIN == HLSL_TEXTURE_2D); for (int groupId = HLSL_TEXTURE_MIN; groupId < HLSL_TEXTURE_MAX; ++groupId) { outputHLSLSamplerUniformGroup(out, HLSLTextureSamplerGroup(groupId), groupedSamplerUniforms[groupId], &groupTextureRegisterIndex); } } }
gl::Error ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext) { ContextVk *contextVk = vk::GetImpl(glContext); VkDevice device = contextVk->getDevice(); // Process vertex and fragment uniforms into std140 packing. std::array<sh::BlockLayoutMap, 2> layoutMap; std::array<size_t, 2> requiredBufferSize = {{0, 0}}; for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex) { ANGLE_TRY(InitDefaultUniformBlock(glContext, device, GetShader(mState, shaderIndex), &mDefaultUniformBlocks[shaderIndex].storage, &layoutMap[shaderIndex], &requiredBufferSize[shaderIndex])); } // Init the default block layout info. const auto &locations = mState.getUniformLocations(); const auto &uniforms = mState.getUniforms(); for (size_t locationIndex = 0; locationIndex < locations.size(); ++locationIndex) { std::array<sh::BlockMemberInfo, 2> layoutInfo; const auto &location = locations[locationIndex]; if (location.used() && !location.ignored) { const auto &uniform = uniforms[location.index]; if (uniform.isSampler()) continue; std::string uniformName = uniform.name; if (uniform.isArray()) { uniformName += ArrayString(location.arrayIndex); } bool found = false; for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex) { auto it = layoutMap[shaderIndex].find(uniformName); if (it != layoutMap[shaderIndex].end()) { found = true; layoutInfo[shaderIndex] = it->second; } } ASSERT(found); } for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex) { mDefaultUniformBlocks[shaderIndex].uniformLayout.push_back(layoutInfo[shaderIndex]); } } bool anyDirty = false; bool allDirty = true; for (uint32_t shaderIndex = MinShaderIndex; shaderIndex < MaxShaderIndex; ++shaderIndex) { if (requiredBufferSize[shaderIndex] > 0) { if (!mDefaultUniformBlocks[shaderIndex].uniformData.resize( requiredBufferSize[shaderIndex])) { return gl::OutOfMemory() << "Memory allocation failure."; } mDefaultUniformBlocks[shaderIndex].uniformData.fill(0); mDefaultUniformBlocks[shaderIndex].uniformsDirty = true; anyDirty = true; } else { allDirty = false; } } if (anyDirty) { // Initialize the "empty" uniform block if necessary. if (!allDirty) { VkBufferCreateInfo uniformBufferInfo; uniformBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; uniformBufferInfo.pNext = nullptr; uniformBufferInfo.flags = 0; uniformBufferInfo.size = 1; uniformBufferInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; uniformBufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; uniformBufferInfo.queueFamilyIndexCount = 0; uniformBufferInfo.pQueueFamilyIndices = nullptr; ANGLE_TRY(mEmptyUniformBlockStorage.buffer.init(device, uniformBufferInfo)); size_t requiredSize = 0; ANGLE_TRY(AllocateBufferMemory(contextVk, 1, &mEmptyUniformBlockStorage.buffer, &mEmptyUniformBlockStorage.memory, &requiredSize)); } ANGLE_TRY(updateDefaultUniformsDescriptorSet(contextVk)); } else { // If the program has no uniforms, note this in the offset. mDescriptorSetOffset = 1; } return gl::NoError(); }
void StructureHLSL::addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters) { if (name == "") { return; // Nameless structures don't have constructors } if (type.getStruct() && mStructNames.find(name) != mStructNames.end()) { return; // Already added } TType ctorType = type; ctorType.clearArrayness(); ctorType.setPrecision(EbpHigh); ctorType.setQualifier(EvqTemporary); typedef std::vector<TType> ParameterArray; ParameterArray ctorParameters; const TStructure* structure = type.getStruct(); if (structure) { mStructNames.insert(name); // Add element index storeStd140ElementIndex(*structure, false); storeStd140ElementIndex(*structure, true); const TString &structString = defineQualified(*structure, false, false); if (std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structString) == mStructDeclarations.end()) { // Add row-major packed struct for interface blocks TString rowMajorString = "#pragma pack_matrix(row_major)\n" + defineQualified(*structure, true, false) + "#pragma pack_matrix(column_major)\n"; TString std140String = defineQualified(*structure, false, true); TString std140RowMajorString = "#pragma pack_matrix(row_major)\n" + defineQualified(*structure, true, true) + "#pragma pack_matrix(column_major)\n"; mStructDeclarations.push_back(structString); mStructDeclarations.push_back(rowMajorString); mStructDeclarations.push_back(std140String); mStructDeclarations.push_back(std140RowMajorString); } const TFieldList &fields = structure->fields(); for (unsigned int i = 0; i < fields.size(); i++) { ctorParameters.push_back(*fields[i]->type()); } } else if (parameters) { for (TIntermSequence::const_iterator parameter = parameters->begin(); parameter != parameters->end(); parameter++) { ctorParameters.push_back((*parameter)->getAsTyped()->getType()); } } else UNREACHABLE(); TString constructor; if (ctorType.getStruct()) { constructor += name + " " + name + "_ctor("; } else // Built-in type { constructor += TypeString(ctorType) + " " + name + "("; } for (unsigned int parameter = 0; parameter < ctorParameters.size(); parameter++) { const TType ¶mType = ctorParameters[parameter]; constructor += TypeString(paramType) + " x" + str(parameter) + ArrayString(paramType); if (parameter < ctorParameters.size() - 1) { constructor += ", "; } } constructor += ")\n" "{\n"; if (ctorType.getStruct()) { constructor += " " + name + " structure = {"; } else { constructor += " return " + TypeString(ctorType) + "("; } if (ctorType.isMatrix() && ctorParameters.size() == 1) { int rows = ctorType.getRows(); int cols = ctorType.getCols(); const TType ¶meter = ctorParameters[0]; if (parameter.isScalar()) { for (int col = 0; col < cols; col++) { for (int row = 0; row < rows; row++) { constructor += TString((row == col) ? "x0" : "0.0"); if (row < rows - 1 || col < cols - 1) { constructor += ", "; } } } } else if (parameter.isMatrix()) { for (int col = 0; col < cols; col++) { for (int row = 0; row < rows; row++) { if (row < parameter.getRows() && col < parameter.getCols()) { constructor += TString("x0") + "[" + str(col) + "][" + str(row) + "]"; } else { constructor += TString((row == col) ? "1.0" : "0.0"); } if (row < rows - 1 || col < cols - 1) { constructor += ", "; } } } } else { ASSERT(rows == 2 && cols == 2 && parameter.isVector() && parameter.getNominalSize() == 4); constructor += "x0"; } } else { size_t remainingComponents = ctorType.getObjectSize(); size_t parameterIndex = 0; while (remainingComponents > 0) { const TType ¶meter = ctorParameters[parameterIndex]; const size_t parameterSize = parameter.getObjectSize(); bool moreParameters = parameterIndex + 1 < ctorParameters.size(); constructor += "x" + str(parameterIndex); if (ctorType.getStruct()) { ASSERT(remainingComponents == parameterSize || moreParameters); ASSERT(parameterSize <= remainingComponents); remainingComponents -= parameterSize; } else if (parameter.isScalar()) { remainingComponents -= parameter.getObjectSize(); } else if (parameter.isVector()) { if (remainingComponents == parameterSize || moreParameters) { ASSERT(parameterSize <= remainingComponents); remainingComponents -= parameterSize; } else if (remainingComponents < static_cast<size_t>(parameter.getNominalSize())) { switch (remainingComponents) { case 1: constructor += ".x"; break; case 2: constructor += ".xy"; break; case 3: constructor += ".xyz"; break; case 4: constructor += ".xyzw"; break; default: UNREACHABLE(); } remainingComponents = 0; } else UNREACHABLE(); } else if (parameter.isMatrix()) { int column = 0; while (remainingComponents > 0 && column < parameter.getCols()) { constructor += "[" + str(column) + "]"; if (remainingComponents < static_cast<size_t>(parameter.getRows())) { switch (remainingComponents) { case 1: constructor += ".x"; break; case 2: constructor += ".xy"; break; case 3: constructor += ".xyz"; break; default: UNREACHABLE(); } remainingComponents = 0; } else { remainingComponents -= parameter.getRows(); if (remainingComponents > 0) { constructor += ", x" + str(parameterIndex); } } column++; } } else UNREACHABLE(); if (moreParameters) { parameterIndex++; } if (remainingComponents) { constructor += ", "; } } } if (ctorType.getStruct()) { constructor += "};\n" " return structure;\n" "}\n"; } else { constructor += ");\n" "}\n"; } mConstructors.insert(constructor); }
TString StructureHLSL::define(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing, Std140PaddingHelper *padHelper) { const TFieldList &fields = structure.fields(); const bool isNameless = (structure.name() == ""); const TString &structName = QualifiedStructNameString(structure, useHLSLRowMajorPacking, useStd140Packing); const TString declareString = (isNameless ? "struct" : "struct " + structName); TString string; string += declareString + "\n" "{\n"; for (unsigned int i = 0; i < fields.size(); i++) { const TField &field = *fields[i]; const TType &fieldType = *field.type(); const TStructure *fieldStruct = fieldType.getStruct(); const TString &fieldTypeString = fieldStruct ? QualifiedStructNameString(*fieldStruct, useHLSLRowMajorPacking, useStd140Packing) : TypeString(fieldType); if (padHelper) { string += padHelper->prePaddingString(fieldType); } string += " " + fieldTypeString + " " + DecorateField(field.name(), structure) + ArrayString(fieldType) + ";\n"; if (padHelper) { string += padHelper->postPaddingString(fieldType, useHLSLRowMajorPacking); } } // Nameless structs do not finish with a semicolon and newline, to leave room for an instance variable string += (isNameless ? "} " : "};\n"); return string; }
// test the sort in place const bool TestInsertionSort() { // test array of size 0 std::cout << "testing zero size array:\n"; int* v0 = NULL; int const N0 = 0; std::cout << "before sorted = " << ArrayString(v0, N0) << "\n"; r1::insert_sort_int(v0, N0); assert(r1::is_sorted(v0, N0)); std::cout << "after sorted = " << ArrayString(v0, N0) << "\n" << std::endl; // test array of size 1 std::cout << "testing one size array:\n"; int v1[] = { 7 }; std::cout << "before sorted = " << ArrayString(v1) << "\n"; r1::insert_sort_int(v1); assert(r1::is_sorted(v1)); std::cout << "after sorted = " << ArrayString(v1) << "\n" << std::endl; // test unsorted array std::cout << "testing unsorted array:\n"; int const v2[] = { 4, 8, 3, 9 }; std::cout << "v2 = " << ArrayString(v2) << "\n" << std::endl; assert(!r1::is_sorted(v2)); // test example from page 20 std::cout << "test example (page 20):\n"; int v[] = { 5, 2, 4, 6, 1, 3 }; std::cout << "before sorted = " << ArrayString(v) << "\n"; r1::insert_sort_int(v); assert(r1::is_sorted(v)); std::cout << "after sorted = " << ArrayString(v) << "\n" << std::endl; // test example from page 20 using iterators std::cout << "test example (page 20) using templates:\n"; int v3[] = { 5, 2, 4, 6, 1, 3 }; const int N3 = sizeof(v3)/sizeof(v3[0]); std::cout << "before sorted = " << ArrayString(v3) << "\n"; r1::insert_sort(v3, v3+N3); assert(r1::is_sorted(v3)); std::cout << "after sorted = " << ArrayString(v3) << "\n" << std::endl; // now try it with an std::list std::cout << "test example (page 20) using tempates and std::list:\n"; int v4[] = { 5, 2, 4, 6, 1, 3 }; const int N4 = sizeof(v4) / sizeof(v4[0]); std::list<int> l1(v4, v4+N4); std::cout << "before sorted = " << ArrayString(v4) << "\n"; r1::insert_sort(l1.begin(), l1.end()); std::copy(l1.begin(), l1.end(), v4); assert(r1::is_sorted(v4)); std::cout << "after sorted = " << ArrayString(v4) << "\n" << std::endl; return true; }
std::string ArrayString(T const(&array)[N]) { return ArrayString(array, N); }