...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
The following code demonstrates the syntax for using implicit conversions to and copying of any objects:
#include <list> #include <boost/any.hpp> using boost::any_cast; typedef std::list<boost::any> many; void append_int(many & values, int value) { boost::any to_append = value; values.push_back(to_append); } void append_string(many & values, const std::string & value) { values.push_back(value); } void append_char_ptr(many & values, const char * value) { values.push_back(value); } void append_any(many & values, const boost::any & value) { values.push_back(value); } void append_nothing(many & values) { values.push_back(boost::any()); }
The following predicates follow on from the previous definitions and demonstrate the use of queries on any objects:
bool is_empty(const boost::any & operand) { return operand.empty(); } bool is_int(const boost::any & operand) { return operand.type() == typeid(int); } bool is_char_ptr(const boost::any & operand) { try { any_cast<const char *>(operand); return true; } catch(const boost::bad_any_cast &) { return false; } } bool is_string(const boost::any & operand) { return any_cast<std::string>(&operand); } void count_all(many & values, std::ostream & out) { out << "#empty == " << std::count_if(values.begin(), values.end(), is_empty) << std::endl; out << "#int == " << std::count_if(values.begin(), values.end(), is_int) << std::endl; out << "#const char * == " << std::count_if(values.begin(), values.end(), is_char_ptr) << std::endl; out << "#string == " << std::count_if(values.begin(), values.end(), is_string) << std::endl; }
The following type, patterned after the OMG's Property Service, defines name-value pairs for arbitrary value types:
struct property { property(); property(const std::string &, const boost::any &); std::string name; boost::any value; }; typedef std::list<property> properties;
The following base class demonstrates one approach to runtime polymorphism based callbacks that also require arbitrary argument types. The absence of virtual member templates requires that different solutions have different trade-offs in terms of efficiency, safety, and generality. Using a checked variant type offers one approach:
class consumer { public: virtual void notify(const any &) = 0; ... };
The following code demonstrates boost::anys::unique_any
usage for implementing HTTP processing with passing of optional user data from
the authorizer to the HTTP body processing:
void HttpServer::ProcessRequest() const { const auto path = this->ReceiveHttpStartingLine(); auto headers = this->ReceiveHeaders(); boost::anys::unique_any user_data; const auto& user_authorizer = immutable_authorizers_.at(path); if (!user_authorizer(headers, user_data)) { throw Unauthorized(); } const auto body = this->ReceiveBody(); const auto& user_handler = immutable_handlers_.at(this->ReceiveHttpStartingLine()); user_handler(body, user_data); }