Skip to content

Instantly share code, notes, and snippets.

@rcook
Created July 7, 2014 16:03
Show Gist options
  • Save rcook/af506f203a784eb761e0 to your computer and use it in GitHub Desktop.
Save rcook/af506f203a784eb761e0 to your computer and use it in GitHub Desktop.
C++ builder/named argument pattern with unique_ptr
#include <iostream>
#include <memory>
#include <vector>
// Backported from C++14
template<typename T, typename ...Args>
std::unique_ptr<T> make_unique(Args &&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
using namespace std;
class Widget
{
Widget(Widget const &) = delete;
Widget(Widget &&) = delete;
Widget &operator=(Widget const &) = delete;
Widget &operator=(Widget &&) = delete;
public:
Widget(string const &name) :
m_name(name)
{ }
~Widget()
{ };
string const &name() const
{ return m_name; }
private:
string const m_name;
};
class WidgetBuilder
{
WidgetBuilder(WidgetBuilder const &) = delete;
WidgetBuilder(WidgetBuilder &&) = delete;
WidgetBuilder &operator=(WidgetBuilder const &) = delete;
WidgetBuilder &operator=(WidgetBuilder &&) = delete;
public:
WidgetBuilder()
{ }
~WidgetBuilder()
{ };
WidgetBuilder &name(string const &name)
{ m_name = name; return *this; }
unique_ptr<Widget> create()
{ return make_unique<Widget>(m_name); }
private:
string m_name;
};
class WidgetContainer
{
WidgetContainer(WidgetContainer const &) = delete;
WidgetContainer(WidgetContainer &&) = delete;
WidgetContainer &operator=(WidgetContainer const &) = delete;
WidgetContainer &operator=(WidgetContainer &&) = delete;
public:
WidgetContainer(
string const &firstName,
string const &lastName,
unique_ptr<vector<unique_ptr<Widget>>> widgets) :
m_firstName(firstName),
m_lastName(lastName),
m_widgets(move(widgets))
{ }
~WidgetContainer()
{ };
string const &firstName() const
{ return m_firstName; }
string const &lastName() const
{ return m_lastName; }
vector<unique_ptr<Widget>> const &widgets() const
{ return *m_widgets; }
private:
string const m_firstName;
string const m_lastName;
unique_ptr<vector<unique_ptr<Widget>>> m_widgets;
};
class WidgetContainerBuilder
{
WidgetContainerBuilder(WidgetContainerBuilder const &) = delete;
WidgetContainerBuilder(WidgetContainerBuilder &&) = delete;
WidgetContainerBuilder &operator=(WidgetContainerBuilder const &) = delete;
WidgetContainerBuilder &operator=(WidgetContainerBuilder &&) = delete;
public:
WidgetContainerBuilder()
{ }
~WidgetContainerBuilder()
{ };
WidgetContainerBuilder &firstName(string const &firstName)
{ m_firstName = firstName; return *this; }
WidgetContainerBuilder &lastName(string const &lastName)
{ m_lastName = lastName; return *this; }
WidgetContainerBuilder &addWidget(WidgetBuilder &widgetBuilder)
{
m_widgetBuilders.push_back(&widgetBuilder);
return *this;
}
unique_ptr<WidgetContainer> create()
{
unique_ptr<vector<unique_ptr<Widget>>> widgets =
make_unique<vector<unique_ptr<Widget>>>();
for (auto &widgetBuilder : m_widgetBuilders)
{
widgets->push_back(widgetBuilder->create());
}
return make_unique<WidgetContainer>(
m_firstName,
m_lastName,
move(widgets));
}
private:
string m_firstName;
string m_lastName;
vector<WidgetBuilder *> m_widgetBuilders;
};
int main(int argc, char *argv[])
{
unique_ptr<WidgetContainer> x(
WidgetContainerBuilder()
.firstName("my-first-name")
.lastName("my-last-name")
.addWidget(
WidgetBuilder()
.name("my-widget-0"))
.addWidget(
WidgetBuilder()
.name("my-widget-1"))
.create());
cout << x->firstName() << " " << x->lastName() << endl;
for (auto &widget : x->widgets())
{
cout << widget->name() << endl;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment