sample/subextension.auto_ptr/main.cpp

00001 /*
00002 
00003 Copyright (c) 2002-2005, Yauheni Akhotnikau
00004 All rights reserved.
00005 
00006 Redistribution and use in source and binary forms, with or without
00007 modification, are permitted provided that the following conditions are met:
00008 
00009 - Redistributions of source code must retain the above copyright notice, this
00010 list of conditions and the following disclaimer.
00011 
00012 - Redistributions in binary form must reproduce the above copyright notice, this
00013 list of conditions and the following disclaimer in the documentation and/or
00014 other materials provided with the distribution.
00015 
00016 - The name of the author may not be used to endorse or promote products derived
00017 from this software without specific prior written permission.
00018 
00019 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
00020 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00021 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
00022 EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00023 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00024 OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
00027 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00028 OF SUCH DAMAGE.
00029 
00030 */
00031 
00032 /*
00033   Пример работы с механизмом subclassing by extension.
00034 
00035   В качестве политики для умных указателей используется
00036   политика на основе клонирования. Отличие от примера
00037   sample/subextension состоит в том, что метод clone возвращает
00038   не голый указатель, а std::auto_ptr.
00039 */
00040 
00041 #include <iostream>
00042 #include <stdexcept>
00043 #include <memory>
00044 
00045 #include <oess_1/io/h/mem_buf.hpp>
00046 #include <oess_1/stdsn/h/serializable.hpp>
00047 #include <oess_1/stdsn/h/ent_std.hpp>
00048 #include <oess_1/stdsn/h/inout_templ.hpp>
00049 #include <oess_1/stdsn/h/shptr.hpp>
00050 
00051 /*
00052   Базовый класс в иерархии subclassing by extension классов.
00053 */
00054 class base_t
00055   : public oess_1::stdsn::serializable_t
00056   {
00057     OESS_SERIALIZER( base_t )
00058   public :
00059     base_t() {}
00060     virtual ~base_t()
00061       {}
00062 
00063     virtual std::auto_ptr< base_t >
00064     clone() const = 0;
00065   };
00066 
00067 class base_shptr_t
00068   : public oess_1::stdsn::shptr_skeleton_t<
00069         base_t,
00070         oess_1::stdsn::cloneable_policy_t< base_t > >
00071   {
00072     typedef oess_1::stdsn::shptr_skeleton_t<
00073             base_t,
00074             oess_1::stdsn::cloneable_policy_t< base_t > >
00075         base_type_t;
00076 
00077     OESS_SERIALIZER( base_shptr_t )
00078     OESS_1_SHPTR_IFACE(
00079         base_shptr_t,
00080         base_t,
00081         base_type_t )
00082   };
00083 
00084 /*
00085   Класс, атрибутами которого являются экземпляры класса base_t.
00086 */
00087 class holder_t
00088   : public oess_1::stdsn::serializable_t
00089   {
00090     OESS_SERIALIZER( holder_t )
00091   public :
00092     holder_t() {}
00093     holder_t(
00094       const base_shptr_t & value )
00095       : m_value( value )
00096       {}
00097     virtual ~holder_t() {}
00098 
00099     const base_shptr_t &
00100     value() const
00101       {
00102         return m_value;
00103       }
00104 
00105     void
00106     set_value( const base_shptr_t & v )
00107       {
00108         m_value = v;
00109       }
00110 
00111   private :
00112     base_shptr_t  m_value;
00113   };
00114 
00115 /*
00116   Первый потомок base_t.
00117 */
00118 class string_value_t
00119   : public base_t
00120   {
00121     typedef base_t base_type_t;
00122     OESS_SERIALIZER( string_value_t )
00123   public :
00124     string_value_t()
00125       {}
00126     string_value_t( const std::string & value )
00127       : m_value( value )
00128       {}
00129     virtual ~string_value_t()
00130       {}
00131 
00132     virtual std::auto_ptr< base_t >
00133     clone() const
00134       {
00135         return std::auto_ptr< base_t >(
00136             new string_value_t( *this ) );
00137       }
00138 
00139     const std::string &
00140     value() const
00141       {
00142         return m_value;
00143       }
00144 
00145     void
00146     set_value( const std::string & v )
00147       {
00148         m_value = v;
00149       }
00150 
00151   private :
00152     std::string m_value;
00153   };
00154 
00155 /*
00156   Второй потомок base_t.
00157 */
00158 class incapsulated_value_t
00159   : public base_t
00160   {
00161     typedef base_t base_type_t;
00162     OESS_SERIALIZER( incapsulated_value_t )
00163   public :
00164     incapsulated_value_t()
00165       {
00166       }
00167     incapsulated_value_t(
00168       const base_shptr_t & original,
00169       const std::string & self )
00170       : m_original( original )
00171       , m_self( self )
00172       {
00173       }
00174     virtual ~incapsulated_value_t()
00175       {
00176       }
00177 
00178     virtual std::auto_ptr< base_t >
00179     clone() const
00180       {
00181         return std::auto_ptr< base_t >(
00182             new incapsulated_value_t( *this ) );
00183       }
00184 
00185     const base_shptr_t &
00186     original() const
00187       {
00188         return m_original;
00189       }
00190 
00191     void
00192     set_original(
00193       const base_shptr_t & o )
00194       {
00195         m_original = o;
00196       }
00197 
00198     const std::string &
00199     self() const
00200       {
00201         return m_self;
00202       }
00203 
00204     void
00205     set_self( const std::string & v )
00206       {
00207         m_self = v;
00208       }
00209 
00210   private :
00211     base_shptr_t  m_original;
00212     std::string m_self;
00213   };
00214 
00215 #include "main.ddl.cpp"
00216 
00217 const std::string test_identity = "my-test-identification-string";
00218 
00219 void
00220 receive_string_value(
00221   const holder_t & holder )
00222   {
00223     const string_value_t & sv = *holder.value().cast_to(
00224         oess_1::stdsn::shptr_type_tag< string_value_t >() );
00225 
00226     if( test_identity != sv.value() )
00227       throw std::domain_error(
00228           std::string( "receive_string_value: Expected value: " ) +
00229           test_identity + ", actual value: " + sv.value() );
00230   }
00231 
00232 void
00233 receive_incapsulated_string_value(
00234   const holder_t & holder )
00235   {
00236     const incapsulated_value_t & iv = *holder.value().cast_to(
00237         oess_1::stdsn::shptr_type_tag< incapsulated_value_t  >() );
00238 
00239     if( test_identity != iv.self() )
00240       throw std::domain_error(
00241           std::string( "receive_incapsulated_string_value: "
00242               "Expected 'self' value: " ) +
00243           test_identity + ", actual 'self' value: " + iv.self() );
00244 
00245     const string_value_t & sv = *iv.original().cast_to(
00246         oess_1::stdsn::shptr_type_tag< string_value_t >() );
00247     if( test_identity != sv.value() )
00248       throw std::domain_error(
00249           std::string( "receive_incapsulated_string_value: "
00250               "Expected 'string' value: " ) +
00251           test_identity + ", actual 'string' value: " + sv.value() );
00252   }
00253 
00254 holder_t
00255 send_string_value(
00256   const string_value_t & v )
00257   {
00258     return holder_t( base_shptr_t( v.clone().release() ) );
00259   }
00260 
00261 holder_t
00262 send_incapsulated_value(
00263   const base_shptr_t & original,
00264   const std::string & self )
00265   {
00266     return holder_t(
00267         base_shptr_t(
00268             new incapsulated_value_t( original, self ) ) );
00269   }
00270 
00271 void
00272 test_string_value_packing()
00273   {
00274     // Эта строка не должна вызвать исключения.
00275     receive_string_value(
00276         send_string_value(
00277             string_value_t( test_identity ) ) );
00278   }
00279 
00280 void
00281 test_incapsulated_value_packing()
00282   {
00283     // Эта строка не должна вызвать исключения.
00284     receive_incapsulated_string_value(
00285         send_incapsulated_value(
00286             base_shptr_t( new string_value_t( test_identity ) ),
00287             test_identity ) );
00288 
00289     bool is_test_failed = true;
00290     try
00291       {
00292         // А вот здесь исключение должно произойти.
00293         receive_incapsulated_string_value(
00294             send_incapsulated_value(
00295                 base_shptr_t(
00296                     new incapsulated_value_t(
00297                         base_shptr_t(
00298                             new string_value_t(
00299                                 test_identity ) ),
00300                         test_identity ) ),
00301                 test_identity ) );
00302       }
00303     catch( const oess_1::ex_t & )
00304       {
00305         is_test_failed = false;
00306       }
00307     if( is_test_failed )
00308       throw std::logic_error(
00309           "Exception for invalid casting not thrown!" );
00310   }
00311 
00312 int
00313 main()
00314   {
00315     try
00316       {
00317         test_string_value_packing();
00318         test_incapsulated_value_packing();
00319 
00320         return 0;
00321       }
00322     catch( const std::exception & x )
00323       {
00324         std::cerr << "### " << x.what() << " ###" << std::endl;
00325       }
00326 
00327     return 2;
00328   }
00329 

Документация по ObjESSty. Последние изменения: Fri Oct 13 18:35:35 2006. Создано системой  doxygen 1.4.7
Hosted by uCoz