11dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org/* 21dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 31dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org * 41dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org * Use of this source code is governed by a BSD-style license 51dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org * that can be found in the LICENSE file in the root of the source 61dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org * tree. An additional intellectual property rights grant can be found 71dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org * in the file PATENTS. All contributing project authors may 81dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org * be found in the AUTHORS file in the root of the source tree. 91dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org */ 101dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org 1125613ea5abb9c44acaab04519677f6d17fe5e306andrew@webrtc.org#ifndef WEBRTC_COMMON_H_ 1225613ea5abb9c44acaab04519677f6d17fe5e306andrew@webrtc.org#define WEBRTC_COMMON_H_ 131dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org 141dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org#include <map> 151dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org 161dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.orgnamespace webrtc { 171dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org 181dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org// Class Config is designed to ease passing a set of options across webrtc code. 191dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org// Options are identified by typename in order to avoid incorrect casts. 201dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org// 211dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org// Usage: 221dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org// * declaring an option: 231dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org// struct Algo1_CostFunction { 241dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org// virtual float cost(int x) const { return x; } 251dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org// virtual ~Algo1_CostFunction() {} 261dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org// }; 271dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org// 281dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org// * accessing an option: 291dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org// config.Get<Algo1_CostFunction>().cost(value); 301dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org// 311dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org// * setting an option: 321dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org// struct SqrCost : Algo1_CostFunction { 331dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org// virtual float cost(int x) const { return x*x; } 341dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org// }; 351dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org// config.Set<Algo1_CostFunction>(new SqrCost()); 361dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org// 371dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org// Note: This class is thread-compatible (like STL containers). 381dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.orgclass Config { 391dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org public: 401dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org // Returns the option if set or a default constructed one. 4125613ea5abb9c44acaab04519677f6d17fe5e306andrew@webrtc.org // Callers that access options too often are encouraged to cache the result. 421dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org // Returned references are owned by this. 431dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org // 441dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org // Requires std::is_default_constructible<T> 451dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org template<typename T> const T& Get() const; 461dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org 471dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org // Set the option, deleting any previous instance of the same. 4825613ea5abb9c44acaab04519677f6d17fe5e306andrew@webrtc.org // This instance gets ownership of the newly set value. 491dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org template<typename T> void Set(T* value); 501dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org 511dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org Config() {} 521dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org ~Config() { 531dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org // Note: this method is inline so webrtc public API depends only 541dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org // on the headers. 551dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org for (OptionMap::iterator it = options_.begin(); 561dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org it != options_.end(); ++it) { 571dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org delete it->second; 581dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org } 591dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org } 601dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org 611dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org private: 621dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org typedef void* OptionIdentifier; 631dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org 641dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org struct BaseOption { 651dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org virtual ~BaseOption() {} 661dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org }; 671dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org 681dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org template<typename T> 691dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org struct Option : BaseOption { 701dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org explicit Option(T* v): value(v) {} 711dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org ~Option() { 721dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org delete value; 731dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org } 741dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org T* value; 751dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org }; 761dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org 771dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org // Own implementation of rtti-subset to avoid depending on rtti and its costs. 781dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org template<typename T> 791dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org static OptionIdentifier identifier() { 801dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org static char id_placeholder; 811dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org return &id_placeholder; 821dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org } 831dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org 841dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org // Used to instantiate a default constructed object that doesn't needs to be 851dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org // owned. This allows Get<T> to be implemented without requiring explicitly 861dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org // locks. 871dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org template<typename T> 881dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org static const T& default_value() { 891dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org static const T def; 901dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org return def; 911dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org } 921dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org 931dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org typedef std::map<OptionIdentifier, BaseOption*> OptionMap; 941dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org OptionMap options_; 951dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org 961dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org // DISALLOW_COPY_AND_ASSIGN 971dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org Config(const Config&); 981dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org void operator=(const Config&); 991dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org}; 1001dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org 1011dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.orgtemplate<typename T> 1021dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.orgconst T& Config::Get() const { 1031dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org OptionMap::const_iterator it = options_.find(identifier<T>()); 1041dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org if (it != options_.end()) { 1051dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org const T* t = static_cast<Option<T>*>(it->second)->value; 1061dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org if (t) { 1071dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org return *t; 1081dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org } 1091dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org } 1101dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org return default_value<T>(); 1111dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org} 1121dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org 1131dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.orgtemplate<typename T> 1141dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.orgvoid Config::Set(T* value) { 1151dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org BaseOption*& it = options_[identifier<T>()]; 1161dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org delete it; 1171dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org it = new Option<T>(value); 1181dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org} 11925613ea5abb9c44acaab04519677f6d17fe5e306andrew@webrtc.org 1201dba6218e85a206a8e57dc2c6d1e2f5a8cbbd30aandresp@webrtc.org} // namespace webrtc 12125613ea5abb9c44acaab04519677f6d17fe5e306andrew@webrtc.org 12225613ea5abb9c44acaab04519677f6d17fe5e306andrew@webrtc.org#endif // WEBRTC_COMMON_H_ 123