classstr.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:61k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: classstr.cpp,v $
  4.  * PRODUCTION Revision 1000.3  2004/06/01 19:42:34  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.63
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: classstr.cpp,v 1000.3 2004/06/01 19:42:34 gouriano Exp $
  10. * ===========================================================================
  11. *
  12. *                            PUBLIC DOMAIN NOTICE
  13. *               National Center for Biotechnology Information
  14. *
  15. *  This software/database is a "United States Government Work" under the
  16. *  terms of the United States Copyright Act.  It was written as part of
  17. *  the author's official duties as a United States Government employee and
  18. *  thus cannot be copyrighted.  This software/database is freely available
  19. *  to the public for use. The National Library of Medicine and the U.S.
  20. *  Government have not placed any restriction on its use or reproduction.
  21. *
  22. *  Although all reasonable efforts have been taken to ensure the accuracy
  23. *  and reliability of the software and data, the NLM and the U.S.
  24. *  Government do not and cannot warrant the performance or results that
  25. *  may be obtained by using this software or data. The NLM and the U.S.
  26. *  Government disclaim all warranties, express or implied, including
  27. *  warranties of performance, merchantability or fitness for any particular
  28. *  purpose.
  29. *
  30. *  Please cite the author in any work or product based on this material.
  31. *
  32. * ===========================================================================
  33. *
  34. * Author: Eugene Vasilchenko
  35. *
  36. * File Description:
  37. *   Type info for class generation: includes, used classes, C code etc.
  38. */
  39. #include <ncbi_pch.hpp>
  40. #include <serial/datatool/exceptions.hpp>
  41. #include <serial/datatool/type.hpp>
  42. #include <serial/datatool/blocktype.hpp>
  43. #include <serial/datatool/classstr.hpp>
  44. #include <serial/datatool/stdstr.hpp>
  45. #include <serial/datatool/code.hpp>
  46. #include <serial/datatool/srcutil.hpp>
  47. #include <serial/datatool/comments.hpp>
  48. BEGIN_NCBI_SCOPE
  49. #define SET_PREFIX "m_set_State"
  50. #define DELAY_PREFIX "m_delay_"
  51. CClassTypeStrings::CClassTypeStrings(const string& externalName,
  52.                                      const string& className)
  53.     : m_IsObject(true), m_HaveUserClass(true), m_HaveTypeInfo(true),
  54.       m_ExternalName(externalName), m_ClassName(className)
  55. {
  56. }
  57. CClassTypeStrings::~CClassTypeStrings(void)
  58. {
  59. }
  60. CTypeStrings::EKind CClassTypeStrings::GetKind(void) const
  61. {
  62.     return m_IsObject? eKindObject: eKindClass;
  63. }
  64. bool CClassTypeStrings::x_IsNullType(TMembers::const_iterator i) const
  65. {
  66.     return i->haveFlag ?
  67.         (dynamic_cast<CNullTypeStrings*>(i->type.get()) != 0) : false;
  68. }
  69. bool CClassTypeStrings::x_IsNullWithAttlist(TMembers::const_iterator i) const
  70. {
  71.     if (i->ref && i->dataType) {
  72.         const CDataType* resolved = i->dataType->Resolve();
  73.         if (resolved && resolved != i->dataType) {
  74.             CClassTypeStrings* typeStr = resolved->GetTypeStr();
  75.             if (typeStr) {
  76.                 ITERATE ( TMembers, ir, typeStr->m_Members ) {
  77.                     if (ir->simple) {
  78.                         return x_IsNullType(ir);
  79.                     }
  80.                 }
  81.             }
  82.         }
  83.     }
  84.     return false;
  85. }
  86. void CClassTypeStrings::AddMember(const string& name,
  87.                                   const AutoPtr<CTypeStrings>& type,
  88.                                   const string& pointerType,
  89.                                   bool optional,
  90.                                   const string& defaultValue,
  91.                                   bool delayed, int tag,
  92.                                   bool noPrefix, bool attlist, bool noTag,
  93.                                   bool simple,const CDataType* dataType,
  94.                                   bool nonempty)
  95. {
  96.     m_Members.push_back(SMemberInfo(name, type,
  97.                                     pointerType,
  98.                                     optional, defaultValue,
  99.                                     delayed, tag, noPrefix,attlist,noTag,
  100.                                     simple,dataType,nonempty));
  101. }
  102. CClassTypeStrings::SMemberInfo::SMemberInfo(const string& name,
  103.                                             const AutoPtr<CTypeStrings>& t,
  104.                                             const string& pType,
  105.                                             bool opt, const string& defValue,
  106.                                             bool del, int tag, bool noPrefx,
  107.                                             bool attlst, bool noTg, bool simpl,
  108.                                             const CDataType* dataTp, bool nEmpty)
  109.     : externalName(name), cName(Identifier(name)),
  110.       mName("m_"+cName), tName('T'+cName),
  111.       type(t), ptrType(pType),
  112.       optional(opt), delayed(del), memberTag(tag),
  113.       defaultValue(defValue), noPrefix(noPrefx), attlist(attlst), noTag(noTg),
  114.       simple(simpl),dataType(dataTp),nonEmpty(nEmpty)
  115. {
  116.     if ( cName.empty() ) {
  117.         mName = "m_data";
  118.         tName = "Tdata";
  119.     }
  120.     bool haveDefault = !defaultValue.empty();
  121. //    if ( optional && !haveDefault ) {
  122. //    }
  123.     // true [optional] CObject type should be implemented as CRef
  124.     if ( ptrType.empty() ) {
  125.         if ( type->GetKind() == eKindObject )
  126.             ptrType = "Ref";
  127.         else
  128.             ptrType = "false";
  129.     }
  130.     if ( ptrType == "Ref" ) {
  131.         ref = true;
  132.     }
  133.     else if ( /*ptrType.empty()  ||*/ ptrType == "false" ) {
  134.         ref = false;
  135.     }
  136.     else {
  137.         _ASSERT("Unknown reference type: "+ref);
  138.     }
  139.     
  140.     if ( ref ) {
  141.         valueName = "(*"+mName+")";
  142.         haveFlag = false;
  143.     }
  144.     else {
  145.         valueName = mName;
  146.         haveFlag = /*optional &&*/ type->NeedSetFlag();
  147.     }
  148.     if ( haveDefault ) // cannot detect DEFAULT value
  149.         haveFlag = true;
  150.     
  151.     canBeNull = ref && optional && !haveFlag;
  152. }
  153. string CClassTypeStrings::GetCType(const CNamespace& /*ns*/) const
  154. {
  155.     return GetClassNameDT();
  156. }
  157. string CClassTypeStrings::GetPrefixedCType(const CNamespace& ns,
  158.                                            const string& methodPrefix) const
  159. {
  160.     string s;
  161.     if (!HaveUserClass()) {
  162.         s += methodPrefix;
  163.     }
  164.     return s + GetCType(ns);
  165. }
  166. string CClassTypeStrings::GetRef(const CNamespace& /*ns*/) const
  167. {
  168.     return "CLASS, ("+GetClassNameDT()+')';
  169. }
  170. string CClassTypeStrings::NewInstance(const string& init) const
  171. {
  172.     return "new "+GetCType(CNamespace::KEmptyNamespace)+"("+init+')';
  173. }
  174. string CClassTypeStrings::GetResetCode(const string& var) const
  175. {
  176.     return var+".Reset();n";
  177. }
  178. void CClassTypeStrings::SetParentClass(const string& className,
  179.                                        const CNamespace& ns,
  180.                                        const string& fileName)
  181. {
  182.     m_ParentClassName = className;
  183.     m_ParentClassNamespace = ns;
  184.     m_ParentClassFileName = fileName;
  185. }
  186. static
  187. CNcbiOstream& DeclareConstructor(CNcbiOstream& out, const string className)
  188. {
  189.     return out <<
  190.         "    // constructorn"
  191.         "    "<<className<<"(void);n";
  192. }
  193. static
  194. CNcbiOstream& DeclareDestructor(CNcbiOstream& out, const string className,
  195.                                 bool virt)
  196. {
  197.     out <<
  198.         "    // destructorn"
  199.         "    ";
  200.     if ( virt )
  201.         out << "virtual ";
  202.     return out << '~'<<className<<"(void);n"
  203.         "n";
  204. }
  205. void CClassTypeStrings::GenerateTypeCode(CClassContext& ctx) const
  206. {
  207.     bool haveUserClass = HaveUserClass();
  208.     string codeClassName = GetClassNameDT();
  209.     if ( haveUserClass )
  210.         codeClassName += "_Base";
  211.     CClassCode code(ctx, codeClassName);
  212.     if ( !m_ParentClassName.empty() ) {
  213.         code.SetParentClass(m_ParentClassName, m_ParentClassNamespace);
  214.         if ( !m_ParentClassFileName.empty() )
  215.             code.HPPIncludes().insert(m_ParentClassFileName);
  216.     }
  217.     else if ( GetKind() == eKindObject ) {
  218.         code.SetParentClass("CSerialObject", CNamespace::KNCBINamespace);
  219.     }
  220.     string methodPrefix = code.GetMethodPrefix();
  221.     DeclareConstructor(code.ClassPublic(), codeClassName);
  222.     DeclareDestructor(code.ClassPublic(), codeClassName, haveUserClass);
  223.     string ncbiNamespace =
  224.         code.GetNamespace().GetNamespaceRef(CNamespace::KNCBINamespace);
  225.     if (HaveTypeInfo()) {
  226.         code.ClassPublic() <<
  227.             "    // type infon"
  228.             "    DECLARE_INTERNAL_TYPE_INFO();n"
  229.             "n";
  230.     }
  231.     GenerateClassCode(code,
  232.                       code.ClassPublic(),
  233.                       methodPrefix, haveUserClass, ctx.GetMethodPrefix());
  234.     // constructors/destructor code
  235.     code.Methods() <<
  236.         "// constructorn"<<
  237.         methodPrefix<<codeClassName<<"(void)n";
  238.     if ( code.HaveInitializers() ) {
  239.         code.Methods() <<
  240.             "    : ";
  241.         code.WriteInitializers(code.Methods());
  242.         code.Methods() << 'n';
  243.     }
  244.     code.Methods() <<
  245.         "{n";
  246.     if (typeid(*this) == typeid(CClassTypeStrings)) {
  247.         code.Methods() <<
  248.             "    memset("SET_PREFIX",0,sizeof("SET_PREFIX"));n";
  249.     }
  250.     code.Methods() <<
  251.         "}n"
  252.         "n";
  253.     code.Methods() <<
  254.         "// destructorn"<<
  255.         methodPrefix<<"~"<<codeClassName<<"(void)n"
  256.         "{n";
  257.     code.WriteDestructionCode(code.Methods());
  258.     code.Methods() <<
  259.         "}n"
  260.         "n";
  261. }
  262. void CClassTypeStrings::GenerateClassCode(CClassCode& code,
  263.                                           CNcbiOstream& setters,
  264.                                           const string& methodPrefix,
  265.                                           bool haveUserClass,
  266.                                           const string& classPrefix) const
  267. {
  268.     bool delayed = false;
  269.     bool generateDoNotDeleteThisObject = false;
  270.     bool wrapperClass = SizeIsOne(m_Members) &&
  271.         m_Members.front().cName.empty();
  272.     // generate member methods
  273.     {
  274.         ITERATE ( TMembers, i, m_Members ) {
  275.             if ( i->ref ) {
  276.                 i->type->GeneratePointerTypeCode(code);
  277.             }
  278.             else {
  279.                 i->type->GenerateTypeCode(code);
  280.                 if ( i->type->GetKind() == eKindObject )
  281.                     generateDoNotDeleteThisObject = true;
  282.             }
  283.             if ( i->delayed )
  284.                 delayed = true;
  285.         }
  286.     }
  287.     // check if the class is Attlist
  288.     bool isAttlist = false;
  289.     if (!m_Members.empty()) {
  290.         TMembers::const_iterator i = m_Members.begin();
  291.         if (i->dataType) {
  292.             const CDataType* t2 = i->dataType->GetParentType();
  293.             if (t2) {
  294.                 const CDataMember* d = t2->GetDataMember();
  295.                 if (d) {
  296.                     isAttlist = d->Attlist();
  297.                 }
  298.             }
  299.         }
  300.     }
  301.     if ( GetKind() != eKindObject )
  302.         generateDoNotDeleteThisObject = false;
  303.     if ( delayed )
  304.         code.HPPIncludes().insert("serial/delaybuf");
  305.     // generate member types
  306.     {
  307.         code.ClassPublic() <<
  308.             "    // typesn";
  309.         ITERATE ( TMembers, i, m_Members ) {
  310.             string cType = i->type->GetCType(code.GetNamespace());
  311.             if (!x_IsNullType(i)) {
  312.                 code.ClassPublic() <<
  313.                     "    typedef "<<cType<<" "<<i->tName<<";n";
  314.             }
  315.         }
  316.         code.ClassPublic() << 
  317.             "n";
  318.     }
  319.     string ncbiNamespace =
  320.         code.GetNamespace().GetNamespaceRef(CNamespace::KNCBINamespace);
  321.     CNcbiOstream& methods = code.Methods();
  322.     CNcbiOstream& inlineMethods = code.InlineMethods();
  323.     if ( wrapperClass ) {
  324.         const SMemberInfo& info = m_Members.front();
  325.         if ( info.type->CanBeCopied() ) {
  326.             string cType = info.type->GetCType(code.GetNamespace());
  327.             code.ClassPublic() <<
  328.                 "    /// Data copy constructor.n"
  329.                 "    "<<code.GetClassNameDT()<<"(const "<<cType<<"& value);n"
  330.                 "n"
  331.                 "    /// Data assignment operator.n"
  332.                 "    void operator=(const "<<cType<<"& value);n"
  333.                 "n";
  334.             inlineMethods <<
  335.                 "inlinen"<<
  336.                 methodPrefix<<code.GetClassNameDT()<<"(const "<<info.tName<<"& value)n"
  337.                 "    : "<<info.mName<<"(value)n"
  338.                 "{n"
  339.                 "}n"
  340.                 "n"
  341.                 "inlinen"
  342.                 "void "<<methodPrefix<<"operator=(const "<<info.tName<<"& value)n"
  343.                 "{n"
  344.                 "    "<<info.mName<<" = value;n"
  345.                 "}n"
  346.                 "n";
  347.         }
  348.     }
  349.     // generate member getters & setters
  350.     {
  351.         code.ClassPublic() <<
  352.             "    // gettersn";
  353.         setters <<
  354.             "    // settersnn";
  355.         size_t member_index = (size_t)-1;
  356.         size_t set_index;
  357.         size_t set_offset;
  358.         Uint4  set_mask, set_mask_maybe;
  359.         bool isNull, isNullWithAtt;
  360.         ITERATE ( TMembers, i, m_Members ) {
  361.             // generate IsSet... method
  362.             ++member_index;
  363.             set_index  = (2*member_index)/(8*sizeof(Uint4));
  364.             set_offset = (2*member_index)%(8*sizeof(Uint4));
  365.             set_mask   = (0x03 << set_offset);
  366.             set_mask_maybe = (0x01 << set_offset);
  367.             {
  368.                 isNull = x_IsNullType(i);
  369.                 isNullWithAtt = x_IsNullWithAttlist(i);
  370. // IsSetX
  371.                 if (CClassCode::GetDoxygenComments()) {
  372.                     code.ClassPublic() <<
  373.                         "n"
  374.                         "    /// Check if a value has been assigned to "<<i->cName<<" data member.n"
  375.                         "    ///n"
  376.                         "    /// Data member "<<i->cName<<" is ";
  377.                 } else {
  378.                     code.ClassPublic() <<
  379.                         "    /// ";
  380.                 }
  381. // comment: what is it
  382.                 if (i->optional) {
  383.                     if (i->defaultValue.empty()) {
  384.                         code.ClassPublic() << "optional";
  385.                     } else {
  386.                         code.ClassPublic() << "mandatory with default";
  387.                     }
  388.                 } else {
  389.                     code.ClassPublic() << "mandatory";
  390.                 }
  391. // comment: typedef
  392.                 if (!isNull) {
  393.                     if (CClassCode::GetDoxygenComments()) {
  394.                         code.ClassPublic()
  395.                             <<";n    /// its type is defined as 'typedef "
  396.                             << i->type->GetCType(code.GetNamespace())
  397.                             <<" "<<i->tName<<"'n";
  398.                     } else {
  399.                         code.ClassPublic()
  400.                             << "n    /// typedef "
  401.                             << i->type->GetCType(code.GetNamespace())
  402.                             <<" "<<i->tName<<"n";
  403.                     }
  404.                 } else {
  405.                     code.ClassPublic() << "n";
  406.                 }
  407.                 if (CClassCode::GetDoxygenComments()) {
  408.                     code.ClassPublic() <<
  409.                         "    /// @returnn"
  410.                         "    ///   - true, if a value has been assigned.n"
  411.                         "    ///   - false, otherwise.n";
  412.                 }
  413.                 code.ClassPublic() <<
  414.                     "    bool IsSet" << i->cName<<"(void) const;n";
  415.                 inlineMethods <<
  416.                     "inlinen"
  417.                     "bool "<<methodPrefix<<"IsSet"<<i->cName<<"(void) constn"
  418.                     "{n";
  419.                 if ( i->haveFlag ) {
  420.                     // use special boolean flag
  421.                     inlineMethods <<
  422.                         "    return (("SET_PREFIX"["<<set_index<<"] & 0x"<<
  423.                             hex<<set_mask<<dec<<") != 0);n";
  424.                 }
  425.                 else {
  426.                     if ( i->delayed ) {
  427.                         inlineMethods <<
  428.                             "    if ( "DELAY_PREFIX<<i->cName<<" )n"
  429.                             "        return true;n";
  430.                     }
  431.                     if ( i->ref ) {
  432.                         // CRef
  433.                         if (isNullWithAtt) {
  434.                             inlineMethods <<
  435.                                 "    return "<<i->mName<<"->IsSet"<<i->cName<<"();n";
  436.                         } else {
  437.                             inlineMethods <<
  438.                                 "    return "<<i->mName<<";n";
  439.                         }
  440.                     }
  441.                     else {
  442.                         // doesn't need set flag -> use special code
  443.                         inlineMethods <<
  444.                             "    return "<<i->type->GetIsSetCode(i->mName)<<";n";
  445.                     }
  446.                 }
  447.                 inlineMethods <<
  448.                     "}n"
  449.                     "n";
  450. // CanGetX
  451.                 if (CClassCode::GetDoxygenComments()) {
  452.                     if (isNull || isNullWithAtt) {
  453.                         code.ClassPublic() <<
  454.                             "n"
  455.                             "    /// Check if value of "<<i->cName<<" member is getatable.n"
  456.                             "    ///n"
  457.                             "    /// @returnn"
  458.                             "    ///   - false; the data member of type 'NULL' has no value.n";
  459.                     } else {
  460.                         code.ClassPublic() <<
  461.                             "n"
  462.                             "    /// Check if it is safe to call Get"<<i->cName<<" method.n"
  463.                             "    ///n"
  464.                             "    /// @returnn"
  465.                             "    ///   - true, if the data member is getatable.n"
  466.                             "    ///   - false, otherwise.n";
  467.                     }
  468.                 }
  469.                 code.ClassPublic() <<
  470.                     "    bool CanGet" << i->cName<<"(void) const;n";
  471.                 inlineMethods <<
  472.                     "inlinen"
  473.                     "bool "<<methodPrefix<<"CanGet"<<i->cName<<"(void) constn"
  474.                     "{n";
  475.                 if (!i->defaultValue.empty() || i->type->GetKind() == eKindContainer) {
  476.                     inlineMethods <<"    return true;n";
  477.                 } else {
  478.                     if (isNull || isNullWithAtt) {
  479.                         inlineMethods <<"    return false;n";
  480.                     } else {
  481.                         inlineMethods <<"    return IsSet"<<i->cName<<"();n";
  482.                     }
  483.                 }
  484.                 inlineMethods <<
  485.                     "}n"
  486.                     "n";
  487.             }
  488.             
  489.             // generate Reset... method
  490.             string destructionCode = i->type->GetDestructionCode(i->valueName);
  491.             string assignValue = i->defaultValue;
  492.             string resetCode;
  493.             if ( assignValue.empty() && !i->ref ) {
  494.                 resetCode = i->type->GetResetCode(i->valueName);
  495.                 if ( resetCode.empty() )
  496.                     assignValue = i->type->GetInitializer();
  497.             }
  498.             if (CClassCode::GetDoxygenComments()) {
  499.                 setters <<
  500.                     "n"
  501.                     "    /// Reset "<<i->cName<<" data member.n";
  502.             }
  503.             setters <<
  504.                 "    void Reset"<<i->cName<<"(void);n";
  505.             // inline only when non reference and doesn't have reset code
  506.             bool inl = !i->ref && resetCode.empty();
  507.             code.MethodStart(inl) <<
  508.                 "void "<<methodPrefix<<"Reset"<<i->cName<<"(void)n"
  509.                 "{n";
  510.             if ( i->delayed ) {
  511.                 code.Methods(inl) <<
  512.                     "    "DELAY_PREFIX<<i->cName<<".Forget();n";
  513.             }
  514.             WriteTabbed(code.Methods(inl), destructionCode);
  515.             if ( i->ref ) {
  516.                 if ( !i->optional ) {
  517.                     // just reset value
  518.                     resetCode = i->type->GetResetCode(i->valueName);
  519.                     if ( !resetCode.empty() ) {
  520.                         WriteTabbed(code.Methods(inl), resetCode);
  521.                     }
  522.                     else {
  523.                         code.Methods(inl) <<
  524.                             "    "<<i->valueName<<" = "<<i->type->GetInitializer()<<";n";
  525.                     }
  526.                 }
  527.                 else if ( assignValue.empty() ) {
  528.                     // plain OPTIONAL
  529.                     code.Methods(inl) <<
  530.                         "    "<<i->mName<<".Reset();n";
  531.                 }
  532.                 else {
  533.                     if ( assignValue.empty() )
  534.                         assignValue = i->type->GetInitializer();
  535.                     // assign default value
  536.                     code.Methods(inl) <<
  537.                         "    "<<i->mName<<".Reset(new "<<i->tName<<"("<<assignValue<<"));n";
  538.                 }
  539.             }
  540.             else {
  541.                 if ( !assignValue.empty() ) {
  542.                     // assign default value
  543.                     if (!isNull) {
  544.                         code.Methods(inl) <<
  545.                             "    "<<i->mName<<" = "<<assignValue<<";n";
  546.                     }
  547.                 }
  548.                 else {
  549.                     // no default value
  550.                     WriteTabbed(code.Methods(inl), resetCode);
  551.                 }
  552.             }
  553.             if ( i->haveFlag ) {
  554.                 code.Methods(inl) <<
  555.                     "    "SET_PREFIX"["<<set_index<<"] &= ~0x"<<hex<<set_mask<<dec<<";n";
  556.             }
  557.             code.Methods(inl) <<
  558.                 "}n"
  559.                 "n";
  560.             string cType = i->type->GetCType(code.GetNamespace());
  561.             string rType = i->type->GetPrefixedCType(code.GetNamespace(),methodPrefix);
  562.             CTypeStrings::EKind kind = i->type->GetKind();
  563.             // generate getter
  564.             inl = true;//!i->ref;
  565.             if (!isNull) {
  566.                 if (i->dataType && i->dataType->IsPrimitive()) {
  567.                     if (CClassCode::GetDoxygenComments()) {
  568.                         code.ClassPublic() <<
  569.                             "n"
  570.                             "    /// Get the "<<i->cName<<" member data.n"
  571.                             "    ///n"
  572.                             "    /// @returnn"
  573.                             "    ///   Copy of the member data.n";
  574.                     }
  575.                     code.ClassPublic() <<
  576.                         "    "<<i->tName<<" Get"<<i->cName<<"(void) const;n";
  577.                     code.MethodStart(inl) <<
  578.                         ""<<rType<<" "<<methodPrefix<<"Get"<<i->cName<<"(void) constn"
  579.                         "{n";
  580.                 } else {
  581.                     if (CClassCode::GetDoxygenComments()) {
  582.                         code.ClassPublic() <<
  583.                             "n"
  584.                             "    /// Get the "<<i->cName<<" member data.n"
  585.                             "    ///n"
  586.                             "    /// @returnn"
  587.                             "    ///   Reference to the member data.n";
  588.                     }
  589.                     code.ClassPublic() <<
  590.                         "    const "<<i->tName<<"& Get"<<i->cName<<"(void) const;n";
  591.                     code.MethodStart(inl) <<
  592.                         "const "<<rType<<"& "<<methodPrefix<<"Get"<<i->cName<<"(void) constn"
  593.                         "{n";
  594.                 }
  595.                 if ( i->delayed ) {
  596.                     code.Methods(inl) <<
  597.                         "    "DELAY_PREFIX<<i->cName<<".Update();n";
  598.                 }
  599.                 if (i->defaultValue.empty() &&
  600.                     i->type->GetKind() != eKindContainer && !isNullWithAtt) {
  601.                     code.Methods(inl) <<
  602.                         "    if (!CanGet"<< i->cName<<"()) {n"
  603.                         "        ThrowUnassigned("<<member_index<<");n"
  604.                         "    }n";
  605.                 }
  606.                 code.Methods(inl) <<
  607.                     "    return "<<i->valueName<<";n"
  608.                     "}n"
  609.                     "n";
  610.             }
  611.             // generate setter
  612.             if ( i->ref ) {
  613.                 if (!isNullWithAtt) {
  614.                     // generate reference setter
  615.                     if (CClassCode::GetDoxygenComments()) {
  616.                         setters <<
  617.                             "n"
  618.                             "    /// Assign a value to "<<i->cName<<" data member.n"
  619.                             "    ///n"
  620.                             "    /// @param valuen"
  621.                             "    ///   Reference to value.n";
  622.                     }
  623.                     setters <<
  624.                         "    void Set"<<i->cName<<"("<<i->tName<<"& value);n";
  625.                     methods <<
  626.                         "void "<<methodPrefix<<"Set"<<i->cName<<"("<<rType<<"& value)n"
  627.                         "{n";
  628.                     if ( i->delayed ) {
  629.                         methods <<
  630.                             "    "DELAY_PREFIX<<i->cName<<".Forget();n";
  631.                     }
  632.                     methods <<
  633.                         "    "<<i->mName<<".Reset(&value);n";
  634.                     if ( i->haveFlag ) {
  635.                         methods <<
  636.                             "    "SET_PREFIX"["<<set_index<<"] |= 0x"<<hex<<set_mask<<dec<<";n";
  637.                     }
  638.                     methods <<
  639.                         "}n"
  640.                         "n";
  641.                 }
  642.                 if (CClassCode::GetDoxygenComments()) {
  643.                     setters <<
  644.                         "n"
  645.                         "    /// Assign a value to "<<i->cName<<" data member.n"
  646.                         "    ///n"
  647.                         "    /// @returnn"
  648.                         "    ///   Reference to the data value.n";
  649.                 }
  650.                 setters <<
  651.                     "    "<<i->tName<<"& Set"<<i->cName<<"(void);n";
  652.                 if ( i->canBeNull ) {
  653.                     // we have to init ref before returning
  654.                     _ASSERT(!i->haveFlag);
  655.                     methods <<
  656.                         rType<<"& "<<methodPrefix<<"Set"<<i->cName<<"(void)n"
  657.                         "{n";
  658.                     if ( i->delayed ) {
  659.                         methods <<
  660.                             "    "DELAY_PREFIX<<i->cName<<".Update();n";
  661.                     }
  662.                     methods <<
  663.                         "    if ( !"<<i->mName<<" )n"
  664.                         "        "<<i->mName<<".Reset("<<i->type->NewInstance(NcbiEmptyString)<<");n"
  665.                         "    return "<<i->valueName<<";n"
  666.                         "}n"
  667.                         "n";
  668.                 }
  669.                 else {
  670.                     // value already not null -> simple inline method
  671.                     inlineMethods <<
  672.                         "inlinen"<<
  673.                         rType<<"& "<<methodPrefix<<"Set"<<i->cName<<"(void)n"
  674.                         "{n";
  675.                     if ( i->delayed ) {
  676.                         inlineMethods <<
  677.                             "    "DELAY_PREFIX<<i->cName<<".Update();n";
  678.                     }
  679.                     if ( i->haveFlag) {
  680.                         inlineMethods <<
  681.                             "    "SET_PREFIX"["<<set_index<<"] |= 0x"<<hex<<set_mask<<dec<<";n";
  682.                     }
  683.                     if (isNullWithAtt) {
  684.                         inlineMethods <<
  685.                             "    "<<i->mName<<"->Set"<<i->cName<<"();n";
  686.                     }
  687.                     inlineMethods <<
  688.                         "    return "<<i->valueName<<";n"
  689.                         "}n"
  690.                         "n";
  691.                 }
  692.                 if (i->dataType && !isNullWithAtt) {
  693.                     const CDataType* resolved = i->dataType->Resolve();
  694.                     if (resolved && resolved != i->dataType) {
  695.                         CClassTypeStrings* typeStr = resolved->GetTypeStr();
  696.                         if (typeStr) {
  697.                             ITERATE ( TMembers, ir, typeStr->m_Members ) {
  698.                                 if (ir->simple) {
  699.                                     string ircType(ir->type->GetCType(
  700.                                         code.GetNamespace()));
  701.                                     if (CClassCode::GetDoxygenComments()) {
  702.                                         setters <<
  703.                                             "n"
  704.                                             "    /// Assign a value to "<<i->cName<<" data member.n"
  705.                                             "    ///n"
  706.                                             "    /// @param valuen"
  707.                                             "    ///   Reference to value.n";
  708.                                     }
  709.                                     setters <<
  710.                                         "    void Set"<<i->cName<<"(const "<<
  711.                                         ircType<<"& value);n";
  712.                                     methods <<
  713.                                         "void "<<methodPrefix<<"Set"<<
  714.                                         i->cName<<"(const "<<ircType<<
  715.                                         "& value)n"
  716.                                         "{n";
  717.                                     methods <<
  718.                                         "    Set" << i->cName <<
  719.                                         "() = value;n"
  720.                                         "}n"
  721.                                         "n";
  722.                                 }
  723.                             }
  724.                         }
  725.                     }
  726.                 }
  727.             }
  728.             else {
  729.                 if (isNull) {
  730.                     if (CClassCode::GetDoxygenComments()) {
  731.                         setters <<
  732.                             "n"
  733.                             "    /// Set NULL data member (assign 'NULL' value to "<<i->cName<<" data member).n";
  734.                     }
  735.                     setters <<
  736.                         "    void Set"<<i->cName<<"(void);n";
  737.                     inlineMethods <<
  738.                         "inlinen"<<
  739.                         "void "<<methodPrefix<<"Set"<<i->cName<<"(void)n"
  740.                         "{n";
  741.                     inlineMethods <<
  742.                         "    "SET_PREFIX"["<<set_index<<"] |= 0x"<<hex<<set_mask<<dec<<";n";
  743.                     inlineMethods <<
  744.                         "}n"
  745.                         "n";
  746.                 } else {
  747.                     if ( i->type->CanBeCopied() ) {
  748.                         if (CClassCode::GetDoxygenComments()) {
  749.                             setters <<
  750.                                 "n"
  751.                                 "    /// Assign a value to "<<i->cName<<" data member.n"
  752.                                 "    ///n"
  753.                                 "    /// @param valuen"
  754.                                 "    ///   Reference to value.n";
  755.                         }
  756.                         setters <<
  757.                             "    void Set"<<i->cName<<"(const "<<i->tName<<"& value);n";
  758.                         inlineMethods <<
  759.                             "inlinen"
  760.                             "void "<<methodPrefix<<"Set"<<i->cName<<"(const "<<rType<<"& value)n"
  761.                             "{n";
  762.                         if ( i->delayed ) {
  763.                             inlineMethods <<
  764.                                 "    "DELAY_PREFIX<<i->cName<<".Forget();n";
  765.                         }
  766.                         inlineMethods <<                        
  767.                             "    "<<i->valueName<<" = value;n";
  768.                         if ( i->haveFlag ) {
  769.                             inlineMethods <<
  770.                                 "    "SET_PREFIX"["<<set_index<<"] |= 0x"<<hex<<set_mask<<dec<<";n";
  771.                         }
  772.                         inlineMethods <<
  773.                             "}n"
  774.                             "n";
  775.                     }
  776.                     if (CClassCode::GetDoxygenComments()) {
  777.                         setters <<
  778.                             "n"
  779.                             "    /// Assign a value to "<<i->cName<<" data member.n"
  780.                             "    ///n"
  781.                             "    /// @returnn"
  782.                             "    ///   Reference to the data value.n";
  783.                     }
  784.                     setters <<
  785.                         "    "<<i->tName<<"& Set"<<i->cName<<"(void);n";
  786.                     inlineMethods <<
  787.                         "inlinen"<<
  788.                         rType<<"& "<<methodPrefix<<"Set"<<i->cName<<"(void)n"
  789.                         "{n";
  790.                     if ( i->delayed ) {
  791.                         inlineMethods <<
  792.                             "    "DELAY_PREFIX<<i->cName<<".Update();n";
  793.                     }
  794.                     if ( i->haveFlag ) {
  795.                         if ((kind == eKindStd) || (kind == eKindEnum) || (kind == eKindString)) {
  796.                             inlineMethods <<
  797.                                 "#ifdef _DEBUGn"
  798.                                 "    if (!IsSet"<<i->cName<<"()) {n"
  799.                                 "        ";
  800.                             if (kind == eKindString) {
  801.                                 inlineMethods <<
  802.                                     i->valueName << " = ms_UnassignedStr;n";
  803.                             } else {
  804.                                 inlineMethods <<
  805.                                     "memset(&"<<i->valueName<<",ms_UnassignedByte,sizeof("<<i->valueName<<"));n";
  806.                             }
  807.                             inlineMethods <<
  808.                                 "    }n"
  809.                                 "#endifn";
  810.                         }
  811.                         inlineMethods <<
  812.                             "    "SET_PREFIX"["<<set_index<<"] |= 0x"<<hex<<set_mask_maybe<<dec<<";n";
  813.                     }
  814.                     inlineMethods <<
  815.                         "    return "<<i->valueName<<";n"
  816.                         "}n"
  817.                         "n";
  818.                 }
  819.             }
  820.             // generate conversion operators
  821.             if ( i->cName.empty() ) {
  822.                 if ( i->optional ) {
  823.                     NCBI_THROW(CDatatoolException,eInvalidData,
  824.                         "the only member of adaptor class is optional");
  825.                 }
  826.                 code.ClassPublic() <<
  827.                     "    /// Conversion operator to 'const "<<i->tName<<"' type.n"
  828.                     "    operator const "<<i->tName<<"& (void) const;nn"
  829.                     "    /// Conversion operator to '"<<i->tName<<"' type.n"
  830.                     "    operator "<<i->tName<<"& (void);nn";
  831.                 inlineMethods <<
  832.                     "inlinen"<<
  833.                     methodPrefix<<"operator const "<<rType<<"& (void) constn"
  834.                     "{n";
  835.                 if ( i->delayed ) {
  836.                     inlineMethods <<
  837.                         "    "DELAY_PREFIX<<i->cName<<".Update();n";
  838.                 }
  839.                 inlineMethods << "    return ";
  840.                 if ( i->ref )
  841.                     inlineMethods << "*";
  842.                 inlineMethods <<
  843.                     i->mName<<";n"
  844.                     "}n"
  845.                     "n";
  846.                 inlineMethods <<
  847.                     "inlinen"<<
  848.                     methodPrefix<<"operator "<<rType<<"& (void)n"
  849.                     "{n";
  850.                 if ( i->delayed ) {
  851.                     inlineMethods <<
  852.                         "    "DELAY_PREFIX<<i->cName<<".Update();n";
  853.                 }
  854.                 if ( i->haveFlag ) {
  855.                     if ((kind == eKindStd) || (kind == eKindEnum) || (kind == eKindString)) {
  856.                         inlineMethods <<
  857.                             "#ifdef _DEBUGn"
  858.                             "    if (!IsSet"<<i->cName<<"()) {n"
  859.                             "        ";
  860.                         if (kind == eKindString) {
  861.                             inlineMethods <<
  862.                                 i->valueName << " = ms_UnassignedStr;n";
  863.                         } else {
  864.                             inlineMethods <<
  865.                                 "memset(&"<<i->valueName<<",ms_UnassignedByte,sizeof("<<i->valueName<<"));n";
  866.                         }
  867.                         inlineMethods <<
  868.                             "    }n"
  869.                             "#endifn";
  870.                     }
  871.                     inlineMethods <<
  872.                         "    "SET_PREFIX"["<<set_index<<"] |= 0x"<<hex<<set_mask_maybe<<dec<<";n";
  873.                 }
  874.                 inlineMethods << "    return ";
  875.                 if ( i->ref )
  876.                     inlineMethods << "*";
  877.                 inlineMethods <<
  878.                     i->mName<<";n"
  879.                     "}n"
  880.                     "n";
  881.             }
  882.             setters <<
  883.                 "n";
  884.         }
  885.     }
  886.     // generate member data
  887.     {
  888.         code.ClassPrivate() <<
  889.             "    // Prohibit copy constructor and assignment operatorn" <<
  890.             "    " << code.GetClassNameDT() <<
  891.             "(const " << code.GetClassNameDT() << "&);n" <<
  892.             "    " << code.GetClassNameDT() << "& operator=(const " <<
  893.             code.GetClassNameDT() << "&);n" <<
  894.             "n";
  895.         code.ClassPrivate() <<
  896.             "    // datan";
  897. {
  898.         if (m_Members.size() !=0) {
  899.             code.ClassPrivate() <<
  900.                     "    Uint4 "SET_PREFIX<<"["<<
  901.                     (2*m_Members.size()-1+8*sizeof(Uint4))/(8*sizeof(Uint4)) <<"];n";
  902.             }
  903.         }
  904. {
  905.         ITERATE ( TMembers, i, m_Members ) {
  906.         if ( i->delayed ) {
  907.         code.ClassPrivate() <<
  908.         "    mutable NCBI_NS_NCBI::CDelayBuffer "DELAY_PREFIX<<i->cName<<";n";
  909. }
  910. }
  911.         }
  912. {
  913. ITERATE ( TMembers, i, m_Members ) {
  914.                 if ( i->ref ) {
  915.                     code.ClassPrivate() <<
  916.                         "    "<<ncbiNamespace<<"CRef< "<<i->tName<<" > "<<i->mName<<";n";
  917.                 }
  918.                 else {
  919.                     if (!x_IsNullType(i)) {
  920.                         code.ClassPrivate() <<
  921.                             "    "<<i->tName<<" "<<i->mName<<";n";
  922.                     }
  923.                 }
  924.     }
  925. }
  926.     }
  927.     // generate member initializers
  928.     {
  929.         {
  930.             ITERATE ( TMembers, i, m_Members ) {
  931.                 if ( i->ref ) {
  932.                     if ( !i->canBeNull ) {
  933.                         string init = i->defaultValue;
  934.                         if ( init.empty() ) {
  935.                             init = i->type->GetInitializer();
  936.                         }
  937.                         code.AddInitializer(i->mName,
  938.                                             i->type->NewInstance(init));
  939.                     }
  940.                 }
  941.                 else {
  942.                     if (!x_IsNullType(i)) {
  943.                         string init = i->defaultValue;
  944.                         if ( init.empty() )
  945.                             init = i->type->GetInitializer();
  946.                         if ( !init.empty() )
  947.                             code.AddInitializer(i->mName, init);
  948.                     }
  949.                 }
  950.             }
  951.         }
  952.     }
  953.     // generate Reset method
  954.     code.ClassPublic() <<
  955.         "    /// Reset the whole objectn"
  956.         "    ";
  957.     if ( !wrapperClass ) {
  958.         if ( HaveUserClass() )
  959.             code.ClassPublic() << "virtual ";
  960.         code.ClassPublic() <<
  961.             "void Reset(void);n";
  962.         methods <<
  963.             "void "<<methodPrefix<<"Reset(void)n"
  964.             "{n";
  965.         ITERATE ( TMembers, i, m_Members ) {
  966.             methods <<
  967.                 "    Reset"<<i->cName<<"();n";
  968.         }
  969.         methods <<
  970.             "}n"
  971.             "n";
  972.     }
  973.     code.ClassPublic() << "n";
  974.     if ( generateDoNotDeleteThisObject ) {
  975.         code.ClassPublic() <<
  976.             "    virtual void DoNotDeleteThisObject(void);n"
  977.             "n";
  978.         methods <<
  979.             "void "<<methodPrefix<<"DoNotDeleteThisObject(void)n"
  980.             "{n"
  981.             "    "<<code.GetParentClassName()<<"::DoNotDeleteThisObject();n";
  982.         ITERATE ( TMembers, i, m_Members ) {
  983.             if ( !i->ref && i->type->GetKind() == eKindObject ) {
  984.                 methods <<
  985.                     "    "<<i->mName<<".DoNotDeleteThisObject();n";
  986.             }
  987.         }
  988.         methods <<
  989.             "}n"
  990.             "n";
  991.     }
  992.     // generate destruction code
  993.     {
  994.         for ( TMembers::const_reverse_iterator i = m_Members.rbegin();
  995.               i != m_Members.rend(); ++i ) {
  996.             code.AddDestructionCode(i->type->GetDestructionCode(i->valueName));
  997.         }
  998.     }
  999.     // generate type info
  1000.     methods << "BEGIN_NAMED_";
  1001.     if ( haveUserClass )
  1002.         methods << "BASE_";
  1003.     if ( wrapperClass )
  1004.         methods << "IMPLICIT_";
  1005.     methods <<
  1006.         "CLASS_INFO(""<<GetExternalName()<<"", "<<classPrefix<<GetClassNameDT()<<")n"
  1007.         "{n";
  1008.     if ( !GetModuleName().empty() ) {
  1009.         methods <<
  1010.             "    SET_CLASS_MODULE(""<<GetModuleName()<<"");n";
  1011.     }
  1012.     if ( !m_ParentClassName.empty() ) {
  1013.         code.SetParentClass(m_ParentClassName, m_ParentClassNamespace);
  1014.         methods <<
  1015.             "    SET_PARENT_CLASS("<<m_ParentClassNamespace.GetNamespaceRef(code.GetNamespace())<<m_ParentClassName<<");n";
  1016.     }
  1017.     {
  1018.         // All or none of the members must be tagged
  1019.         bool useTags = false;
  1020.         bool hasUntagged = false;
  1021.         // All tags must be different
  1022.         map<int, bool> tag_map;
  1023.         size_t member_index = 0;
  1024.         ITERATE ( TMembers, i, m_Members ) {
  1025.             ++member_index;
  1026.             if ( i->memberTag >= 0 ) {
  1027.                 if ( hasUntagged ) {
  1028.                     NCBI_THROW(CDatatoolException,eInvalidData,
  1029.                         "No explicit tag for some members in " +
  1030.                         GetModuleName());
  1031.                 }
  1032.                 if ( tag_map[i->memberTag] )
  1033.                     NCBI_THROW(CDatatoolException,eInvalidData,
  1034.                         "Duplicate tag: " + i->cName +
  1035.                         " [" + NStr::IntToString(i->memberTag) + "] in " +
  1036.                         GetModuleName());
  1037.                 tag_map[i->memberTag] = true;
  1038.                 useTags = true;
  1039.             }
  1040.             else {
  1041.                 hasUntagged = true;
  1042.                 if ( useTags ) {
  1043.                     NCBI_THROW(CDatatoolException,eInvalidData,
  1044.                         "No explicit tag for " + i->cName + " in " +
  1045.                         GetModuleName());
  1046.                 }
  1047.             }
  1048.             methods << "    ADD_NAMED_";
  1049.             bool isNull = x_IsNullType(i);
  1050.             if (isNull) {
  1051.                 methods << "NULL_";
  1052.             }
  1053.             
  1054.             bool addNamespace = false;
  1055.             bool addCType = false;
  1056.             bool addEnum = false;
  1057.             bool addRef = false;
  1058.             
  1059.             bool ref = i->ref;
  1060.             if ( ref ) {
  1061.                 methods << "REF_";
  1062.                 addCType = true;
  1063.             }
  1064.             else {
  1065.                 switch ( i->type->GetKind() ) {
  1066.                 case eKindStd:
  1067.                 case eKindString:
  1068.                     if ( i->type->HaveSpecialRef() ) {
  1069.                         addRef = true;
  1070.                     }
  1071.                     else {
  1072.                         methods << "STD_";
  1073.                     }
  1074.                     break;
  1075.                 case eKindEnum:
  1076.                     methods << "ENUM_";
  1077.                     addEnum = true;
  1078.                     if ( !i->type->GetNamespace().IsEmpty() &&
  1079.                          code.GetNamespace() != i->type->GetNamespace()) {
  1080.                         _TRACE("EnumNamespace: "<<i->type->GetNamespace()<<" from "<<code.GetNamespace());
  1081.                         methods << "IN_";
  1082.                         addNamespace = true;
  1083.                     }
  1084.                     break;
  1085.                 default:
  1086.                     addRef = true;
  1087.                     break;
  1088.                 }
  1089.             }
  1090.             methods << "MEMBER(""<<i->externalName<<""";
  1091.             if (!isNull) {
  1092.                 methods << ", "<<i->mName;
  1093.             }
  1094.             if ( addNamespace )
  1095.                 methods << ", "<<i->type->GetNamespace();
  1096.             if ( addCType )
  1097.                 methods << ", "<<i->type->GetCType(code.GetNamespace());
  1098.             if ( addEnum )
  1099.                 methods << ", "<<i->type->GetEnumName();
  1100.             if ( addRef )
  1101.                 methods << ", "<<i->type->GetRef(code.GetNamespace());
  1102.             methods << ")";
  1103.             if ( !i->defaultValue.empty() ) {
  1104.                 methods << "->SetDefault(";
  1105.                 if ( ref )
  1106.                     methods << "new NCBI_NS_NCBI::CRef< "+i->tName+" >(";
  1107.                 methods << "new "<<i->tName<<"("<<i->defaultValue<<')';
  1108.                 if ( ref )
  1109.                     methods << ')';
  1110.                 methods << ')';
  1111.               if ( i->haveFlag )
  1112.                     methods <<
  1113.                         "->SetSetFlag(MEMBER_PTR("SET_PREFIX"[0]))";
  1114.             }
  1115.             else if ( i->optional ) {
  1116.                 methods << "->SetOptional()";
  1117.                 if (i->haveFlag) {
  1118.                     methods <<
  1119.                         "->SetSetFlag(MEMBER_PTR("SET_PREFIX"[0]))";
  1120.                 }
  1121.             }
  1122.             else if (i->haveFlag) {
  1123.                 methods <<
  1124.                     "->SetSetFlag(MEMBER_PTR("SET_PREFIX"[0]))";
  1125.             }
  1126.             if ( i->delayed ) {
  1127.                 methods <<
  1128.                     "->SetDelayBuffer(MEMBER_PTR("DELAY_PREFIX<<
  1129.                     i->cName<<"))";
  1130.             }
  1131.             if (i->nonEmpty) {
  1132.                 methods << "->SetNonEmpty()";
  1133.             }
  1134.             if (i->noPrefix) {
  1135.                 methods << "->SetNoPrefix()";
  1136.             }
  1137.             if (i->attlist) {
  1138.                 methods << "->SetAttlist()";
  1139.             }
  1140.             if (i->noTag) {
  1141.                 methods << "->SetNotag()";
  1142.             }
  1143.             if ( i->memberTag >= 0 ) {
  1144.                 methods << "->GetId().SetTag(" << i->memberTag << ")";
  1145.             }
  1146.             methods << ";n";
  1147.         }
  1148.         if ( isAttlist || useTags ) {
  1149.             // Tagged class is not sequential
  1150.             methods << "    info->SetRandomOrder(true);n";
  1151.         }
  1152.         else {
  1153.             // Just query the flag to avoid warnings.
  1154.             methods << "    info->RandomOrder();n";
  1155.         }
  1156.     }
  1157.     methods <<
  1158.         "}n"
  1159.         "END_CLASS_INFOn"
  1160.         "n";
  1161. }
  1162. void CClassTypeStrings::GenerateUserHPPCode(CNcbiOstream& out) const
  1163. {
  1164.     if (CClassCode::GetDoxygenComments()) {
  1165.         out << "n"
  1166.             << "/** @addtogroup ";
  1167.         if (!CClassCode::GetDoxygenGroup().empty()) {
  1168.             out << CClassCode::GetDoxygenGroup();
  1169.         } else {
  1170.             out << "dataspec_" << GetModuleName();
  1171.         }
  1172.         out
  1173.             << "n *n"
  1174.             << " * @{n"
  1175.             << " */nn";
  1176.     }
  1177.     bool wrapperClass = (m_Members.size() == 1) &&
  1178.         m_Members.front().cName.empty();
  1179.     bool generateCopy = wrapperClass && m_Members.front().type->CanBeCopied();
  1180.     out <<
  1181.         "/////////////////////////////////////////////////////////////////////////////n";
  1182.     if (CClassCode::GetDoxygenComments()) {
  1183.         out <<
  1184.             "///n"
  1185.             "/// " << GetClassNameDT() << " --n"
  1186.             "///nn";
  1187.     }
  1188.     out << "class ";
  1189.     if ( !CClassCode::GetExportSpecifier().empty() )
  1190.         out << CClassCode::GetExportSpecifier() << " ";
  1191.     out << GetClassNameDT()<<" : public "<<GetClassNameDT()<<"_Basen"
  1192.         "{n"
  1193.         "    typedef "<<GetClassNameDT()<<"_Base Tparent;n"
  1194.         "public:n";
  1195.     DeclareConstructor(out, GetClassNameDT());
  1196.     ITERATE ( TMembers, i, m_Members ) {
  1197.         if (i->simple && !x_IsNullType(i)) {
  1198.             out <<
  1199.                 "    " << GetClassNameDT() <<"(const "<<
  1200.                 i->type->GetCType(GetNamespace()) << "& value);" <<
  1201.                 "n";
  1202.             break;
  1203.         }
  1204.     }
  1205.     DeclareDestructor(out, GetClassNameDT(), false);
  1206.     if ( generateCopy ) {
  1207.         const SMemberInfo& info = m_Members.front();
  1208.         string cType = info.type->GetCType(GetNamespace());
  1209.         out <<
  1210.             "    /// Copy constructorn"
  1211.             "    "<<GetClassNameDT()<<"(const "<<cType<<"& value);nn"
  1212.             "n"
  1213.             "    /// Assignment operatorn"
  1214.             "    "<<GetClassNameDT()<<"& operator=(const "<<cType<<"& value);nn"
  1215.             "n";
  1216.     }
  1217.     ITERATE ( TMembers, i, m_Members ) {
  1218.         if (i->simple && !x_IsNullType(i)) {
  1219.             out <<
  1220.             "    /// Conversion operator to '"
  1221.             << i->type->GetCType(GetNamespace()) << "' type.n"
  1222.             "    operator const " << i->type->GetCType(GetNamespace()) <<
  1223.             "&(void) const;nn";
  1224.             out <<
  1225.             "    /// Assignment operator.n"
  1226.             "    " << GetClassNameDT() << "& operator="<<"(const "<<
  1227.             i->type->GetCType(GetNamespace()) << "& value);n" <<
  1228.             "n";
  1229.             break;
  1230.         }
  1231.     }
  1232.     out << "private:n" <<
  1233.         "    // Prohibit copy constructor and assignment operatorn"
  1234.         "    "<<GetClassNameDT()<<"(const "<<GetClassNameDT()<<"& value);n"
  1235.         "    "<<GetClassNameDT()<<"& operator=(const "<<GetClassNameDT()<<
  1236.         "& value);n"
  1237.         "n";
  1238.     out << "};n";
  1239.     if (CClassCode::GetDoxygenComments()) {
  1240.         out << "/* @} */n";
  1241.     }
  1242.     out << "n";
  1243.     out <<
  1244.         "/////////////////// "<<GetClassNameDT()<<" inline methodsn"
  1245.         "n"
  1246.         "// constructorn"
  1247.         "inlinen"<<
  1248.         GetClassNameDT()<<"::"<<GetClassNameDT()<<"(void)n"
  1249.         "{n"
  1250.         "}n"
  1251.         "n";
  1252.     ITERATE ( TMembers, i, m_Members ) {
  1253.         if (i->simple && !x_IsNullType(i)) {
  1254.             out <<
  1255.             "inlinen" <<
  1256.             GetClassNameDT()<<"::"<<GetClassNameDT()<<"(const "<<
  1257.             i->type->GetCType(GetNamespace()) << "& value)n"<<
  1258.             "{n"
  1259.             "    Set" << i->cName << "(value);n" <<
  1260.             "}n"
  1261.             "n";
  1262.         }
  1263.     }
  1264.     if ( generateCopy ) {
  1265.         const SMemberInfo& info = m_Members.front();
  1266.         out <<
  1267.             "// data copy constructorsn"
  1268.             "inlinen"<<
  1269.             GetClassNameDT()<<"::"<<GetClassNameDT()<<"(const "<<info.tName<<"& value)n"
  1270.             "    : Tparent(value)n"
  1271.             "{n"
  1272.             "}n"
  1273.             "n"
  1274.             "// data assignment operatorsn"
  1275.             "inlinen"<<
  1276.             GetClassNameDT()<<"& "<<GetClassNameDT()<<"::operator=(const "<<info.tName<<"& value)n"
  1277.             "{n"
  1278.             "    Set(value);n"
  1279.             "    return *this;n"
  1280.             "}n"
  1281.             "n";
  1282.     }
  1283.     ITERATE ( TMembers, i, m_Members ) {
  1284.         if (i->simple && !x_IsNullType(i)) {
  1285.             out <<
  1286.             "inlinen"<<
  1287.             GetClassNameDT() << "::"
  1288.             "operator const " << i->type->GetCType(GetNamespace()) <<
  1289.             "&(void) constn" <<
  1290.             "{n" <<
  1291.             "    return Get" << i->cName << "();n" <<
  1292.             "}n" <<
  1293.             "n";
  1294.             out <<
  1295.             "inlinen"<<
  1296.             GetClassNameDT() << "& " << GetClassNameDT() << "::"
  1297.             "operator="<<"(const "<<
  1298.             i->type->GetCType(GetNamespace()) << "& value)n" <<
  1299.             "{n" <<
  1300.             "    Set" << i->cName << "(value);n" <<
  1301.             "    return *this;n" <<
  1302.             "}n"
  1303.             "n";
  1304.             break;
  1305.         }
  1306.     }
  1307.     out <<
  1308.         "n"
  1309.         "/////////////////// end of "<<GetClassNameDT()<<" inline methodsn"
  1310.         "n"
  1311.         "n";
  1312. }
  1313. void CClassTypeStrings::GenerateUserCPPCode(CNcbiOstream& out) const
  1314. {
  1315.     out <<
  1316.         "// destructorn"<<
  1317.         GetClassNameDT()<<"::~"<<GetClassNameDT()<<"(void)n"
  1318.         "{n"
  1319.         "}n"
  1320.         "n";
  1321. }
  1322. CClassRefTypeStrings::CClassRefTypeStrings(const string& className,
  1323.                                            const CNamespace& ns,
  1324.                                            const string& fileName)
  1325.     : m_ClassName(className),
  1326.       m_Namespace(ns),
  1327.       m_FileName(fileName)
  1328. {
  1329. }
  1330. CTypeStrings::EKind CClassRefTypeStrings::GetKind(void) const
  1331. {
  1332.     return eKindObject;
  1333. }
  1334. const CNamespace& CClassRefTypeStrings::GetNamespace(void) const
  1335. {
  1336.     return m_Namespace;
  1337. }
  1338. void CClassRefTypeStrings::GenerateTypeCode(CClassContext& ctx) const
  1339. {
  1340.     ctx.HPPIncludes().insert(m_FileName);
  1341. }
  1342. void CClassRefTypeStrings::GeneratePointerTypeCode(CClassContext& ctx) const
  1343. {
  1344.     ctx.AddForwardDeclaration(m_ClassName, m_Namespace);
  1345.     ctx.CPPIncludes().insert(m_FileName);
  1346. }
  1347. string CClassRefTypeStrings::GetClassName(void) const
  1348. {
  1349.     return m_ClassName;
  1350. }
  1351. string CClassRefTypeStrings::GetCType(const CNamespace& ns) const
  1352. {
  1353.     return ns.GetNamespaceRef(m_Namespace)+m_ClassName;
  1354. }
  1355. string CClassRefTypeStrings::GetPrefixedCType(const CNamespace& ns,
  1356.                                               const string& /*methodPrefix*/) const
  1357. {
  1358.     return GetCType(ns);
  1359. }
  1360. string CClassRefTypeStrings::GetRef(const CNamespace& ns) const
  1361. {
  1362.     return "CLASS, ("+GetCType(ns)+')';
  1363. }
  1364. string CClassRefTypeStrings::NewInstance(const string& init) const
  1365. {
  1366.     return "new "+GetCType(CNamespace::KEmptyNamespace)+"("+init+')';
  1367. }
  1368. string CClassRefTypeStrings::GetResetCode(const string& var) const
  1369. {
  1370.     return var+".Reset();n";
  1371. }
  1372. END_NCBI_SCOPE
  1373. /*
  1374. * ===========================================================================
  1375. *
  1376. * $Log: classstr.cpp,v $
  1377. * Revision 1000.3  2004/06/01 19:42:34  gouriano
  1378. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.63
  1379. *
  1380. * Revision 1.63  2004/05/17 21:03:13  gorelenk
  1381. * Added include of PCH ncbi_pch.hpp
  1382. *
  1383. * Revision 1.62  2004/05/03 19:31:03  gouriano
  1384. * Made generation of DOXYGEN-style comments optional
  1385. *
  1386. * Revision 1.61  2004/04/29 20:11:39  gouriano
  1387. * Generate DOXYGEN-style comments in C++ headers
  1388. *
  1389. * Revision 1.60  2004/03/08 20:08:53  gouriano
  1390. * Correct namespaces of generated classes
  1391. *
  1392. * Revision 1.59  2003/11/20 14:32:41  gouriano
  1393. * changed generated C++ code so NULL data types have no value
  1394. *
  1395. * Revision 1.58  2003/06/24 20:55:42  gouriano
  1396. * corrected code generation and serialization of non-empty unnamed containers (XML)
  1397. *
  1398. * Revision 1.57  2003/06/03 15:06:46  gouriano
  1399. * corrected generation of conversion operator for implicit members
  1400. *
  1401. * Revision 1.56  2003/05/08 16:59:08  gouriano
  1402. * added comment about the meaning of typedef for each class member
  1403. *
  1404. * Revision 1.55  2003/05/06 13:34:36  gouriano
  1405. * inline trivial Get methods
  1406. *
  1407. * Revision 1.54  2003/05/05 20:10:28  gouriano
  1408. * removed CanGet check for members which are always "gettable"
  1409. *
  1410. * Revision 1.53  2003/04/29 18:31:09  gouriano
  1411. * object data member initialization verification
  1412. *
  1413. * Revision 1.52  2003/04/10 20:13:41  vakatov
  1414. * Rollback the "uninitialized member" verification -- it still needs to
  1415. * be worked upon...
  1416. *
  1417. * Revision 1.50  2003/04/04 15:22:29  gouriano
  1418. * disable throwing CUnassignedMember exception
  1419. *
  1420. * Revision 1.49  2003/04/03 21:48:45  gouriano
  1421. * verify initialization of data members
  1422. *
  1423. * Revision 1.48  2003/03/11 20:06:47  kuznets
  1424. * iterate -> ITERATE
  1425. *
  1426. * Revision 1.47  2003/03/10 18:55:18  gouriano
  1427. * use new structured exceptions (based on CException)
  1428. *
  1429. * Revision 1.46  2003/02/12 21:39:51  gouriano
  1430. * corrected code generator so primitive data types (bool,int,etc)
  1431. * are returned by value, not by reference
  1432. *
  1433. * Revision 1.45  2002/12/23 18:40:07  dicuccio
  1434. * Added new command-line option: -oex <export-specifier> for adding WIn32 export
  1435. * specifiers to generated objects.
  1436. *
  1437. * Revision 1.44  2002/12/17 21:51:41  gouriano
  1438. * corrected generation of "simple" members
  1439. *
  1440. * Revision 1.43  2002/12/12 21:04:17  gouriano
  1441. * changed code generation so XML attribute list became random access class
  1442. *
  1443. * Revision 1.42  2002/11/19 19:48:28  gouriano
  1444. * added support of XML attributes of choice variants
  1445. *
  1446. * Revision 1.41  2002/11/14 21:03:39  gouriano
  1447. * added support of XML attribute lists
  1448. *
  1449. * Revision 1.40  2002/11/13 00:44:00  ucko
  1450. * Made type info declaration optional (but on by default); CVS logs to end
  1451. *
  1452. * Revision 1.39  2002/10/15 13:58:05  gouriano
  1453. * use "noprefix" flag
  1454. *
  1455. * Revision 1.38  2002/08/14 17:14:25  grichenk
  1456. * Fixed function name conflict on Win32: renamed
  1457. * GetClassName() -> GetClassNameDT()
  1458. *
  1459. * Revision 1.37  2002/05/15 20:22:04  grichenk
  1460. * Added CSerialObject -- base class for all generated ASN.1 classes
  1461. *
  1462. * Revision 1.36  2001/12/12 17:47:35  grichenk
  1463. * Updated setters/getters generator to avoid using CRef<>s
  1464. *
  1465. * Revision 1.35  2001/12/07 18:56:15  grichenk
  1466. * Most generated class members are stored in CRef<>-s by default
  1467. *
  1468. * Revision 1.34  2001/06/25 16:36:23  grichenk
  1469. * // Hide -> // Prohibit
  1470. *
  1471. * Revision 1.33  2001/06/21 19:47:39  grichenk
  1472. * Copy constructor and operator=() moved to "private" section
  1473. *
  1474. * Revision 1.32  2001/06/13 14:40:02  grichenk
  1475. * Modified class and choice info generation code to avoid warnings
  1476. *
  1477. * Revision 1.31  2001/06/11 14:35:02  grichenk
  1478. * Added support for numeric tags in ASN.1 specifications and data streams.
  1479. *
  1480. * Revision 1.30  2001/05/17 15:07:11  lavr
  1481. * Typos corrected
  1482. *
  1483. * Revision 1.29  2000/11/29 17:42:43  vasilche
  1484. * Added CComment class for storing/printing ASN.1/XML module comments.
  1485. * Added srcutil.hpp file to reduce file dependency.
  1486. *
  1487. * Revision 1.28  2000/11/07 17:26:25  vasilche
  1488. * Added module names to CTypeInfo and CEnumeratedTypeValues
  1489. * Added possibility to set include directory for whole module
  1490. *
  1491. * Revision 1.27  2000/11/02 14:42:34  vasilche
  1492. * MSVC doesn't understand namespaces in parent class specifier in subclass methods.
  1493. *
  1494. * Revision 1.26  2000/11/01 20:38:58  vasilche
  1495. * OPTIONAL and DEFAULT are not permitted in CHOICE.
  1496. * Fixed code generation for DEFAULT.
  1497. *
  1498. * Revision 1.25  2000/09/26 17:38:25  vasilche
  1499. * Fixed incomplete choiceptr implementation.
  1500. * Removed temporary comments.
  1501. *
  1502. * Revision 1.24  2000/08/25 15:59:20  vasilche
  1503. * Renamed directory tool -> datatool.
  1504. *
  1505. * Revision 1.23  2000/08/15 19:45:28  vasilche
  1506. * Added Read/Write hooks:
  1507. * CReadObjectHook/CWriteObjectHook for objects of specified type.
  1508. * CReadClassMemberHook/CWriteClassMemberHook for specified members.
  1509. * CReadChoiceVariantHook/CWriteChoiceVariant for specified choice variants.
  1510. * CReadContainerElementHook/CWriteContainerElementsHook for containers.
  1511. *
  1512. * Revision 1.22  2000/07/11 20:36:28  vasilche
  1513. * Removed unnecessary generation of namespace references for enum members.
  1514. * Removed obsolete methods.
  1515. *
  1516. * Revision 1.21  2000/06/27 16:34:47  vasilche
  1517. * Fixed generated comments.
  1518. * Fixed class names conflict. Now internal classes' names begin with "C_".
  1519. *
  1520. * Revision 1.20  2000/06/27 13:22:00  vasilche
  1521. * Added const modifier to generated IsSet*() methods.
  1522. *
  1523. * Revision 1.19  2000/06/16 16:31:38  vasilche
  1524. * Changed implementation of choices and classes info to allow use of the same classes in generated and user written classes.
  1525. *
  1526. * Revision 1.18  2000/05/03 14:38:18  vasilche
  1527. * SERIAL: added support for delayed reading to generated classes.
  1528. * DATATOOL: added code generation for delayed reading.
  1529. *
  1530. * Revision 1.17  2000/04/17 19:11:07  vasilche
  1531. * Fixed failed assertion.
  1532. * Removed redundant namespace specifications.
  1533. *
  1534. * Revision 1.16  2000/04/12 15:36:49  vasilche
  1535. * Added -on <namespace> argument to datatool.
  1536. * Removed unnecessary namespace specifications in generated files.
  1537. *
  1538. * Revision 1.15  2000/04/07 19:26:24  vasilche
  1539. * Added namespace support to datatool.
  1540. * By default with argument -oR datatool will generate objects in namespace
  1541. * NCBI_NS_NCBI::objects (aka ncbi::objects).
  1542. * Datatool's classes also moved to NCBI namespace.
  1543. *
  1544. * Revision 1.14  2000/04/06 16:11:25  vasilche
  1545. * Removed unneeded calls to Reset().
  1546. *
  1547. * Revision 1.13  2000/04/03 18:47:30  vasilche
  1548. * Added main include file for generated headers.
  1549. * serialimpl.hpp is included in generated sources with GetTypeInfo methods
  1550. *
  1551. * Revision 1.12  2000/03/29 15:52:26  vasilche
  1552. * Generated files names limited to 31 symbols due to limitations of Mac.
  1553. * Removed unions with only one member.
  1554. *
  1555. * Revision 1.11  2000/03/17 16:49:55  vasilche
  1556. * Added copyright message to generated files.
  1557. * All objects pointers in choices now share the only CObject pointer.
  1558. * All setters/getters made public until we'll find better solution.
  1559. *
  1560. * Revision 1.10  2000/03/15 14:18:39  vasilche
  1561. * Forgot to fix _ASSERT() expression.
  1562. *
  1563. * Revision 1.9  2000/03/14 18:32:58  vasilche
  1564. * Fixed class includes generation.
  1565. *
  1566. * Revision 1.8  2000/03/14 14:43:10  vasilche
  1567. * All OPTIONAL members implemented via CRef<> by default.
  1568. *
  1569. * Revision 1.7  2000/03/08 14:40:00  vasilche
  1570. * Renamed NewInstance() -> New().
  1571. *
  1572. * Revision 1.6  2000/03/07 20:05:00  vasilche
  1573. * Added NewInstance method to generated classes.
  1574. *
  1575. * Revision 1.5  2000/03/07 14:06:30  vasilche
  1576. * Added generation of reference counted objects.
  1577. *
  1578. * Revision 1.4  2000/02/17 20:05:06  vasilche
  1579. * Inline methods now will be generated in *_Base.inl files.
  1580. * Fixed processing of StringStore.
  1581. * Renamed in choices: Selected() -> Which(), E_choice -> E_Choice.
  1582. * Enumerated values now will preserve case as in ASN.1 definition.
  1583. *
  1584. * Revision 1.3  2000/02/02 19:08:20  vasilche
  1585. * Fixed variable conflict in generated files on MSVC.
  1586. *
  1587. * Revision 1.2  2000/02/02 18:54:15  vasilche
  1588. * Fixed variable conflict in MSVC.
  1589. * Added missing #include <serial/choice.hpp>
  1590. *
  1591. * Revision 1.1  2000/02/01 21:47:55  vasilche
  1592. * Added CGeneratedChoiceTypeInfo for generated choice classes.
  1593. * Removed CMemberInfo subclasses.
  1594. * Added support for DEFAULT/OPTIONAL members.
  1595. * Changed class generation.
  1596. * Moved datatool headers to include/internal/serial/tool.
  1597. *
  1598. * Revision 1.8  2000/01/10 19:46:47  vasilche
  1599. * Fixed encoding/decoding of REAL type.
  1600. * Fixed encoding/decoding of StringStore.
  1601. * Fixed encoding/decoding of NULL type.
  1602. * Fixed error reporting.
  1603. * Reduced object map (only classes).
  1604. *
  1605. * Revision 1.7  1999/12/28 18:56:00  vasilche
  1606. * Reduced size of compiled object files:
  1607. * 1. avoid inline or implicit virtual methods (especially destructors).
  1608. * 2. avoid std::string's methods usage in inline methods.
  1609. * 3. avoid string literals ("xxx") in inline methods.
  1610. *
  1611. * Revision 1.6  1999/12/17 19:05:19  vasilche
  1612. * Simplified generation of GetTypeInfo methods.
  1613. *
  1614. * Revision 1.5  1999/12/01 17:36:28  vasilche
  1615. * Fixed CHOICE processing.
  1616. *
  1617. * Revision 1.4  1999/11/18 17:13:07  vasilche
  1618. * Fixed generation of ENUMERATED CHOICE and VisibleString.
  1619. * Added generation of initializers to zero for primitive types and pointers.
  1620. *
  1621. * Revision 1.3  1999/11/16 15:41:17  vasilche
  1622. * Added plain pointer choice.
  1623. * By default we use C pointer instead of auto_ptr.
  1624. * Start adding initializers.
  1625. *
  1626. * Revision 1.2  1999/11/15 19:36:20  vasilche
  1627. * Fixed warnings on GCC
  1628. *
  1629. * ===========================================================================
  1630. */