00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef BTK_MOLECULES_SYSTEM_BASE_HPP
00022 #define BTK_MOLECULES_SYSTEM_BASE_HPP
00023
00024 #include <boost/iterator/reverse_iterator.hpp>
00025
00026 #include <btk/core/utility/grouped_element_iterator.hpp>
00027
00028 namespace BTK {
00029 namespace MOLECULES {
00030 namespace detail {
00031
00032 typedef struct { char c[1]; } yes;
00033 typedef struct { char c[2]; } no;
00034
00035 template <typename T>
00036 no is_monomer_iterable(...);
00037
00038 template <typename T>
00039 yes is_monomer_iterable(typename T::monomer_type const volatile *,
00040 typename T::size_type const volatile *,
00041 typename T::monomer_iterator const volatile *,
00042 typename T::reverse_monomer_iterator const volatile *);
00043
00044 template <typename T>
00045 struct IsMonomerIterable
00046 {
00047 enum { value = (sizeof(is_monomer_iterable<T>(0,0,0,0)) == sizeof(yes)) };
00048 };
00049
00050
00051
00052
00053 template <typename S,
00054 typename C,
00055 typename CI,
00056 typename CCI,
00057 bool has_monomer_iterable_iface>
00058 struct PolymerSystemBase
00059 {
00060
00061
00062
00063 typedef void monomer_type;
00064 typedef void monomer_iterator;
00065 typedef void const_monomer_iterator;
00066 typedef void reverse_monomer_iterator;
00067 typedef void const_reverse_monomer_iterator;
00068 };
00069
00070
00071
00072
00073 template <typename S,
00074 typename C,
00075 typename CI,
00076 typename CCI>
00077 struct PolymerSystemBase<S,C,CI,CCI,true>
00078 {
00079 private:
00080 typedef C chain_type;
00081 typedef CI chain_iterator;
00082 typedef CCI const_chain_iterator;
00083
00084 public:
00085 typedef typename chain_type::monomer_type monomer_type;
00086
00087 typedef BTK::UTILITY::
00088 GroupedElementIterator<chain_iterator,
00089 typename chain_type::monomer_iterator,
00090 chain_type,
00091 monomer_type> monomer_iterator;
00092
00093 typedef BTK::UTILITY::
00094 GroupedElementIterator<const_chain_iterator,
00095 typename chain_type::const_monomer_iterator,
00096 chain_type const,
00097 monomer_type const> const_monomer_iterator;
00098
00099 typedef boost::reverse_iterator<monomer_iterator> reverse_monomer_iterator;
00100 typedef boost::
00101 reverse_iterator<const_monomer_iterator> const_reverse_monomer_iterator;
00102
00103
00104 typename chain_type::size_type
00105 num_monomers() const
00106 {
00107 typename chain_type::size_type N = 0;
00108 const_chain_iterator ci, c_end;
00109
00110 ci = static_cast<S const *>(this)->system_begin();
00111 c_end = static_cast<S const *>(this)->system_end();
00112
00113 while (ci != c_end) {
00114 N += ci->num_monomers();
00115 ++ci;
00116 }
00117
00118 return N;
00119 }
00120
00121
00122 monomer_iterator polymer_begin()
00123 {
00124 S & sys = static_cast<S&>(*this);
00125
00126 return monomer_iterator(sys.system_begin(),
00127 sys.system_end(),
00128 &chain_type::polymer_begin,
00129 &chain_type::polymer_end);
00130 }
00131
00132 monomer_iterator polymer_end()
00133 {
00134 S & sys = static_cast<S&>(*this);
00135
00136 return monomer_iterator(sys.system_begin(),
00137 sys.system_end(),
00138 &chain_type::polymer_begin,
00139 &chain_type::polymer_end,
00140 true);
00141 }
00142
00143 reverse_monomer_iterator polymer_rbegin()
00144 {
00145 return reverse_monomer_iterator(polymer_end());
00146 }
00147
00148 reverse_monomer_iterator polymer_rend()
00149 {
00150 return reverse_monomer_iterator(polymer_begin());
00151 }
00152
00153 const_monomer_iterator polymer_begin() const
00154 {
00155 S const & sys = static_cast<S const &>(*this);
00156
00157 return const_monomer_iterator(sys.system_begin(),
00158 sys.system_end(),
00159 &chain_type::polymer_begin,
00160 &chain_type::polymer_end);
00161 }
00162
00163 const_monomer_iterator polymer_end() const
00164 {
00165 S const & sys = static_cast<S const &>(*this);
00166
00167 return const_monomer_iterator(sys.system_begin(),
00168 sys.system_end(),
00169 &chain_type::polymer_begin,
00170 &chain_type::polymer_end,
00171 true);
00172 }
00173
00174 const_reverse_monomer_iterator polymer_rbegin() const
00175 {
00176 return const_reverse_monomer_iterator(polymer_end());
00177 }
00178
00179 const_reverse_monomer_iterator polymer_rend() const
00180 {
00181 return const_reverse_polymer_iterator(polymer_begin());
00182 }
00183 };
00184
00185 }
00186 }
00187 }
00188
00189 #endif