Revert "Minor modernization of DynamicAny code"
[ACE_TAO.git] / TAO / tao / Range_Checking_T.h
blob513d80a1d61a94a6464dacd063cf4f68bd05d033
1 #ifndef guard_range_checking_hpp
2 #define guard_range_checking_hpp
3 /**
4 * @file
6 * @brief Details can be found in the documentation for
7 * TAO::details::generic_sequence
9 * @author Carlos O'Ryan
12 #include "tao/Basic_Types.h"
13 #include "tao/SystemException.h"
15 #if !defined (TAO_CHECKED_SEQUENCE_INDEXING) && !defined (ACE_NDEBUG)
16 # define TAO_CHECKED_SEQUENCE_INDEXING 1
17 #endif
19 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
21 namespace TAO
23 namespace details
25 /**
26 * @struct range_checking
28 * @brief Configurable traits to tradeoff safety vs. performance in
29 * the implementation of TAO sequences.
31 * The CORBA specification grants certain latitude to implementors by
32 * not defining the behavior of sequences under certain conditions.
33 * Probably the most clear example is the operator[] access, where the
34 * application <b>must</b> set the length to a high enough value
35 * before using the operator[].
37 * Implementors that cater to high-performance applications tend to
38 * exploit this latitude to the extreme, basically reasoning that
39 * correct applications will behave normally, while incorrect
40 * applications will crash, but those crashes will be detected during
41 * development/testing.
43 * Realizing that this may be a bad tradeoff some implementors offer
44 * compile-time hooks to control the behavior of sequences when used
45 * improperly, some implementors may go as far as using run-time
46 * hooks.
48 * The implementation of sequences calls the following template class
49 * in points where the application may trigger undefined behavior.
50 * The application developer can use partial (or full) template
51 * specialization to introduce her own code at these critical points.
53 * Some examples may help, suppose you want to change your application
54 * so for all sequence types the operator[] raises an exception if the
55 * index is out of range. Then you would provide the following
56 * (partial) template specialization:
58 * <PRE>
59 * template<typename T>
60 * struct range_checking<T,true> {
61 * void check(CORBA::ULong index, CORBA::ULong length) {
62 * if (index < length)
63 * return;
64 * throw std::range_error("CORBA sequence range error");
65 * };
66 * ...
67 * ..
68 * };
69 * </PRE>
71 * This specialization must be introduced before any sequence code is
72 * seen, therefore, the application would also need to define the
73 * following macro in their $ACE_ROOT/ace/config.h file:
75 * - #define TAO_USER_DEFINED_SEQUENCE_SAFETY_TRAITS_INCLUDE "<filename here>"
77 * Likewise, if the application only wanted to check the range for a
78 * special type, say some structure MyStruct, then they would provide
79 * a full specialization. Just for giggles, we will also introduce
80 * run-time controls to this example:
82 * <PRE>
83 * template<>
84 * struct safety_traits<tao::details::value_traits<MyStruct>,true> {
85 * bool enable_range_checking;
86 * void check_range(CORBA::ULong index, CORBA::ULong length) {
87 * if (!enable_range_checking || index < length)
88 * return;
89 * throw std::range_error("CORBA sequence range error");
90 * };
91 * ...
92 * ..
93 * };
94 * </PRE>
96 * @todo There is no control on a per-sequence type basis, only on a
97 * per-underlying type basis, for example, the following two IDL
98 * sequences would get the same behavior:
99 * // IDL
100 * typedef sequence<MyStruct> MyStructSequence;
101 * typedef sequence<MyStruct> MyStructList;
103 * @todo There is no way to control behavior on a per-sequence basis,
104 * i.e. to have some sequences of longs checked while others are
105 * not. This is easy to fix, simply:
106 * - make all members of safety_traits non-static
107 * - have each sequence contain their own instance of
108 * safety_traits
109 * - grant users read/write access to the safety_traits of each
110 * sequence
111 * but there are footprint consequences to that approach. Until
112 * there is more demand to justify the cost, I will not
113 * implement such a change.
115 template<typename T, bool dummy>
116 struct range_checking
118 typedef T value_type;
120 inline static void check(
121 CORBA::ULong index,
122 CORBA::ULong length,
123 CORBA::ULong /* maximum */,
124 char const * /* function_name */)
126 // Applications and tests can specialize this function to define
127 // their own behavior
128 #if defined (TAO_CHECKED_SEQUENCE_INDEXING) && (TAO_CHECKED_SEQUENCE_INDEXING == 1)
129 if (length <= index)
130 throw CORBA::BAD_PARAM ();
131 #else
132 ACE_UNUSED_ARG (index);
133 ACE_UNUSED_ARG (length);
134 #endif // TAO_CHECKED_SEQUENCE_INDEXING
137 inline static void check_length(
138 CORBA::ULong &new_length,
139 CORBA::ULong maximum)
141 if (maximum < new_length)
142 throw CORBA::BAD_PARAM ();
145 } // namespace details
146 } // namespace TAO
148 TAO_END_VERSIONED_NAMESPACE_DECL
150 #if defined(TAO_USER_DEFINED_SEQUENCE_RANGE_CHECKING_INCLUDE)
151 # include TAO_USER_DEFINED_SEQUENCE_RANGE_CHECKING_INCLUDE
152 #endif // TAO_USER_DEFINED_SEQUENCE_RANGE_CHECKING_INCLUDE
154 #endif // guard_range_checking_hpp