BLPAPI C++ 3.26.5
Loading...
Searching...
No Matches
blpapi_correlationid.h
Go to the documentation of this file.
1/* Copyright 2012. Bloomberg Finance L.P.
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to
5 * deal in the Software without restriction, including without limitation the
6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 * sell copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions: The above
9 * copyright notice and this permission notice shall be included in all copies
10 * or substantial portions of the Software.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
18 * IN THE SOFTWARE.
19 */
20
35
36#ifndef INCLUDED_BLPAPI_CORRELATIONID
37#define INCLUDED_BLPAPI_CORRELATIONID
38
68
69#include <blpapi_call.h>
70#include <blpapi_defs.h>
71#include <blpapi_exception.h>
72#include <blpapi_types.h>
73
74#ifdef __cplusplus
75extern "C" {
76#endif
77
79
82
83struct blpapi_ManagedPtr_t_;
84typedef struct blpapi_ManagedPtr_t_ blpapi_ManagedPtr_t;
85
86typedef int (*blpapi_ManagedPtr_ManagerFunction_t)(
87 blpapi_ManagedPtr_t *managedPtr,
88 const blpapi_ManagedPtr_t *srcPtr,
89 int operation);
90
91typedef union {
92 int intValue;
93 void *ptr;
94} blpapi_ManagedPtr_t_data_;
95
96struct blpapi_ManagedPtr_t_ {
97 void *pointer;
98 blpapi_ManagedPtr_t_data_ userData[4];
99 blpapi_ManagedPtr_ManagerFunction_t manager;
100};
101
107typedef struct blpapi_CorrelationId_t_ {
108 unsigned int size : 8;
109 unsigned int valueType
110 : 4;
111 unsigned int classId : 16;
112 unsigned int internalClassId : 4;
113
114 union {
115 blpapi_UInt64_t intValue;
116 blpapi_ManagedPtr_t ptrValue;
117 } value;
118} blpapi_CorrelationId_t;
119
120BLPAPI_EXPORT
121int blpapi_CorrelationId_managedPtrAddRef(
122 int *numRef, blpapi_CorrelationId_t *cid);
123
124BLPAPI_EXPORT
125int blpapi_CorrelationId_managedPtrRelease(
126 int *numRef, blpapi_CorrelationId_t *cid);
127
130
131#ifdef __cplusplus
132}
133
134#include <cstring>
135#include <ostream>
136#include <utility>
137
144
145namespace BloombergLP {
146namespace blpapi {
147
148// ===================
149// class CorrelationId
150// ===================
151
226
227 enum {
228 e_FOREIGN_OBJECT = BLPAPI_CORRELATION_INTERNAL_CLASS_FOREIGN_OBJECT
229 };
230
232 blpapi_CorrelationId_t d_impl;
233
234 void copy(const blpapi_CorrelationId_t& src, bool firstCopy);
235
236 template <typename TYPE>
237 static int managerFunc(blpapi_ManagedPtr_t *managedPtr,
238 const blpapi_ManagedPtr_t *srcPtr,
239 int operation);
241
242 template <typename TYPE> static void assertSmartPtrFits();
243
244 public:
245 // Possible return values for valueType() method.
246
248 UNSET_VALUE = BLPAPI_CORRELATION_TYPE_UNSET,
251 INT_VALUE = BLPAPI_CORRELATION_TYPE_INT,
254 POINTER_VALUE = BLPAPI_CORRELATION_TYPE_POINTER,
257 AUTOGEN_VALUE = BLPAPI_CORRELATION_TYPE_AUTOGEN
259 };
260
261 // The maximum value allowed for classId
262
263 enum {
264 MAX_CLASS_ID = BLPAPI_CORRELATION_MAX_CLASS_ID
266 };
267
275
277 explicit CorrelationId(const blpapi_CorrelationId_t& correlation);
282
283 CorrelationId(const CorrelationId& original);
288
289 explicit CorrelationId(long long value, int classId = 0);
295
296 explicit CorrelationId(void *value, int classId = 0);
302
303 template <typename TYPE>
304 CorrelationId(const TYPE& smartPtr, void *pointerValue, int classId = 0);
314
320
321 void swap(CorrelationId& other);
326
333
334 ValueType valueType() const;
338
339 unsigned short classId() const;
344
345 void *asPointer() const;
351
352 template <typename TYPE> TYPE asSmartPointer() const;
359
360 long long asInteger() const;
366
368 blpapi_CorrelationId_t& impl();
369 const blpapi_CorrelationId_t& impl() const;
371};
372
375
376// FREE OPERATORS
377inline bool operator==(const CorrelationId& lhs, const CorrelationId& rhs);
385
386inline bool operator!=(const CorrelationId& lhs, const CorrelationId& rhs);
390
391inline bool operator<(const CorrelationId& lhs, const CorrelationId& rhs);
401
402//=============================================================================
403// INLINE FUNCTION DEFINITIONS
404//=============================================================================
405
406// -------------------
407// class CorrelationId
408// -------------------
409
411{
412 std::memset(&d_impl, 0, sizeof(d_impl));
413}
414
417 const blpapi_CorrelationId_t& correlationId)
418{
419 copy(correlationId, /* firstCopy = */ true);
420}
422
424{
425 copy(original.d_impl, /* firstCopy = */ false);
426}
427
428inline CorrelationId::CorrelationId(long long intValue, int newClassId)
429{
430 std::memset(&d_impl, 0, sizeof(d_impl));
431
432 d_impl.size = static_cast<unsigned>(sizeof(d_impl));
433 d_impl.valueType = INT_VALUE;
434 d_impl.value.intValue = static_cast<blpapi_UInt64_t>(intValue);
435 d_impl.classId = static_cast<unsigned>(newClassId);
436}
437
438inline CorrelationId::CorrelationId(void *ptrValue, int newClassId)
439{
440 std::memset(&d_impl, 0, sizeof(d_impl));
441
442 d_impl.size = static_cast<unsigned>(sizeof(d_impl));
443 d_impl.valueType = POINTER_VALUE;
444 d_impl.value.ptrValue.pointer = ptrValue;
445 d_impl.classId = static_cast<unsigned>(newClassId);
446}
447
448template <typename TYPE>
450 const TYPE& smartPtr, void *ptrValue, int newClassId)
451{
452 // If you get a compiler error here, the specified smart pointer does not
453 // fit in the CorrelationId and cannot be used at this time.
454
455 assertSmartPtrFits<TYPE>();
456
457 std::memset(&d_impl, 0, sizeof(d_impl));
458
459 d_impl.size = sizeof(d_impl);
460 d_impl.valueType = POINTER_VALUE;
461 d_impl.classId = newClassId;
462
463 d_impl.value.ptrValue.pointer = ptrValue;
464 d_impl.value.ptrValue.manager = &CorrelationId::managerFunc<TYPE>;
465
466 void *arena = (void *)d_impl.value.ptrValue.userData;
467 new (arena) TYPE(smartPtr);
468}
469
471{
472 if (POINTER_VALUE == valueType()) {
473 blpapi_ManagedPtr_ManagerFunction_t& manager
474 = d_impl.value.ptrValue.manager;
475 if (manager) {
476 int numRef = 0;
477 if (d_impl.internalClassId == e_FOREIGN_OBJECT
479 blpapi_CorrelationId_managedPtrRelease)
481 blpapi_CorrelationId_managedPtrRelease)(
482 &numRef, &d_impl)
483 == 0
484 && numRef > 0) {
485 return;
486 }
487 manager(&d_impl.value.ptrValue, 0, BLPAPI_MANAGEDPTR_DESTROY);
488 }
489 }
490}
491
493{
494 using std::swap;
495
496 swap(other.d_impl, d_impl);
497}
498
500{
501 CorrelationId tmp(rhs);
502 tmp.swap(*this);
503 return *this;
504}
505
507inline blpapi_CorrelationId_t& CorrelationId::impl() { return d_impl; }
509
511{
512 return (ValueType)d_impl.valueType;
513}
514
515inline unsigned short CorrelationId::classId() const { return d_impl.classId; }
516
517inline void *CorrelationId::asPointer() const
518{
519 return d_impl.value.ptrValue.pointer;
520}
521
522template <typename TYPE> inline TYPE CorrelationId::asSmartPointer() const
523{
524 typedef int (*ManagerFuncPtr)(
525 blpapi_ManagedPtr_t *, const blpapi_ManagedPtr_t *, int);
526
527 ManagerFuncPtr managerFnPtr
528 = static_cast<ManagerFuncPtr>(&(CorrelationId::managerFunc<TYPE>));
529 if (d_impl.valueType != POINTER_VALUE
530 || (d_impl.value.ptrValue.manager != managerFnPtr)) {
531 return TYPE();
532 }
533 return *(TYPE *)d_impl.value.ptrValue.userData;
534}
535
536inline long long CorrelationId::asInteger() const
537{
538 return static_cast<long long>(d_impl.value.intValue);
539}
540
542inline const blpapi_CorrelationId_t& CorrelationId::impl() const
543{
544 return d_impl;
545}
547
549inline void CorrelationId::copy(
550 const blpapi_CorrelationId_t& src, bool firstCopy)
551{
552 d_impl = src;
553
554 if (POINTER_VALUE == valueType()) {
555 blpapi_ManagedPtr_ManagerFunction_t& manager
556 = d_impl.value.ptrValue.manager;
557 if (manager) {
558 if (d_impl.internalClassId == e_FOREIGN_OBJECT) {
559 if (firstCopy) {
560 // This CorrelationId is created from a C-handle, not from
561 // another C++ CorrelationId. But this C-handle can contain
562 // a pointer to a reference counter previously created in
563 // C++ layer. It is unsafe to reuse as it might be a
564 // dangling pointer by this time. Reset userData. This
565 // allows to create a new reference counter for new C++
566 // copies of this CorrelationId.
567 std::memset(&d_impl.value.ptrValue.userData,
568 0,
569 sizeof(d_impl.value.ptrValue.userData));
570 }
571 int numRef = 0;
573 BLPAPI_CALL(blpapi_CorrelationId_managedPtrAddRef)(
574 &numRef, &d_impl));
575 if (numRef > 1) {
576 return;
577 }
578 }
579 manager(&d_impl.value.ptrValue,
580 &src.value.ptrValue,
581 BLPAPI_MANAGEDPTR_COPY);
582 }
583 }
584}
586
588template <typename TYPE>
589inline int CorrelationId::managerFunc(blpapi_ManagedPtr_t *managedPtr,
590 const blpapi_ManagedPtr_t *srcPtr,
591 int operation)
592{
593 if (operation == BLPAPI_MANAGEDPTR_COPY) {
594 managedPtr->pointer = srcPtr->pointer;
595 managedPtr->manager = srcPtr->manager;
596
597 void *arena = managedPtr->userData;
598 new (arena) TYPE(*((TYPE *)&srcPtr->userData[0]));
599 } else if (operation == BLPAPI_MANAGEDPTR_DESTROY) {
600 TYPE *managedPtr_p = (TYPE *)&managedPtr->userData[0];
601 managedPtr_p->~TYPE();
602 } else if (operation == BLPAPI_MANAGEDPTR_IMPOSSIBLE_OPERATION) {
603 static int uniquePerTemplateInstantiation;
604
605 const int *address = &uniquePerTemplateInstantiation;
606 int rc = 0;
607 std::memcpy(&rc, &address, std::min(sizeof address, sizeof rc));
608 return rc;
609 // Instantiations of this function template, 'managerFunc<TYPE>',
610 // will never be called with 'operation' equal to
611 // 'BLPAPI_MANAGEDPTR_IMPOSSIBLE_OPERATION': this branch will never
612 // be executed.
613 //
614 // The observable use of the address of a local static variable
615 // forces '&managerFunc<T1> != &managerFunc<T2>' for types
616 // 'T1 != T2' even in the presence of Visual C++'s "identical
617 // COMDAT folding" optimization.
618 }
619
620 return 0;
621}
623
624template <typename TYPE> inline void CorrelationId::assertSmartPtrFits()
625{
626 if (false) {
627 // If you get a compiler error here, the specified smart pointer does
628 // not fit in the CorrelationId and cannot be used at this time.
629
630 char errorIfSmartPtrDoesNotFit[sizeof(TYPE) <= (sizeof(void *) * 4)
631 ? 1
632 : -1];
633 (void)errorIfSmartPtrDoesNotFit;
634 }
635}
636
637inline bool operator==(const CorrelationId& lhs, const CorrelationId& rhs)
638{
639 if (lhs.valueType() != rhs.valueType()) {
640 return false;
641 }
642 if (lhs.classId() != rhs.classId()) {
643 return false;
644 }
645 if (lhs.impl().internalClassId != rhs.impl().internalClassId) {
646 return false;
647 }
648
650 if (lhs.asPointer() != rhs.asPointer()) {
651 return false;
652 }
653 } else if (lhs.asInteger() != rhs.asInteger()) {
654 return false;
655 }
656
657 return true;
658}
659
660inline bool operator!=(const CorrelationId& lhs, const CorrelationId& rhs)
661{
662 return !(lhs == rhs);
663}
664
665inline bool operator<(const CorrelationId& lhs, const CorrelationId& rhs)
666{
668 && lhs.impl().internalClassId
669 == BLPAPI_CORRELATION_INTERNAL_CLASS_FOREIGN_OBJECT
671 && rhs.impl().internalClassId
672 == BLPAPI_CORRELATION_INTERNAL_CLASS_FOREIGN_OBJECT) {
673 return lhs.classId() == rhs.classId()
674 ? lhs.asPointer() < rhs.asPointer()
675 : lhs.classId() < rhs.classId();
676 }
677 return std::memcmp(&lhs.impl(), &rhs.impl(), sizeof(rhs.impl())) < 0;
678}
679
680inline std::ostream& operator<<(
681 std::ostream& os, const CorrelationId& correlator)
682{
683 const char *valueType = 0;
684 switch (correlator.valueType()) {
686 valueType = "UNSET";
687 break;
689 valueType = "INT";
690 break;
692 valueType = "POINTER";
693 break;
695 valueType = "AUTOGEN";
696 break;
697 default:
698 valueType = "UNKNOWN";
699 }
700
701 os << "[ valueType=" << valueType << " classId=" << correlator.classId()
702 << " internalClassId=" << correlator.impl().internalClassId
703 << " value=";
704
705 if (correlator.valueType() == CorrelationId::POINTER_VALUE) {
706 os << correlator.asPointer();
707 } else {
708 os << correlator.asInteger();
709 }
710 os << " ]";
711
712 return os;
713}
714
715} // close namespace blpapi
716} // close namespace BloombergLP
717
718#endif // #ifdef __cplusplus
719#endif // #ifndef INCLUDED_BLPAPI_CORRELATIONID
Provide functions for dispatchtbl.
#define BLPAPI_CALL_UNCHECKED(FUNCNAME)
Definition blpapi_call.h:362
#define BLPAPI_CALL_AVAILABLE(FUNCNAME)
Definition blpapi_call.h:360
#define BLPAPI_CALL(FUNCNAME)
Definition blpapi_call.h:361
Common definitions used by the library.
Defines Exceptions that can be thrown by the blpapi library.
Provide BLPAPI types.
Definition blpapi_correlationid.h:225
void swap(CorrelationId &other)
Definition blpapi_correlationid.h:492
@ MAX_CLASS_ID
Definition blpapi_correlationid.h:264
unsigned short classId() const
Definition blpapi_correlationid.h:515
ValueType valueType() const
Definition blpapi_correlationid.h:510
void * asPointer() const
Definition blpapi_correlationid.h:517
TYPE asSmartPointer() const
Definition blpapi_correlationid.h:522
~CorrelationId()
Definition blpapi_correlationid.h:470
CorrelationId()
Definition blpapi_correlationid.h:410
long long asInteger() const
Definition blpapi_correlationid.h:536
ValueType
Definition blpapi_correlationid.h:247
@ AUTOGEN_VALUE
The CorrelationId was created internally by API.
Definition blpapi_correlationid.h:257
@ UNSET_VALUE
Definition blpapi_correlationid.h:248
@ INT_VALUE
Definition blpapi_correlationid.h:251
@ POINTER_VALUE
Definition blpapi_correlationid.h:254
CorrelationId & operator=(const CorrelationId &rhs)
Definition blpapi_correlationid.h:499
static void throwOnError(int errorCode)
Definition blpapi_exception.h:541
Definition blpapi_abstractsession.h:212
bool operator==(const CorrelationId &lhs, const CorrelationId &rhs)
Definition blpapi_correlationid.h:637
std::ostream & operator<<(std::ostream &os, const CorrelationId &correlator)
Definition blpapi_correlationid.h:680
bool operator!=(const CorrelationId &lhs, const CorrelationId &rhs)
Definition blpapi_correlationid.h:660
bool operator<(const CorrelationId &lhs, const CorrelationId &rhs)
Definition blpapi_correlationid.h:665
Definition blpapi_abstractsession.h:211