Skip to content

Instantly share code, notes, and snippets.

@sholsapp
Created April 4, 2016 15:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sholsapp/c38d68e8e4b199fa7124ca1305d23267 to your computer and use it in GitHub Desktop.
Save sholsapp/c38d68e8e4b199fa7124ca1305d23267 to your computer and use it in GitHub Desktop.
An implementation of a boost::any-like thing.
#include <iostream>
#include <map>
#include <string>
#include <utility>
class any {
public:
any()
: content(0)
{}
any(const any &other)
: content(other.content ? other.content->clone() : 0)
{}
template<typename value_type>
any(const value_type &value)
: content(new holder<value_type>(value))
{}
any &swap(any &rhs) {
std::swap(content, rhs.content);
return *this;
}
any &operator=(const any &rhs) {
// TODO(sholsapp): WTF
any tmp = any(rhs);
return swap(tmp);
}
template<typename value_type>
any &operator=(const value_type &rhs) {
// TODO(sholsapp): WTF
any tmp = any(rhs);
return swap(tmp);
}
~any() {
delete content;
}
const std::type_info &type_info() const {
return content
? content->type_info()
: typeid(void);
}
operator const void *() const {
return content;
}
template<typename value_type>
bool copy_to(value_type &value) const {
const value_type *copyable = to_ptr<value_type>();
if (copyable)
value = *copyable;
return copyable;
}
template<typename value_type>
const value_type *to_ptr() const {
return type_info() == typeid(value_type)
? std::addressof(static_cast<holder<value_type> *>(content)->held)
: 0;
}
private:
class placeholder {
public:
virtual ~placeholder() {}
virtual const std::type_info &type_info() const = 0;
virtual placeholder *clone() const = 0;
};
template <typename value_type>
class holder: public placeholder {
public:
holder(const value_type &value)
: held(value)
{}
virtual const std::type_info &type_info() const {
return typeid(value_type);
}
virtual placeholder *clone() const {
return new holder(held);
}
const value_type held;
};
placeholder *content;
};
template<typename value_type>
value_type any_cast(const any &operand) {
const value_type *result = operand.to_ptr<value_type>();
return result
? *result
: throw std::bad_cast();
}
int main(int argc, char *argv[]) {
std::map<std::string, any> test;
test["integer"] = static_cast<int64_t>(1);
test["string"] = std::string("foo");
test["float"] = 3.14;
int64_t a_integer = any_cast<int64_t>(test["integer"]);
std::string a_string = any_cast<std::string>(test["string"]);
double a_float = any_cast<double>(test["float"]);
std::cout << "test[\"integer\"] = " << a_integer << std::endl
<< "test[\"string\"] = " << a_string << std::endl
<< "test[\"float\"] = " << a_float << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment