mirror of https://github.com/CppCon/CppCon2014.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
2.7 KiB
C++
134 lines
2.7 KiB
C++
#include "hairpoll.h"
|
|
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
//
|
|
// Error handling
|
|
//
|
|
|
|
struct Error {
|
|
Error()
|
|
: opaque(nullptr)
|
|
{
|
|
}
|
|
|
|
~Error()
|
|
{
|
|
if (opaque) {
|
|
error_destruct(opaque);
|
|
}
|
|
}
|
|
|
|
error_t opaque;
|
|
};
|
|
|
|
class ThrowOnError {
|
|
public:
|
|
~ThrowOnError() noexcept(false)
|
|
{
|
|
if (_error.opaque) {
|
|
throw std::runtime_error(error_message(_error.opaque));
|
|
}
|
|
}
|
|
|
|
operator error_t*() { return &_error.opaque; }
|
|
|
|
private:
|
|
Error _error;
|
|
};
|
|
|
|
//
|
|
// HairPoll related functionality
|
|
//
|
|
|
|
class HairPoll {
|
|
public:
|
|
HairPoll(std::string person)
|
|
: _opaque(hairpoll_construct(person.c_str(), ThrowOnError{}))
|
|
{
|
|
}
|
|
|
|
~HairPoll()
|
|
{
|
|
hairpoll_destruct(_opaque);
|
|
}
|
|
|
|
HairPoll(const HairPoll&) = delete;
|
|
HairPoll& operator=(const HairPoll&) = delete;
|
|
|
|
int addOption(std::string name, std::string imageUrl)
|
|
{
|
|
return hairpoll_add_option(_opaque, name.c_str(), imageUrl.c_str(), ThrowOnError{});
|
|
}
|
|
|
|
void vote(int option)
|
|
{
|
|
return hairpoll_vote(_opaque, option, ThrowOnError{});
|
|
}
|
|
|
|
struct Result {
|
|
std::string name;
|
|
int votes;
|
|
std::string html;
|
|
};
|
|
|
|
std::vector<Result> results() const
|
|
{
|
|
std::vector<Result> ret;
|
|
|
|
auto addResult = [&ret](const char* name, int32_t votes, const char* html){
|
|
ret.push_back(Result{name, votes, html});
|
|
};
|
|
|
|
auto callback = [](void* client_data, const char* name, int32_t votes, const char* html){
|
|
auto fn = static_cast<decltype(&addResult)>(client_data);
|
|
(*fn)(name, votes, html);
|
|
};
|
|
|
|
hairpoll_tally(_opaque, callback, &addResult, ThrowOnError{});
|
|
|
|
return ret;
|
|
}
|
|
|
|
private:
|
|
hairpoll_t _opaque;
|
|
};
|
|
|
|
void conductPoll()
|
|
{
|
|
HairPoll poll("Stefanus Du Toit");
|
|
|
|
int skel = poll.addOption("Skeletor", "http://static.comicvine.com/uploads/original/4/49448/2413657-skeletor.jpg");
|
|
int beast = poll.addOption("Beast Man", "https://angryjedi.files.wordpress.com/2010/10/he-man_beast_man.jpeg");
|
|
|
|
poll.vote(skel);
|
|
poll.vote(beast);
|
|
poll.vote(beast);
|
|
|
|
// Uncomment this line to exercise the error handling case.
|
|
// poll.vote(423);
|
|
|
|
std::cout << "<!DOCTYPE html>\n"
|
|
<< "<html>\n"
|
|
<< "<body>\n"
|
|
<< "<ul>\n";
|
|
for (auto&& result : poll.results()) {
|
|
std::cout << "<li>" << result.html << "</li>\n";
|
|
}
|
|
std::cout << "</ul>\n"
|
|
<< "</body>\n"
|
|
<< "</html>\n";
|
|
}
|
|
|
|
int main()
|
|
{
|
|
try {
|
|
conductPoll();
|
|
} catch (const std::exception& e) {
|
|
std::cerr << "Error during poll: " << e.what() << std::endl;
|
|
return 1;
|
|
}
|
|
}
|