00001 // 00002 // Copyright (c) Benjamin Kaufmann 2010 00003 // 00004 // This is free software; you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation; either version 2 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // This file is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with this file; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 // 00018 // 00019 // NOTE: ProgramOptions is inspired by Boost.Program_options 00020 // see: www.boost.org/libs/program_options 00021 // 00022 #include <program_opts/value_store.h> 00023 #include <algorithm> 00024 namespace ProgramOptions { 00025 00026 ValueStore::ValueStore() 00027 : vptr_(0) 00028 , value_(0) { 00029 } 00030 ValueStore::ValueStore(const ValueStore& other) 00031 : vptr_(other.vptr_) 00032 , value_(0) { 00033 if (!other.empty()) { 00034 clone(extract(const_cast<void**>(&other.value_)), &value_); 00035 } 00036 } 00037 ValueStore::~ValueStore() { 00038 clear(); 00039 } 00040 ValueStore& ValueStore::operator=(ValueStore other) { 00041 other.swap(*this); 00042 return *this; 00043 } 00044 void ValueStore::swap(ValueStore& other) { 00045 std::swap(vptr_ , other.vptr_); 00046 std::swap(value_, other.value_); 00047 } 00048 00049 const std::type_info& ValueStore::type() const { 00050 if (!empty()) { 00051 void* x; 00052 (*vptr_)[vcall_typeid](0, &x); 00053 return *static_cast<const std::type_info*>( x ); 00054 } 00055 struct internal_empty_type {}; 00056 return typeid(internal_empty_type); 00057 } 00058 00059 void ValueStore::clear() { 00060 if (!empty()) { 00061 (*vptr_)[vcall_destroy](extract(&value_), &value_); 00062 vptr_ = 0; 00063 } 00064 } 00065 00066 void ValueStore::surrender() { 00067 vptr_ = 0; 00068 } 00069 00070 void ValueStore::clone(const void* obj, void** out) const { 00071 (*vptr_)[vcall_clone](obj, out); 00072 } 00073 00074 void* ValueStore::extract(void** v) const { 00075 if ((*vptr_)[call_extract] == 0) { 00076 return *v; 00077 } 00078 return reinterpret_cast<void*>(v); 00079 } 00080 00081 } 00082