A useful report rarely arrives all at once. Its title is known up front, while the subtitle, sections, charts, and footer are added as the document takes shape. A builder lets that draft grow naturally without forcing callers through one oversized constructor.
Your task is to implement only the ReportBuilder class. ReportSection, the finished ReportDoc, and the ReportComposer test harness are already implemented.
The builder must provide this behavior (method names follow each language's starter code):
ReportBuilder(title) stores the title and starts with an empty subtitle, footer, section list, and chart list.setSubtitle(text) and setFooter(text) replace their current values.addSection(heading, content) creates a ReportSection and appends it to the section list.addChart(name) appends the chart name. Sections and charts both keep insertion order.sectionCount() returns the current number of sections.- Every configuration method returns the same builder instance.
build() returns no product (null, None, or nil) when the draft has no sections. In C++, where ReportDoc is returned by value, canBuild() performs this readiness check before build() is called. A valid build returns a new ReportDoc containing the current state, and a refused build must not change the builder.
The provided composer validates the title, owns the active builder, handles discard(), translates a missing product into "Error: Report must have at least one section", and stores successful builds. Those orchestration rules are already implemented for you.
A report renders like this:
Report{title='Q3 Review', subtitle='July - September', sections=[1. Summary: Revenue held steady. | 2. Risks: Two vendors are late.], charts=[spend-by-team], footer='Internal'}
Sections are numbered from one in the order they were added, and each renders as <number>. <heading>: <content>, joined by | . Charts render in insertion order. An unset subtitle and an unset footer render as empty text, and a report with no charts renders charts=[].
A build leaves the builder in place, whether it succeeds or is refused. The same draft can therefore gain another section and produce a second, longer report. The provided ReportDoc copies both lists, so the earlier report remains unchanged.
The examples use ReportComposer because it is the public test harness. Your implementation belongs only inside ReportBuilder.
Example 1:
Input:
Output:
Explanation: Three sections render in the order they were added, numbered one to three, with the two charts and the footer following. Nothing here is sorted.
Example 2:
Input:
Output:
Explanation: A report with no sections is refused and nothing is counted, but the draft survives, so adding one section and building again succeeds.
Constraints
0 <= title.length <= 601 <= heading.length, content.length <= 600 <= index <= 100- At most
9 sections and 9 charts are added to one draft. - At most
100 calls in total are made across all methods.
Starter Code
Only the ReportBuilder type is unfinished. No builder template is supplied: define all of its fields, its constructor, and its methods yourself. Every other type is already implemented; do not rewrite it.