system_base.hpp

Go to the documentation of this file.
00001 // -*- mode: c++; indent-tabs-mode: nil; -*-
00002 //
00003 //The Biomolecule Toolkit (BTK) is a C++ library for use in the
00004 //modeling, analysis, and design of biological macromolecules.
00005 //Copyright (C) 2006, Tim Robertson <kid50@users.sourceforge.net>
00006 //
00007 //This program is free software; you can redistribute it and/or modify
00008 //it under the terms of the GNU Lesser General Public License as published
00009 //by the Free Software Foundation; either version 2.1 of the License, or (at
00010 //your option) any later version.
00011 //
00012 //This program is distributed in the hope that it will be useful,  but
00013 //WITHOUT ANY WARRANTY; without even the implied warranty of
00014 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 //Lesser General Public License for more details.
00016 //
00017 //You should have received a copy of the GNU Lesser General Public License
00018 //along with this program; if not, write to the Free Software Foundation,
00019 //Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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 // Default PolymerSystemBase -- disabled.
00052 //
00053 template <typename S, // System type
00054           typename C, // chain type
00055           typename CI, // chain iterator
00056           typename CCI, // const chain iterator
00057           bool has_monomer_iterable_iface>
00058 struct PolymerSystemBase 
00059 {
00060   // technically speaking, these don't need to be here,
00061   // but it eliminates the need to create multiple import
00062   // macros to define them as void.
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 // PolymerSystemBase -- enabled.
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 } // detail
00186 } // MOLECULES
00187 } // BTK
00188 
00189 #endif 

Generated on Sun Jul 15 20:46:27 2007 for BTK Core by  doxygen 1.5.1