|
libpsynth 0.2.1
|
00001 00013 /* 00014 * Copyright (C) 2010 Juan Pedro Bolivar Puente 00015 * 00016 * This file is part of Psychosynth. 00017 * 00018 * Psychosynth is free software: you can redistribute it and/or modify 00019 * it under the terms of the GNU General Public License as published by 00020 * the Free Software Foundation, either version 3 of the License, or 00021 * (at your option) any later version. 00022 * 00023 * Psychosynth is distributed in the hope that it will be useful, 00024 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00025 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00026 * GNU General Public License for more details. 00027 * 00028 * You should have received a copy of the GNU General Public License 00029 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00030 * 00031 */ 00032 00033 #ifndef PSYNTH_BASE_DECLARE_H_ 00034 #define PSYNTH_BASE_DECLARE_H_ 00035 00036 #include <utility> 00037 #include <memory> 00038 00039 #include <boost/preprocessor/cat.hpp> 00040 #include <boost/preprocessor/seq/size.hpp> 00041 #include <boost/preprocessor/seq/for_each_i.hpp> 00042 #include <boost/preprocessor/repetition/enum_params.hpp> 00043 00044 #include <psynth/base/preprocessor.hpp> 00045 00046 namespace psynth 00047 { 00048 namespace base 00049 { 00050 00051 #define PSYNTH_DECLARE_SHARED_POINTER(type_name) \ 00052 typedef std::shared_ptr<type_name> type_name ## _ptr; \ 00053 typedef std::weak_ptr<type_name> type_name ## _weak_ptr; \ 00054 template <typename... Args> \ 00055 type_name ## _ptr new_ ## type_name (Args && ... args) \ 00056 { \ 00057 return std::make_shared <type_name> ( \ 00058 std::forward<Args>(args) ...); \ 00059 } 00060 00061 #define PSYNTH_DECLARE_TYPE(type_name) \ 00062 struct type_name; 00063 00064 #define PSYNTH_DECLARE_SHARED_TYPE(type_name) \ 00065 PSYNTH_DECLARE_TYPE (type_name) \ 00066 PSYNTH_DECLARE_SHARED_POINTER (type_name) 00067 00068 00072 #define PSYNTH_DECLARE_SHARED_POINTER_TEMPLATE(type_name, ...) \ 00073 PSYNTH_DECLARE_SHARED_POINTER_TEMPLATE_IMPL( \ 00074 type_name, PSYNTH_VARG_TO_SEQ(__VA_ARGS__)) 00075 00076 #define PSYNTH_TEMPLATE_PARAM_ITER(r, data, i, elem) \ 00077 BOOST_PP_COMMA_IF(i) elem BOOST_PP_CAT(Par__, i) 00078 00079 #define PSYNTH_TEMPLATE_PARAMS_FULL(param_seq) \ 00080 BOOST_PP_SEQ_FOR_EACH_I(PSYNTH_TEMPLATE_PARAM_ITER, _, param_seq) 00081 00082 #define PSYNTH_TEMPLATE_PARAMS(param_seq) \ 00083 BOOST_PP_ENUM_PARAMS(BOOST_PP_SEQ_SIZE(param_seq), Par__) 00084 00085 // TODO: Make this generate a weak pointer alias too? 00086 #define PSYNTH_DECLARE_SHARED_POINTER_TEMPLATE_IMPL(type_name, param_seq) \ 00087 template <PSYNTH_TEMPLATE_PARAMS_FULL(param_seq)> \ 00088 struct type_name ## _ptr : \ 00089 public std::shared_ptr<type_name <PSYNTH_TEMPLATE_PARAMS(param_seq)> > \ 00090 { \ 00091 typedef std::shared_ptr<type_name <PSYNTH_TEMPLATE_PARAMS(param_seq)> > base; \ 00092 template <typename... Args> \ 00093 type_name ## _ptr (Args&&... args) \ 00094 : base (std::forward<Args> (args) ...) {} \ 00095 template <typename... Args> \ 00096 type_name ## _ptr& operator= (Args&&... args) \ 00097 { this->base::operator= (std::forward<Args> (args) ...); return *this; } \ 00098 }; \ 00099 \ 00100 template <PSYNTH_TEMPLATE_PARAMS_FULL(param_seq), typename... Args> \ 00101 type_name ## _ptr<PSYNTH_TEMPLATE_PARAMS(param_seq)> \ 00102 inline new_ ## type_name (Args && ... args) \ 00103 { \ 00104 return \ 00105 std::make_shared <type_name <PSYNTH_TEMPLATE_PARAMS(param_seq)> > \ 00106 (std::forward<Args>(args)...); \ 00107 } 00108 00109 #define PSYNTH_DECLARE_TEMPLATE(type_name, ...) \ 00110 template <__VA_ARGS__> \ 00111 struct type_name; 00112 00113 #define PSYNTH_DECLARE_SHARED_TEMPLATE(type_name, ...) \ 00114 PSYNTH_DECLARE_TEMPLATE (type_name, __VA_ARGS__) \ 00115 PSYNTH_DECLARE_SHARED_POINTER_TEMPLATE (type_name, __VA_ARGS__) 00116 00117 } /* namespace base */ 00118 } /* namespace psynth */ 00119 00120 00121 #endif /* PSYNTH_BASE_DECLARE_H_ */
1.7.4