Subversion Repositories Games.Descent

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * This file is part of the DXX-Rebirth project <https://www.dxx-rebirth.com/>.
  3.  * It is copyright by its individual contributors, as recorded in the
  4.  * project's Git history.  See COPYING.txt at the top level for license
  5.  * terms and a link to the Git history.
  6.  */
  7.  
  8. #pragma once
  9. #include "dxxsconf.h"
  10.  
  11. /* This header serves several purposes:
  12.  * - Declare namespace dcx and add it to the list of searched
  13.  *   namespaces.
  14.  * - If the compiler can disambiguate a namespace from a class inside a
  15.  *   searched namespace[1], declare dummy classes scoped so that
  16.  *   attempting to nest a namespace incorrectly causes a redefinition
  17.  *   error.  The build would usually fail even without this forced
  18.  *   check, but the redefinition error forces a clear and immediate
  19.  *   report.
  20.  *
  21.  * If building game-specific code:
  22.  * - #define dsx to a game-specific namespace: d1x or d2x, as
  23.  *   appropriate.
  24.  * - Declare namespace dsx and add it to the list of searched
  25.  *   namespaces.  When the dsx migration is finished, this `using
  26.  *   namespace` statement will be removed.
  27.  * Otherwise:
  28.  * - Declare dummy class dsx to force a redefinition error on attempts
  29.  *   to declare `namespace dsx` in common-only code.
  30.  *
  31.  * [1] gcc handles this in all tested versions.  There are no known
  32.  *      clang versions which handle this.  See the SConstruct test for
  33.  *      DXX_HAVE_CXX_DISAMBIGUATE_USING_NAMESPACE for how this is detected.
  34.  */
  35. #if defined(DXX_BUILD_DESCENT_I) || defined(DXX_BUILD_DESCENT_II)
  36. #       if defined(DXX_BUILD_DESCENT_I)
  37. #               define dsx d1x
  38. #       else
  39. #               define dsx d2x
  40. #       endif
  41. /* The "X declared inside Y" comments are on the same line as their
  42.  * declaration so that, if the compiler reports a redefinition error,
  43.  * the output shows the comment, which explains which type of mistake is
  44.  * being reported.
  45.  */
  46. namespace d1x { /* Force type mismatch on attempted nesting */
  47. #       ifdef DXX_HAVE_CXX_DISAMBIGUATE_USING_NAMESPACE
  48.         class dcx;      /* dcx declared inside d1x */
  49.         class d1x;      /* d1x declared inside d1x */
  50.         class d2x;      /* d2x declared inside d1x */
  51. #       endif
  52. }
  53. namespace d2x { /* Force type mismatch on attempted nesting */
  54. #       ifdef DXX_HAVE_CXX_DISAMBIGUATE_USING_NAMESPACE
  55.         class dcx;      /* dcx declared inside d2x */
  56.         class d1x;      /* d1x declared inside d2x */
  57.         class d2x;      /* d2x declared inside d2x */
  58. #       endif
  59. }
  60. #ifndef DXX_NO_USING_DSX
  61. /* For compatibility during migration, add namespace dsx to the search
  62.  * list.  This conflicts with the long term goal of the dsx project, but
  63.  * is currently required for a successful build.
  64.  *
  65.  * When working on the dsx project, define this preprocessor symbol on a
  66.  * file, then fix everything that breaks with that symbol defined.  Move
  67.  * on to the next file.  When all files build with this symbol set, the
  68.  * symbol and the using statement can be removed.
  69.  */
  70. using namespace dsx;    // deprecated
  71. #endif
  72. #else
  73. /* This dummy class does not need to be guarded by
  74.  * DXX_HAVE_CXX_DISAMBIGUATE_USING_NAMESPACE because it is declared only
  75.  * when no other uses of `dsx` are present, so there is no ambiguity for
  76.  * the compiler to resolve.
  77.  */
  78. class dsx;      /* dsx declared in common-only code */
  79. class d1x;      /* d1x declared in common-only code */
  80. class d2x;      /* d2x declared in common-only code */
  81. #endif
  82.  
  83. #ifdef DXX_HAVE_CXX_DISAMBIGUATE_USING_NAMESPACE
  84. namespace dcx { /* Force type mismatch on attempted nesting */
  85.         class dcx;      /* dcx declared inside dcx */
  86.         class d1x;      /* d1x declared inside dcx */
  87.         class d2x;      /* d2x declared inside dcx */
  88. }
  89.  
  90. namespace {
  91.         class dcx;      /* dcx declared inside anonymous */
  92.         class d1x;      /* d1x declared inside anonymous */
  93.         class d2x;      /* d2x declared inside anonymous */
  94. }
  95. #else
  96. /* This empty namespace is required because, if
  97.  * !DXX_HAVE_CXX_DISAMBIGUATE_USING_NAMESPACE, then no other declaration
  98.  * of `namespace dcx` has been seen in this file.
  99.  */
  100. namespace dcx {
  101. }
  102. #endif
  103.  
  104. using namespace dcx;
  105.